From 11ad7b4bc8bcb049040c02fae04074faf5dfaf27 Mon Sep 17 00:00:00 2001 From: Jens Arnold Date: Tue, 10 Feb 2009 23:43:37 +0000 Subject: Move screendump from apps to firmware, solving two nasty firmware-to-apps calls. This required to move the filename creation functions as well. * Fix bug in the BMP header of Clip screendumps. * Add remote screendump for targets with an LCD remote. * Simplify some ifdefs and rename a macro in the sim. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@19967 a1c6a512-1295-4272-9138-f99709370657 --- apps/misc.c | 330 ------------------------------------------------------------ 1 file changed, 330 deletions(-) (limited to 'apps/misc.c') diff --git a/apps/misc.c b/apps/misc.c index b1d795708c..872d91592d 100644 --- a/apps/misc.c +++ b/apps/misc.c @@ -135,109 +135,6 @@ char *output_dyn_value(char *buf, int buf_size, int value, return buf; } -/* Create a filename with a number part in a way that the number is 1 - * higher than the highest numbered file matching the same pattern. - * It is allowed that buffer and path point to the same memory location, - * saving a strcpy(). Path must always be given without trailing slash. - * "num" can point to an int specifying the number to use or NULL or a value - * less than zero to number automatically. The final number used will also - * be returned in *num. If *num is >= 0 then *num will be incremented by - * one. */ -char *create_numbered_filename(char *buffer, const char *path, - const char *prefix, const char *suffix, - int numberlen IF_CNFN_NUM_(, int *num)) -{ - DIR *dir; - struct dirent *entry; - int max_num; - int pathlen; - int prefixlen = strlen(prefix); - char fmtstring[12]; - - if (buffer != path) - strncpy(buffer, path, MAX_PATH); - - pathlen = strlen(buffer); - -#ifdef IF_CNFN_NUM - if (num && *num >= 0) - { - /* number specified */ - max_num = *num; - } - else -#endif - { - /* automatic numbering */ - max_num = 0; - - dir = opendir(pathlen ? buffer : "/"); - if (!dir) - return NULL; - - while ((entry = readdir(dir))) - { - int curr_num; - - if (strncasecmp((char *)entry->d_name, prefix, prefixlen) - || strcasecmp((char *)entry->d_name + prefixlen + numberlen, suffix)) - continue; - - curr_num = atoi((char *)entry->d_name + prefixlen); - if (curr_num > max_num) - max_num = curr_num; - } - - closedir(dir); - } - - max_num++; - - snprintf(fmtstring, sizeof(fmtstring), "/%%s%%0%dd%%s", numberlen); - snprintf(buffer + pathlen, MAX_PATH - pathlen, fmtstring, prefix, - max_num, suffix); - -#ifdef IF_CNFN_NUM - if (num) - *num = max_num; -#endif - - return buffer; -} - - -#if CONFIG_RTC -/* Create a filename with a date+time part. - It is allowed that buffer and path point to the same memory location, - saving a strcpy(). Path must always be given without trailing slash. - unique_time as true makes the function wait until the current time has - changed. */ -char *create_datetime_filename(char *buffer, const char *path, - const char *prefix, const char *suffix, - bool unique_time) -{ - struct tm *tm = get_time(); - static struct tm last_tm; - int pathlen; - - while (unique_time && !memcmp(get_time(), &last_tm, sizeof (struct tm))) - sleep(HZ/10); - - last_tm = *tm; - - if (buffer != path) - strncpy(buffer, path, MAX_PATH); - - pathlen = strlen(buffer); - snprintf(buffer + pathlen, MAX_PATH - pathlen, - "/%s%02d%02d%02d-%02d%02d%02d%s", prefix, - tm->tm_year % 100, tm->tm_mon + 1, tm->tm_mday, - tm->tm_hour, tm->tm_min, tm->tm_sec, suffix); - - return buffer; -} -#endif /* CONFIG_RTC */ - /* Ask the user if they really want to erase the current dynamic playlist * returns true if the playlist should be replaced */ bool warn_on_pl_erase(void) @@ -339,233 +236,6 @@ int fast_readline(int fd, char *buf, int buf_size, void *parameters, return 0; } -#ifdef HAVE_LCD_BITMAP - -#if LCD_DEPTH == 16 -#define BMP_COMPRESSION 3 /* BI_BITFIELDS */ -#define BMP_NUMCOLORS 3 -#else /* LCD_DEPTH != 16 */ -#define BMP_COMPRESSION 0 /* BI_RGB */ -#if LCD_DEPTH <= 8 -#ifdef HAVE_LCD_SPLIT -#define BMP_NUMCOLORS (2 << LCD_DEPTH) -#else -#define BMP_NUMCOLORS (1 << LCD_DEPTH) -#endif -#else /* LCD_DEPTH > 8 */ -#define BMP_NUMCOLORS 0 -#endif /* LCD_DEPTH > 8 */ -#endif /* LCD_DEPTH != 16 */ - -#if LCD_DEPTH <= 4 -#define BMP_BPP 4 -#define BMP_LINESIZE ((LCD_WIDTH/2 + 3) & ~3) -#elif LCD_DEPTH <= 8 -#define BMP_BPP 8 -#define BMP_LINESIZE ((LCD_WIDTH + 3) & ~3) -#elif LCD_DEPTH <= 16 -#define BMP_BPP 16 -#define BMP_LINESIZE ((LCD_WIDTH*2 + 3) & ~3) -#else -#define BMP_BPP 24 -#define BMP_LINESIZE ((LCD_WIDTH*3 + 3) & ~3) -#endif - -#define BMP_HEADERSIZE (54 + 4 * BMP_NUMCOLORS) -#define BMP_DATASIZE (BMP_LINESIZE * LCD_HEIGHT) -#define BMP_TOTALSIZE (BMP_HEADERSIZE + BMP_DATASIZE) - -#define LE16_CONST(x) (x)&0xff, ((x)>>8)&0xff -#define LE32_CONST(x) (x)&0xff, ((x)>>8)&0xff, ((x)>>16)&0xff, ((x)>>24)&0xff - -static const unsigned char bmpheader[] = -{ - 0x42, 0x4d, /* 'BM' */ - LE32_CONST(BMP_TOTALSIZE), /* Total file size */ - 0x00, 0x00, 0x00, 0x00, /* Reserved */ - LE32_CONST(BMP_HEADERSIZE), /* Offset to start of pixel data */ - - 0x28, 0x00, 0x00, 0x00, /* Size of (2nd) header */ - LE32_CONST(LCD_WIDTH), /* Width in pixels */ - LE32_CONST(LCD_HEIGHT+LCD_SPLIT_LINES), /* Height in pixels */ - 0x01, 0x00, /* Number of planes (always 1) */ - LE16_CONST(BMP_BPP), /* Bits per pixel 1/4/8/16/24 */ - LE32_CONST(BMP_COMPRESSION),/* Compression mode */ - LE32_CONST(BMP_DATASIZE), /* Size of bitmap data */ - 0xc4, 0x0e, 0x00, 0x00, /* Horizontal resolution (pixels/meter) */ - 0xc4, 0x0e, 0x00, 0x00, /* Vertical resolution (pixels/meter) */ - LE32_CONST(BMP_NUMCOLORS), /* Number of used colours */ - LE32_CONST(BMP_NUMCOLORS), /* Number of important colours */ - -#if LCD_DEPTH == 1 -#ifdef HAVE_NEGATIVE_LCD - BMP_COLOR(LCD_BL_DARKCOLOR), - BMP_COLOR(LCD_BL_BRIGHTCOLOR), -#ifdef HAVE_LCD_SPLIT - BMP_COLOR(LCD_BL_DARKCOLOR_2), - BMP_COLOR(LCD_BL_BRIGHTCOLOR_2), -#endif -#else /* positive display */ - BMP_COLOR(LCD_BL_BRIGHTCOLOR), - BMP_COLOR(LCD_BL_DARKCOLOR), -#endif /* positive display */ -#elif LCD_DEPTH == 2 - BMP_COLOR(LCD_BL_BRIGHTCOLOR), - BMP_COLOR_MIX(LCD_BL_BRIGHTCOLOR, LCD_BL_DARKCOLOR, 1, 3), - BMP_COLOR_MIX(LCD_BL_BRIGHTCOLOR, LCD_BL_DARKCOLOR, 2, 3), - BMP_COLOR(LCD_BL_DARKCOLOR), -#elif LCD_DEPTH == 16 - 0x00, 0xf8, 0x00, 0x00, /* red bitfield mask */ - 0xe0, 0x07, 0x00, 0x00, /* green bitfield mask */ - 0x1f, 0x00, 0x00, 0x00, /* blue bitfield mask */ -#endif -}; - -static void (*screen_dump_hook)(int fh) = NULL; - -void screen_dump(void) -{ - int fd, y; - char filename[MAX_PATH]; - - fb_data *src; -#if LCD_DEPTH == 1 - unsigned mask; - unsigned val; -#elif (LCD_DEPTH == 2) && (LCD_PIXELFORMAT != HORIZONTAL_PACKING) - int shift; - unsigned val; -#endif -#if LCD_DEPTH <= 8 - unsigned char *dst, *dst_end; - unsigned char linebuf[BMP_LINESIZE]; -#elif LCD_DEPTH <= 16 - unsigned short *dst, *dst_end; - unsigned short linebuf[BMP_LINESIZE/2]; -#endif - -#if CONFIG_RTC - create_datetime_filename(filename, "", "dump ", ".bmp", false); -#else - create_numbered_filename(filename, "", "dump_", ".bmp", 4 - IF_CNFN_NUM_(, NULL)); -#endif - - fd = creat(filename); - if (fd < 0) - return; - - if (screen_dump_hook) - { - screen_dump_hook(fd); - } - else - { - write(fd, bmpheader, sizeof(bmpheader)); - - /* BMP image goes bottom up */ - for (y = LCD_HEIGHT - 1; y >= 0; y--) - { - memset(linebuf, 0, BMP_LINESIZE); - -#if defined(HAVE_LCD_SPLIT) && (LCD_SPLIT_LINES == 2) - if (y == LCD_SPLIT_POS - 1) - { - write(fd, linebuf, BMP_LINESIZE); - write(fd, linebuf, BMP_LINESIZE); - } -#endif - dst = linebuf; - -#if LCD_DEPTH == 1 - dst_end = dst + LCD_WIDTH/2; - src = lcd_framebuffer[y >> 3]; - mask = 1 << (y & 7); - - do - { - val = (*src++ & mask) ? 0x10 : 0; - val |= (*src++ & mask) ? 0x01 : 0; -#ifdef HAVE_LCD_SPLIT - if (y < LCD_SPLIT_POS) - val |= 0x22; -#endif - *dst++ = val; - } - while (dst < dst_end); - -#elif LCD_DEPTH == 2 - dst_end = dst + LCD_WIDTH/2; - -#if LCD_PIXELFORMAT == HORIZONTAL_PACKING - src = lcd_framebuffer[y]; - - do - { - unsigned data = *src++; - - *dst++ = ((data >> 2) & 0x30) | ((data >> 4) & 0x03); - *dst++ = ((data << 2) & 0x30) | (data & 0x03); - } - while (dst < dst_end); - -#elif LCD_PIXELFORMAT == VERTICAL_PACKING - src = lcd_framebuffer[y >> 2]; - shift = 2 * (y & 3); - - do - { - val = ((*src++ >> shift) & 3) << 4; - val |= ((*src++ >> shift) & 3); - *dst++ = val; - } - while (dst < dst_end); - -#elif LCD_PIXELFORMAT == VERTICAL_INTERLEAVED - src = lcd_framebuffer[y >> 3]; - shift = y & 7; - - do - { - unsigned data = (*src++ >> shift) & 0x0101; - - val = (((data >> 7) | data) & 3) << 4; - data = (*src++ >> shift) & 0x0101; - val |= ((data >> 7) | data) & 3; - *dst++ = val; - } - while (dst < dst_end); - -#endif -#elif LCD_DEPTH == 16 - dst_end = dst + LCD_WIDTH; - src = lcd_framebuffer[y]; - - do - { -#if (LCD_PIXELFORMAT == RGB565SWAPPED) - /* iPod LCD data is big endian although the CPU is not */ - *dst++ = htobe16(*src++); -#else - *dst++ = htole16(*src++); -#endif - } - while (dst < dst_end); - -#endif /* LCD_DEPTH */ - write(fd, linebuf, BMP_LINESIZE); - } - } - close(fd); -} - -void screen_dump_set_hook(void (*hook)(int fh)) -{ - screen_dump_hook = hook; -} - -#endif /* HAVE_LCD_BITMAP */ - /* parse a line from a configuration file. the line format is: name: value -- cgit v1.2.3