Index: apps/gui/gwps-common.c =================================================================== --- apps/gui/gwps-common.c (revision 18997) +++ apps/gui/gwps-common.c (working copy) @@ -1575,6 +1575,16 @@ *buf++ = 0; cur_align_start = buf; break; +#ifdef HAVE_LCD_BITMAP + case WPS_VIEWPORT_BACKDROP: + { + struct screen *display = gwps->display; + int n = data->tokens[i].value.i & 0xFF; + struct bitmap *bm = &(data->img[n].bm); + display->set_viewport_backdrop(bm); + } + break; +#endif case WPS_VIEWPORT_ENABLE: { char label = data->tokens[i].value.i; Index: apps/gui/gwps.h =================================================================== --- apps/gui/gwps.h (revision 18997) +++ apps/gui/gwps.h (working copy) @@ -292,6 +292,7 @@ #endif /* Viewport display */ + WPS_VIEWPORT_BACKDROP, WPS_VIEWPORT_ENABLE, /* buttons */ Index: apps/gui/viewport.c =================================================================== --- apps/gui/viewport.c (revision 18997) +++ apps/gui/viewport.c (working copy) @@ -55,6 +55,7 @@ #ifdef HAVE_LCD_BITMAP vp->drawmode = DRMODE_SOLID; vp->font = FONT_UI; /* default to UI to discourage SYSFONT use */ + vp->bg = 0; #endif #ifdef HAVE_REMOTE_LCD Index: apps/gui/wps_debug.c =================================================================== --- apps/gui/wps_debug.c (revision 18997) +++ apps/gui/wps_debug.c (working copy) @@ -427,6 +427,10 @@ snprintf(buf, bufsize, "pitch value"); break; #endif + case WPS_VIEWPORT_BACKDROP: + snprintf(buf, bufsize, "backdrop VP:%d", + token->value.i); + break; case WPS_VIEWPORT_ENABLE: snprintf(buf, bufsize, "enable VP:%d", token->value.i); Index: apps/gui/wps_parser.c =================================================================== --- apps/gui/wps_parser.c (revision 18997) +++ apps/gui/wps_parser.c (working copy) @@ -139,6 +139,8 @@ struct wps_token *token, struct wps_data *wps_data); #ifdef HAVE_LCD_BITMAP +static int parse_viewport_backdrop(const char *wps_bufptr, + struct wps_token *token, struct wps_data *wps_data); static int parse_viewport_display(const char *wps_bufptr, struct wps_token *token, struct wps_data *wps_data); static int parse_viewport(const char *wps_bufptr, @@ -333,6 +335,8 @@ parse_albumart_conditional }, #endif + { WPS_VIEWPORT_BACKDROP, "VX", WPS_REFRESH_DYNAMIC, + parse_viewport_backdrop }, { WPS_VIEWPORT_ENABLE, "Vd", WPS_REFRESH_DYNAMIC, parse_viewport_display }, { WPS_NO_TOKEN, "V", 0, parse_viewport }, @@ -557,6 +561,24 @@ return skip_end_of_line(wps_bufptr); } +static int parse_viewport_backdrop(const char *wps_bufptr, + struct wps_token *token, + struct wps_data *wps_data) +{ + (void)wps_data; + char letter = wps_bufptr[0]; + + token->value.i = get_image_id(letter); + + if (token->value.i == -1) + { + /* invalid viewport tag */ + return WPS_ERROR_INVALID_PARAM; + } + + return 1; +} + static int parse_viewport_display(const char *wps_bufptr, struct wps_token *token, struct wps_data *wps_data) Index: apps/plugins/test_viewports.c =================================================================== --- apps/plugins/test_viewports.c (revision 18997) +++ apps/plugins/test_viewports.c (working copy) @@ -48,6 +48,7 @@ #if LCD_DEPTH > 1 .fg_pattern = LCD_DEFAULT_FG, .bg_pattern = BGCOLOR_1, + .fb = 0, #endif #ifdef HAVE_LCD_COLOR .lss_pattern = LCD_DEFAULT_BG, @@ -67,6 +68,7 @@ #if LCD_DEPTH > 1 .fg_pattern = LCD_DEFAULT_FG, .bg_pattern = LCD_DEFAULT_BG, + .fb = 0, #ifdef HAVE_LCD_COLOR .lss_pattern = LCD_DEFAULT_BG, .lse_pattern = LCD_DEFAULT_BG, @@ -86,6 +88,7 @@ #if LCD_DEPTH > 1 .fg_pattern = FGCOLOR_1, .bg_pattern = BGCOLOR_2, + .fb = 0, #ifdef HAVE_LCD_COLOR .lss_pattern = LCD_DEFAULT_BG, .lse_pattern = LCD_DEFAULT_BG, @@ -106,6 +109,7 @@ #if LCD_DEPTH > 1 .fg_pattern = LCD_BLACK, .bg_pattern = LCD_WHITE, + .fb = 0, #ifdef HAVE_LCD_COLOR .lss_pattern = LCD_DEFAULT_BG, .lse_pattern = LCD_DEFAULT_BG, @@ -127,6 +131,7 @@ #if LCD_REMOTE_DEPTH > 1 .fg_pattern = LCD_REMOTE_BLACK, .bg_pattern = LCD_REMOTE_LIGHTGRAY, + .fb = 0, #endif }; @@ -141,6 +146,7 @@ #if LCD_REMOTE_DEPTH > 1 .fg_pattern = LCD_REMOTE_DEFAULT_FG, .bg_pattern = LCD_REMOTE_DEFAULT_BG + .fb = 0, #endif }; Index: apps/screen_access.c =================================================================== --- apps/screen_access.c (revision 18997) +++ apps/screen_access.c (working copy) @@ -127,6 +127,7 @@ .getheight=&lcd_getheight, .getstringsize=&lcd_getstringsize, #ifdef HAVE_LCD_BITMAP + .set_viewport_backdrop=&lcd_set_viewport_backdrop, .setfont=&lcd_setfont, .getfont=&lcd_getfont, .mono_bitmap=&lcd_mono_bitmap, @@ -218,6 +219,7 @@ .getheight=&lcd_remote_getheight, .getstringsize=&lcd_remote_getstringsize, #if 1 /* all remote LCDs are bitmapped so far */ + .set_viewport_backdrop=&lcd_set_viewport_backdrop, .setfont=&lcd_remote_setfont, .getfont=&lcd_remote_getfont, .mono_bitmap=&lcd_remote_mono_bitmap, Index: apps/screen_access.h =================================================================== --- apps/screen_access.h (revision 18997) +++ apps/screen_access.h (working copy) @@ -78,6 +78,7 @@ int (*getheight)(void); int (*getstringsize)(const unsigned char *str, int *w, int *h); #if defined(HAVE_LCD_BITMAP) || defined(HAVE_REMOTE_LCD) /* always bitmap */ + void (*set_viewport_backdrop)(struct bitmap *bg); void (*setfont)(int newfont); int (*getfont)(void); Index: firmware/drivers/lcd-16bit.c =================================================================== --- firmware/drivers/lcd-16bit.c (revision 18997) +++ firmware/drivers/lcd-16bit.c (working copy) @@ -40,7 +40,8 @@ enum fill_opt { OPT_NONE = 0, OPT_SET, - OPT_COPY + OPT_COPY, + OPT_SKIP }; /*** globals ***/ @@ -63,6 +64,7 @@ .height = LCD_HEIGHT, .font = FONT_SYSFIXED, .drawmode = DRMODE_SOLID, + .bg = 0, .fg_pattern = LCD_DEFAULT_FG, .bg_pattern = LCD_DEFAULT_BG, .lss_pattern = LCD_DEFAULT_BG, @@ -107,6 +109,11 @@ /*** Viewports ***/ +void lcd_set_viewport_backdrop(struct bitmap *bg) +{ + current_vp->bg = bg; +} + void lcd_set_viewport(struct viewport* vp) { if (vp == NULL) @@ -268,6 +275,63 @@ /*** drawing functions ***/ +static void draw_viewport_backdrop(struct bitmap *bm) +{ + if (bm) + { + int old_drawmode = current_vp->drawmode; + + current_vp->drawmode = DRMODE_SOLID; /* we may want DRMODE_FG */ + + /* --- */ + int width = bm->width; + int height = bm->height; + + /* clamp the bitmap's width and height to the viewport */ + if ( width > current_vp->width ) + { + width = current_vp->width; + } + + if ( height > current_vp->height ) + { + height = current_vp->height; + } + + /* draw the image */ + if(bm->format == FORMAT_MONO) + { + lcd_mono_bitmap_part(bm->data, + 0, 0, + bm->width, + current_vp->x, current_vp->y, + width, height); + } + else + { + if (current_vp->drawmode == DRMODE_FG) + { + lcd_bitmap_transparent_part((fb_data *)bm->data, + 0, 0, + bm->width, + current_vp->x, current_vp->y, + width, height); + + } + else + { + lcd_bitmap_part((fb_data *)bm->data, + 0, 0, + bm->width, + current_vp->x, current_vp->y, + width, height); + } + } + + current_vp->drawmode = old_drawmode; + } +} + /* Clear the current viewport */ void lcd_clear_viewport(void) { @@ -289,12 +353,16 @@ { if (!lcd_backdrop) { - do + if (current_vp == &default_vp + || current_vp->bg_pattern != TRANSPARENT_COLOR) { - memset16(dst, current_vp->bg_pattern, current_vp->width); - dst += LCD_WIDTH; + do + { + memset16(dst, current_vp->bg_pattern, current_vp->width); + dst += LCD_WIDTH; + } + while (dst < dst_end); } - while (dst < dst_end); } else { @@ -308,6 +376,9 @@ } } + /* overwrite with the viewport's backdrop */ + draw_viewport_backdrop(current_vp->bg); + if (current_vp == &default_vp) { lcd_scroll_info.lines = 0; @@ -462,8 +533,16 @@ { if (!lcd_backdrop) { - fillopt = OPT_SET; - bits = current_vp->bg_pattern; + if (current_vp == &default_vp + || current_vp->bg_pattern != TRANSPARENT_COLOR) + { + fillopt = OPT_SET; + bits = current_vp->bg_pattern; + } + else + { + fillopt = OPT_SKIP; + } } else fillopt = OPT_COPY; @@ -481,6 +560,10 @@ switch (fillopt) { + case OPT_SKIP: + /* - do nothing - */ + break; + case OPT_SET: memset16(dst, bits, width); break; @@ -497,6 +580,9 @@ while (dst < dst_end); break; } + + /* overwrite with the viewport's backdrop */ + draw_viewport_backdrop(current_vp->bg); } /* Draw a vertical line (optimised) */ @@ -587,8 +673,16 @@ { if (!lcd_backdrop) { - fillopt = OPT_SET; - bits = current_vp->bg_pattern; + if (current_vp == &default_vp + || current_vp->bg_pattern != TRANSPARENT_COLOR) + { + fillopt = OPT_SET; + bits = current_vp->bg_pattern; + } + else + { + fillopt = OPT_SKIP; + } } else fillopt = OPT_COPY; @@ -611,6 +705,10 @@ switch (fillopt) { + case OPT_SKIP: + /* - do nothing - */ + break; + case OPT_SET: memset16(dst, bits, width); break; @@ -631,6 +729,9 @@ dst += LCD_WIDTH; } while (dst < dst_end); + + /* overwrite with the viewport's backdrop */ + draw_viewport_backdrop(current_vp->bg); } /* Fill a rectangle with a gradient */ @@ -901,6 +1002,14 @@ ucs = bidi_l2v(str, 1); + /* set drawmode to FG if there's a backdrop for this viewport */ + int old_drawmode = current_vp->drawmode; + + if (current_vp->bg) + { + current_vp->drawmode = DRMODE_FG; + } + while ((ch = *ucs++) != 0 && x < current_vp->width) { int width; @@ -922,6 +1031,8 @@ x += width - ofs; ofs = 0; } + + current_vp->drawmode = old_drawmode; } /* put a string at a given pixel position */ @@ -995,7 +1106,9 @@ current_vp->drawmode = (style & STYLE_INVERT) ? (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; } + lcd_putsxyofs(xpos, ypos, offset, str); + current_vp->drawmode = lastmode; current_vp->fg_pattern = oldfgcolor; current_vp->bg_pattern = oldbgcolor; @@ -1165,7 +1278,9 @@ current_vp->drawmode = DRMODE_SOLID; break; } + lcd_putsxyofs(xpos, ypos, s->offset, s->line); + current_vp->drawmode = lastmode; current_vp->fg_pattern = old_fgcolor; current_vp->bg_pattern = old_bgcolor; Index: firmware/drivers/lcd-1bit-vert.c =================================================================== --- firmware/drivers/lcd-1bit-vert.c (revision 18997) +++ firmware/drivers/lcd-1bit-vert.c (working copy) @@ -58,12 +58,22 @@ .height = LCDM(HEIGHT), .font = FONT_SYSFIXED, .drawmode = DRMODE_SOLID, +#ifdef HAVE_LCD_BITMAP + .bg = 0, +#endif }; static struct viewport* current_vp = &default_vp; /*** Viewports ***/ +#ifdef HAVE_LCD_BITMAP +void LCDFN(set_viewport_backdrop)(struct bitmap *bg) +{ + current_vp->bg = bg; +} +#endif + void LCDFN(set_viewport)(struct viewport* vp) { if (vp == NULL) Index: firmware/drivers/lcd-2bit-horz.c =================================================================== --- firmware/drivers/lcd-2bit-horz.c (revision 18997) +++ firmware/drivers/lcd-2bit-horz.c (working copy) @@ -56,6 +56,9 @@ .height = LCD_HEIGHT, .font = FONT_SYSFIXED, .drawmode = DRMODE_SOLID, +#ifdef HAVE_LCD_BITMAP + .bg = 0, +#endif .fg_pattern = LCD_DEFAULT_FG, .bg_pattern = LCD_DEFAULT_BG }; @@ -78,6 +81,13 @@ /*** Viewports ***/ +#ifdef HAVE_LCD_BITMAP +void lcd_set_viewport_backdrop(struct bitmap *bg) +{ + current_vp->bg = bg; +} +#endif + void lcd_set_viewport(struct viewport* vp) { if (vp == NULL) Index: firmware/drivers/lcd-2bit-vert.c =================================================================== --- firmware/drivers/lcd-2bit-vert.c (revision 18997) +++ firmware/drivers/lcd-2bit-vert.c (working copy) @@ -58,6 +58,9 @@ .height = LCD_HEIGHT, .font = FONT_SYSFIXED, .drawmode = DRMODE_SOLID, +#ifdef HAVE_LCD_BITMAP + .bg = 0, +#endif .fg_pattern = LCD_DEFAULT_FG, .bg_pattern = LCD_DEFAULT_BG }; @@ -80,6 +83,13 @@ /*** Viewports ***/ +#ifdef HAVE_LCD_BITMAP +void lcd_set_viewport_backdrop(struct bitmap *bg) +{ + lcd_set_backdrop( current_vp->fb ); +} +#endif + void lcd_set_viewport(struct viewport* vp) { if (vp == NULL) Index: firmware/drivers/lcd-2bit-vi.c =================================================================== --- firmware/drivers/lcd-2bit-vi.c (revision 18997) +++ firmware/drivers/lcd-2bit-vi.c (working copy) @@ -62,6 +62,9 @@ .height = LCDM(HEIGHT), .font = FONT_SYSFIXED, .drawmode = DRMODE_SOLID, +#ifdef HAVE_LCD_BITMAP + .bg = 0, +#endif .fg_pattern = LCDM(DEFAULT_FG), .bg_pattern = LCDM(DEFAULT_BG) }; @@ -73,6 +76,13 @@ /*** Viewports ***/ +#ifdef HAVE_LCD_BITMAP +void LCDFN(set_viewport_backdrop)(struct bitmap *bg) +{ + current_vp->bg = bg; +} +#endif + void LCDFN(set_viewport)(struct viewport* vp) { if (vp == NULL) Index: firmware/export/lcd.h =================================================================== --- firmware/export/lcd.h (revision 18997) +++ firmware/export/lcd.h (working copy) @@ -26,26 +26,6 @@ #include "cpu.h" #include "config.h" -struct viewport { - int x; - int y; - int width; - int height; -#ifdef HAVE_LCD_BITMAP - int font; - int drawmode; -#endif -#if LCD_DEPTH > 1 - unsigned fg_pattern; - unsigned bg_pattern; -#ifdef HAVE_LCD_COLOR - unsigned lss_pattern; - unsigned lse_pattern; - unsigned lst_pattern; -#endif -#endif -}; - #define STYLE_DEFAULT 0x00000000 #define STYLE_COLORED 0x10000000 #define STYLE_INVERT 0x20000000 @@ -88,6 +68,27 @@ typedef unsigned char fb_data; #endif +struct viewport { + int x; + int y; + int width; + int height; +#ifdef HAVE_LCD_BITMAP + int font; + int drawmode; + struct bitmap *bg; +#endif +#if LCD_DEPTH > 1 + unsigned fg_pattern; + unsigned bg_pattern; +#ifdef HAVE_LCD_COLOR + unsigned lss_pattern; + unsigned lse_pattern; + unsigned lst_pattern; +#endif +#endif +}; + /* common functions */ extern void lcd_write_command(int byte); extern void lcd_write_command_e(int cmd, int data); @@ -109,6 +110,7 @@ extern int lcd_getheight(void); extern int lcd_getstringsize(const unsigned char *str, int *w, int *h); +extern void lcd_set_viewport_backdrop(struct bitmap *bg); extern void lcd_set_viewport(struct viewport* vp); extern void lcd_update(void); extern void lcd_update_viewport(void); Index: utils/wpseditor/libwps/src/api.c =================================================================== --- utils/wpseditor/libwps/src/api.c (revision 18997) +++ utils/wpseditor/libwps/src/api.c (working copy) @@ -173,6 +173,8 @@ void test_api(struct proxy_api *api) { if (!api->stop_scroll) api->stop_scroll=stop_scroll; + if (!api->set_viewport_backdrop) + api->set_viewport_backdrop=lcd_set_viewport_backdrop; if (!api->set_viewport) api->set_viewport=lcd_set_viewport; if (!api->clear_viewport) @@ -228,6 +230,8 @@ if (api->stop_scroll) screens[0].stop_scroll=api->stop_scroll; screens[0].scroll_stop = lcd_scroll_stop; + if (api->set_viewport_backdrop) + screens[0].set_viewport_backdrop=api->set_viewport_backdrop; if (api->set_viewport) screens[0].set_viewport=api->set_viewport; if (api->clear_viewport) Index: utils/wpseditor/libwps/src/api.h =================================================================== --- utils/wpseditor/libwps/src/api.h (revision 18997) +++ utils/wpseditor/libwps/src/api.h (working copy) @@ -36,6 +36,7 @@ int height; int font; int drawmode; + struct bitmap *bg; unsigned fg_pattern; unsigned bg_pattern; unsigned lss_pattern; @@ -75,6 +76,7 @@ void (*update)(); + void (*set_viewport_backdrop)(struct bitmap *bg); void (*set_viewport)(struct viewport* vp); void (*clear_display)(void); void (*clear_viewport)(int x,int y,int w,int h, int color); Index: utils/wpseditor/libwps/src/lcd.c =================================================================== --- utils/wpseditor/libwps/src/lcd.c (revision 18997) +++ utils/wpseditor/libwps/src/lcd.c (working copy) @@ -36,6 +36,7 @@ #ifdef HAVE_LCD_BITMAP .font = FONT_SYSFIXED, .drawmode = DRMODE_SOLID, + .bg = 0, #endif #if LCD_DEPTH > 1 .fg_pattern = LCD_DEFAULT_FG, @@ -60,6 +61,14 @@ avp->fontheight = sysfont.height; } +#ifdef HAVE_LCD_BITMAP +void lcd_set_viewport_backdrop(struct bitmap *bg) +{ + current_vp->bg = bg; + DEBUGF3("lcd_set_viewport_backdrop(struct bitmap *bg=%x)\n", bg); +} +#endif + void lcd_set_viewport(struct viewport* vp) { if (vp == NULL){