diff --git a/apps/plugin.c b/apps/plugin.c index 35b4179..4278c99 100644 --- a/apps/plugin.c +++ b/apps/plugin.c @@ -668,6 +668,9 @@ static const struct plugin_api rockbox_api = { #if defined(HAVE_USBSTACK) && defined(USB_ENABLE_HID) usb_hid_send, #endif +#ifdef HAVE_LCD_BITMAP + lcd_set_style_hook, +#endif }; int plugin_load(const char* plugin, const void* parameter) diff --git a/apps/plugin.h b/apps/plugin.h index 3809486..caf11a2 100644 --- a/apps/plugin.h +++ b/apps/plugin.h @@ -133,7 +133,7 @@ void* plugin_get_buffer(size_t *buffer_size); #define PLUGIN_MAGIC 0x526F634B /* RocK */ /* increase this every time the api struct changes */ -#define PLUGIN_API_VERSION 165 +#define PLUGIN_API_VERSION 166 /* update this to latest version if a change to the api struct breaks backwards compatibility (and please take the opportunity to sort in any @@ -836,6 +836,13 @@ struct plugin_api { #if defined(HAVE_USBSTACK) && defined(USB_ENABLE_HID) void (*usb_hid_send)(usage_page_t usage_page, int id); #endif +#ifdef HAVE_LCD_BITMAP + void (*lcd_set_style_hook)(void (*hook)(int xpos, int ypos, + const unsigned char *str, + int style, int w, int h, + int offset, + struct viewport *current_vp)); +#endif }; /* plugin header */ diff --git a/apps/screen_access.h b/apps/screen_access.h index c76d2b1..af8fbba 100644 --- a/apps/screen_access.h +++ b/apps/screen_access.h @@ -86,8 +86,9 @@ struct screen int style, int offset); void (*puts_scroll_style)(int x, int y, const unsigned char *string, int style); - void (*puts_scroll_style_offset)(int x, int y, const unsigned char *string, - int style, int offset); + struct scrollinfo* (*puts_scroll_style_offset)(int x, int y, + const unsigned char *string, + int style, int offset); void (*mono_bitmap)(const unsigned char *src, int x, int y, int width, int height); void (*mono_bitmap_part)(const unsigned char *src, int src_x, int src_y, diff --git a/firmware/drivers/lcd-bitmap-common.c b/firmware/drivers/lcd-bitmap-common.c index 802555a..b9ce8d3 100644 --- a/firmware/drivers/lcd-bitmap-common.c +++ b/firmware/drivers/lcd-bitmap-common.c @@ -29,7 +29,20 @@ #define MAIN_LCD #endif -#if defined(MAIN_LCD) && defined(HAVE_LCD_COLOR) +#ifdef MAIN_LCD +static void (*lcd_style_hook)(int xpos, int ypos, const unsigned char *str, + int style, int w, int h, int offset, + struct viewport *current_vp) = NULL; + +void lcd_set_style_hook(void (*hook)(int xpos, int ypos, + const unsigned char *str, int style, + int w, int h, int offset, + struct viewport *current_vp)) +{ + lcd_style_hook = hook; +} + +#ifdef HAVE_LCD_COLOR /* Fill a rectangle with a gradient */ static void lcd_gradient_rect(int x1, int x2, int y, unsigned h, int num_lines, int cur_line) @@ -68,7 +81,8 @@ static void lcd_gradient_rect(int x1, int x2, int y, unsigned h, current_vp->fg_pattern = old_pattern; } -#endif +#endif /* HAVE_LCD_COLOR */ +#endif /* MAIN_LCD */ /* put a string at a given pixel position, skipping first ofs pixel columns */ static void LCDFN(putsxyofs)(int x, int y, int ofs, const unsigned char *str) @@ -117,41 +131,53 @@ static void LCDFN(putsxyofs_style)(int xpos, int ypos, #if defined(MAIN_LCD) && defined(HAVE_LCD_COLOR) int oldfgcolor = current_vp->fg_pattern; int oldbgcolor = current_vp->bg_pattern; - current_vp->drawmode = DRMODE_SOLID | ((style & STYLE_INVERT) ? - DRMODE_INVERSEVID : 0); - if (style & STYLE_COLORED) { - if (current_vp->drawmode == DRMODE_SOLID) - current_vp->fg_pattern = style & STYLE_COLOR_MASK; - else - current_vp->bg_pattern = style & STYLE_COLOR_MASK; - } - current_vp->drawmode ^= DRMODE_INVERSEVID; - if (style & STYLE_GRADIENT) { - current_vp->drawmode = DRMODE_FG; - lcd_gradient_rect(xpos, current_vp->width, ypos, h, - NUMLN_UNPACK(style), CURLN_UNPACK(style)); - current_vp->fg_pattern = current_vp->lst_pattern; - } - else if (style & STYLE_COLORBAR) { - current_vp->drawmode = DRMODE_FG; - current_vp->fg_pattern = current_vp->lss_pattern; - lcd_fillrect(xpos, ypos, current_vp->width - xpos, h); - current_vp->fg_pattern = current_vp->lst_pattern; - } - else { - lcd_fillrect(xrect, ypos, current_vp->width - xrect, h); - current_vp->drawmode = (style & STYLE_INVERT) ? - (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; + if (style & STYLE_CUSTOM && lcd_style_hook) + lcd_style_hook(xpos, ypos, str, style, w, h, offset, current_vp); + else if(!(style & STYLE_NODRAW)) + { + current_vp->drawmode = DRMODE_SOLID | ((style & STYLE_INVERT) ? + DRMODE_INVERSEVID : 0); + if (style & STYLE_COLORED) { + if (current_vp->drawmode == DRMODE_SOLID) + current_vp->fg_pattern = style & STYLE_COLOR_MASK; + else + current_vp->bg_pattern = style & STYLE_COLOR_MASK; + } + current_vp->drawmode ^= DRMODE_INVERSEVID; + if (style & STYLE_GRADIENT) { + current_vp->drawmode = DRMODE_FG; + lcd_gradient_rect(xpos, current_vp->width, ypos, h, + NUMLN_UNPACK(style), CURLN_UNPACK(style)); + current_vp->fg_pattern = current_vp->lst_pattern; + } + else if (style & STYLE_COLORBAR) { + current_vp->drawmode = DRMODE_FG; + current_vp->fg_pattern = current_vp->lss_pattern; + lcd_fillrect(xpos, ypos, current_vp->width - xpos, h); + current_vp->fg_pattern = current_vp->lst_pattern; + } + else { + lcd_fillrect(xrect, ypos, current_vp->width - xrect, h); + current_vp->drawmode = (style & STYLE_INVERT) ? + (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; + } + lcd_putsxyofs(xpos, ypos, offset, str); } - lcd_putsxyofs(xpos, ypos, offset, str); current_vp->fg_pattern = oldfgcolor; current_vp->bg_pattern = oldbgcolor; #else - current_vp->drawmode = DRMODE_SOLID | ((style & STYLE_INVERT) ? - 0 : DRMODE_INVERSEVID); - LCDFN(fillrect)(xrect, ypos, current_vp->width - xrect, h); - current_vp->drawmode ^= DRMODE_INVERSEVID; - LCDFN(putsxyofs)(xpos, ypos, offset, str); +#ifdef MAIN_LCD + if (style & STYLE_CUSTOM && lcd_style_hook) + lcd_style_hook(xpos, ypos, str, style, w, h, offset, current_vp); + else if(!(style & STYLE_NODRAW)) +#endif + { + current_vp->drawmode = DRMODE_SOLID | ((style & STYLE_INVERT) ? + 0 : DRMODE_INVERSEVID); + LCDFN(fillrect)(xrect, ypos, current_vp->width - xrect, h); + current_vp->drawmode ^= DRMODE_INVERSEVID; + LCDFN(putsxyofs)(xpos, ypos, offset, str); + } #endif current_vp->drawmode = lastmode; } @@ -189,27 +215,28 @@ void LCDFN(puts_offset)(int x, int y, const unsigned char *str, int offset) /*** scrolling ***/ -void LCDFN(puts_scroll_style_offset)(int x, int y, const unsigned char *string, - int style, int offset) +struct scrollinfo * +LCDFN(puts_scroll_style_offset)(int x, int y, const unsigned char *string, + int style, int offset) { int w, h; + struct scrollinfo* s = NULL; if ((unsigned)y >= (unsigned)current_vp->height) - return; + return s; /* remove any previously scrolling line at the same location */ lcd_scroll_stop_line(current_vp, y); - if (LCDFN(scroll_info.lines) >= LCDM(SCROLLABLE_LINES)) return; + if (LCDFN(scroll_info.lines) >= LCDM(SCROLLABLE_LINES)) return s; if (!string) - return; + return s; LCDFN(puts_style_offset)(x, y, string, style, offset); LCDFN(getstringsize)(string, &w, &h); if (current_vp->width - x * 8 < w) { /* prepare scroll line */ - struct scrollinfo* s; s = &LCDFN(scroll_info).scroll[LCDFN(scroll_info).lines]; s->start_tick = current_tick + LCDFN(scroll_info).delay; s->style = style; @@ -249,6 +276,7 @@ void LCDFN(puts_scroll_style_offset)(int x, int y, const unsigned char *string, LCDFN(scroll_info).lines++; } + return s; } void LCDFN(puts_scroll)(int x, int y, const unsigned char *string) @@ -315,8 +343,12 @@ void LCDFN(scroll_fn)(void) } LCDFN(putsxyofs_style)(xpos, ypos, s->line, s->style, s->width, pf->height, s->offset); - LCDFN(update_viewport_rect)(xpos, ypos, current_vp->width - xpos, - pf->height); +#ifdef MAIN_LCD + if (!((s->style & STYLE_CUSTOM && lcd_style_hook) || + (s->style & STYLE_NODRAW))) +#endif + LCDFN(update_viewport_rect)(xpos, ypos, current_vp->width - xpos, + pf->height); } LCDFN(set_viewport)(old_vp); } diff --git a/firmware/export/lcd.h b/firmware/export/lcd.h index 11fcc98..7de51b8 100644 --- a/firmware/export/lcd.h +++ b/firmware/export/lcd.h @@ -51,6 +51,8 @@ struct viewport { #define STYLE_INVERT 0x20000000 #define STYLE_COLORBAR 0x40000000 #define STYLE_GRADIENT 0x80000000 +#define STYLE_CUSTOM 0x08000000 +#define STYLE_NODRAW 0x04000000 #define STYLE_MODE_MASK 0xF0000000 #define STYLE_COLOR_MASK 0x0000FFFF #ifdef HAVE_LCD_COLOR @@ -415,11 +417,16 @@ extern void lcd_set_drawmode(int mode); extern int lcd_get_drawmode(void); extern void lcd_setfont(int font); extern int lcd_getfont(void); - +extern void lcd_set_style_hook(void (*hook)(int xpos, int ypos, + const unsigned char *str, + int style, int w, int h, + int offset, + struct viewport *current_vp)); extern void lcd_puts_style_offset(int x, int y, const unsigned char *str, int style, int offset); -extern void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string, - int style, int offset); +extern struct scrollinfo *lcd_puts_scroll_style_offset(int x, int y, + const unsigned char *string, + int style, int offset); /* low level drawing function pointer arrays */ #if LCD_DEPTH >= 8