summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonathan Gordon <rockbox@jdgordon.info>2012-02-28 22:26:32 +1100
committerJonathan Gordon <rockbox@jdgordon.info>2012-02-28 23:03:04 +1100
commit2c71aa9feb0268da7d993feddbbe4db591fcd3ba (patch)
tree29b3c1480abca46813ef2dc3bb8f0862b596fe34
parent13f98df5ed6b8183d972f85a1bfe55cf02194941 (diff)
downloadrockbox-2c71aa9feb0268da7d993feddbbe4db591fcd3ba.tar.gz
rockbox-2c71aa9feb0268da7d993feddbbe4db591fcd3ba.tar.bz2
rockbox-2c71aa9feb0268da7d993feddbbe4db591fcd3ba.zip
lcd/skin_engine: Add the ability to draw onto the backdrop layer
The framebuffer the lcd driver uses can now be changed on the fly which means that regular lcd_* drawing functions can draw onto the "backdrop" buffer. The skin engine can use this to create layered effects. Add the tag %VB to a viewport to draw that viewport onto the backdrop layer. If you want to draw an image onto the backdrop framebuffer use %x(backdrop filename) instead of %X() inside a viewport with %VB. Change-Id: I741498e2af6d4f2d78932cabe8942317893e7cfc
-rw-r--r--apps/gui/skin_engine/skin_backdrops.c34
-rw-r--r--apps/gui/skin_engine/skin_engine.h2
-rw-r--r--apps/gui/skin_engine/skin_parser.c6
-rw-r--r--apps/gui/skin_engine/skin_render.c27
-rw-r--r--apps/gui/skin_engine/wps_internals.h3
-rw-r--r--apps/screen_access.c6
-rw-r--r--apps/screen_access.h3
-rw-r--r--firmware/drivers/lcd-bitmap-common.c8
-rw-r--r--firmware/export/lcd-remote.h1
-rw-r--r--firmware/export/lcd.h1
-rw-r--r--lib/skin_parser/tag_table.c1
-rw-r--r--lib/skin_parser/tag_table.h3
-rw-r--r--manual/appendix/wps_tags.tex2
13 files changed, 87 insertions, 10 deletions
diff --git a/apps/gui/skin_engine/skin_backdrops.c b/apps/gui/skin_engine/skin_backdrops.c
index 12b21ccb50..15b68589a9 100644
--- a/apps/gui/skin_engine/skin_backdrops.c
+++ b/apps/gui/skin_engine/skin_backdrops.c
@@ -95,6 +95,10 @@ int skin_backdrop_assign(char* backdrop, char *bmpdir,
filename[2] = '\0'; /* we check this later to see if we actually have an
image to load. != '\0' means display the image */
}
+ else if (!strcmp(backdrop, BACKDROP_BUFFERNAME))
+ {
+ strcpy(filename, backdrop);
+ }
else
{
get_image_filename(backdrop, bmpdir, filename, sizeof(filename));
@@ -156,15 +160,20 @@ bool skin_backdrops_preload(void)
{
backdrops[i].buffer = core_get_data(backdrops[i].buflib_handle);
handle_being_loaded = backdrops[i].buflib_handle;
- backdrops[i].loaded =
- screens[screen].backdrop_load(filename, backdrops[i].buffer);
- handle_being_loaded = -1;
- if (!backdrops[i].loaded)
+ if (strcmp(filename, BACKDROP_BUFFERNAME))
{
- core_free(backdrops[i].buflib_handle);
- backdrops[i].buflib_handle = -1;
- retval = false;
+ backdrops[i].loaded =
+ screens[screen].backdrop_load(filename, backdrops[i].buffer);
+ handle_being_loaded = -1;
+ if (!backdrops[i].loaded)
+ {
+ core_free(backdrops[i].buflib_handle);
+ backdrops[i].buflib_handle = -1;
+ retval = false;
+ }
}
+ else
+ backdrops[i].loaded = true;
}
else
retval = false;
@@ -176,10 +185,21 @@ bool skin_backdrops_preload(void)
return retval;
}
+void* skin_backdrop_get_buffer(int backdrop_id)
+{
+ if (backdrop_id < 0)
+ return NULL;
+ return backdrops[backdrop_id].buffer;
+}
+
void skin_backdrop_show(int backdrop_id)
{
if (backdrop_id < 0)
+ {
+ screens[0].backdrop_show(NULL);
+ current_lcd_backdrop[0] = -1;
return;
+ }
enum screen_type screen = backdrops[backdrop_id].screen;
if ((backdrops[backdrop_id].loaded == false) ||
(backdrops[backdrop_id].name[0] == '-' &&
diff --git a/apps/gui/skin_engine/skin_engine.h b/apps/gui/skin_engine/skin_engine.h
index ac839fff2e..625467ea3b 100644
--- a/apps/gui/skin_engine/skin_engine.h
+++ b/apps/gui/skin_engine/skin_engine.h
@@ -70,6 +70,8 @@ bool skin_backdrops_preload(void);
void skin_backdrop_show(int backdrop_id);
void skin_backdrop_load_setting(void);
void skin_backdrop_unload(int backdrop_id);
+#define BACKDROP_BUFFERNAME "#backdrop_buffer#"
+void* skin_backdrop_get_buffer(int backdrop_id);
/* do the button loop as often as required for the peak meters to update
* with a good refresh rate.
diff --git a/apps/gui/skin_engine/skin_parser.c b/apps/gui/skin_engine/skin_parser.c
index 340cbbdb01..0fe8789bcb 100644
--- a/apps/gui/skin_engine/skin_parser.c
+++ b/apps/gui/skin_engine/skin_parser.c
@@ -1832,6 +1832,7 @@ static int convert_viewport(struct wps_data *data, struct skin_element* element)
viewport_set_defaults(&skin_vp->vp, curr_screen);
#if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1))
+ skin_vp->output_to_backdrop_buffer = false;
skin_vp->start_fgcolour = skin_vp->vp.fg_pattern;
skin_vp->start_bgcolour = skin_vp->vp.bg_pattern;
#endif
@@ -2023,6 +2024,11 @@ static int skin_element_callback(struct skin_element* element, void* data)
case SKIN_TOKEN_VIEWPORT_TEXTSTYLE:
function = parse_viewporttextstyle;
break;
+ case SKIN_TOKEN_VIEWPORT_DRAWONBG:
+ curr_vp->output_to_backdrop_buffer = true;
+ backdrop_filename = BACKDROP_BUFFERNAME;
+ wps_data->use_extra_framebuffer = true;
+ break;
#endif
#ifdef HAVE_LCD_COLOR
case SKIN_TOKEN_VIEWPORT_GRADIENT_SETUP:
diff --git a/apps/gui/skin_engine/skin_render.c b/apps/gui/skin_engine/skin_render.c
index 951d34a724..d4ddf99c34 100644
--- a/apps/gui/skin_engine/skin_render.c
+++ b/apps/gui/skin_engine/skin_render.c
@@ -385,11 +385,22 @@ static void do_tags_in_hidden_conditional(struct skin_element* branch,
skin_viewport->hidden_flags |= VP_DRAW_WASHIDDEN;
else
{
+ if (skin_viewport->output_to_backdrop_buffer)
+ {
+ void *backdrop = skin_backdrop_get_buffer(data->backdrop_id);
+ gwps->display->set_framebuffer(backdrop);
+ skin_backdrop_show(-1);
+ }
gwps->display->set_viewport(&skin_viewport->vp);
gwps->display->clear_viewport();
gwps->display->scroll_stop(&skin_viewport->vp);
gwps->display->set_viewport(&info->skin_vp->vp);
skin_viewport->hidden_flags |= VP_DRAW_HIDDEN;
+ if (skin_viewport->output_to_backdrop_buffer)
+ {
+ gwps->display->set_framebuffer(NULL);
+ skin_backdrop_show(data->backdrop_id);
+ }
}
}
}
@@ -767,6 +778,7 @@ void skin_render(struct gui_wps *gwps, unsigned refresh_mode)
data->wps_progress_pat[i] = display->get_locked_pattern();
}
#endif
+
viewport = SKINOFFSETTOPTR(skin_buffer, data->tree);
skin_viewport = SKINOFFSETTOPTR(skin_buffer, viewport->data);
label = SKINOFFSETTOPTR(skin_buffer, skin_viewport->label);
@@ -786,6 +798,16 @@ void skin_render(struct gui_wps *gwps, unsigned refresh_mode)
#if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1)
skin_viewport->vp.fg_pattern = skin_viewport->start_fgcolour;
skin_viewport->vp.bg_pattern = skin_viewport->start_bgcolour;
+ if (skin_viewport->output_to_backdrop_buffer)
+ {
+ display->set_framebuffer(skin_backdrop_get_buffer(data->backdrop_id));
+ skin_backdrop_show(-1);
+ }
+ else
+ {
+ display->set_framebuffer(NULL);
+ skin_backdrop_show(data->backdrop_id);
+ }
#endif
#ifdef HAVE_LCD_COLOR
skin_viewport->vp.lss_pattern = skin_viewport->start_gradient.start;
@@ -822,7 +844,10 @@ void skin_render(struct gui_wps *gwps, unsigned refresh_mode)
skin_viewport, vp_refresh_mode);
refresh_mode = old_refresh_mode;
}
-
+#ifdef HAVE_LCD_BITMAP
+ display->set_framebuffer(NULL);
+ skin_backdrop_show(data->backdrop_id);
+#endif
/* Restore the default viewport */
display->set_viewport(NULL);
display->update();
diff --git a/apps/gui/skin_engine/wps_internals.h b/apps/gui/skin_engine/wps_internals.h
index c55c8d2515..1ea5dbf467 100644
--- a/apps/gui/skin_engine/wps_internals.h
+++ b/apps/gui/skin_engine/wps_internals.h
@@ -44,7 +44,6 @@
#include "statusbar.h"
#include "metadata.h"
-
#define TOKEN_VALUE_ONLY 0x0DEADC0D
/* wps_data*/
@@ -166,6 +165,7 @@ struct skin_viewport {
OFFSETTYPE(char*) label;
int parsed_fontid;
#if LCD_DEPTH > 1
+ bool output_to_backdrop_buffer;
unsigned start_fgcolour;
unsigned start_bgcolour;
#ifdef HAVE_LCD_COLOR
@@ -328,6 +328,7 @@ struct wps_data
#endif
#ifdef HAVE_BACKDROP_IMAGE
int backdrop_id;
+ bool use_extra_framebuffer;
#endif
#ifdef HAVE_TOUCHSCREEN
diff --git a/apps/screen_access.c b/apps/screen_access.c
index 5ab08b7fc5..43000e1360 100644
--- a/apps/screen_access.c
+++ b/apps/screen_access.c
@@ -262,6 +262,9 @@ struct screen screens[NB_SCREENS] =
#ifdef HAVE_BUTTONBAR
.has_buttonbar=false,
#endif
+#if defined(HAVE_LCD_BITMAP)
+ .set_framebuffer = (void*)lcd_set_framebuffer,
+#endif
},
#if NB_SCREENS == 2
{
@@ -357,6 +360,9 @@ struct screen screens[NB_SCREENS] =
#ifdef HAVE_BUTTONBAR
.has_buttonbar=false,
#endif
+#if defined(HAVE_LCD_BITMAP)
+ .set_framebuffer = (void*)lcd_remote_set_framebuffer,
+#endif
}
#endif /* NB_SCREENS == 2 */
};
diff --git a/apps/screen_access.h b/apps/screen_access.h
index a9d1408898..343829b915 100644
--- a/apps/screen_access.h
+++ b/apps/screen_access.h
@@ -160,6 +160,9 @@ struct screen
bool (*backdrop_load)(const char *filename, char* backdrop_buffer);
void (*backdrop_show)(char* backdrop_buffer);
#endif
+#if defined(HAVE_LCD_BITMAP)
+ void (*set_framebuffer)(void *framebuffer);
+#endif
};
#if defined(HAVE_LCD_BITMAP) || defined(HAVE_REMOTE_LCD)
diff --git a/firmware/drivers/lcd-bitmap-common.c b/firmware/drivers/lcd-bitmap-common.c
index f122e336d7..b0be687ed2 100644
--- a/firmware/drivers/lcd-bitmap-common.c
+++ b/firmware/drivers/lcd-bitmap-common.c
@@ -81,6 +81,14 @@ static void lcd_gradient_rect(int x1, int x2, int y, unsigned h,
}
#endif
+void LCDFN(set_framebuffer)(FBFN(data) *fb)
+{
+ if (fb)
+ LCDFN(framebuffer) = fb;
+ else
+ LCDFN(framebuffer) = &LCDFN(static_framebuffer)[0][0];
+}
+
/*
* draws the borders of the current viewport
**/
diff --git a/firmware/export/lcd-remote.h b/firmware/export/lcd-remote.h
index 0f5f7ed6b7..1bb19a5cfa 100644
--- a/firmware/export/lcd-remote.h
+++ b/firmware/export/lcd-remote.h
@@ -132,6 +132,7 @@ void lcd_remote_init(void);
void lcd_remote_write_command(int cmd);
void lcd_remote_write_command_ex(int cmd, int data);
void lcd_remote_write_data(const fb_remote_data *data, int count);
+extern void lcd_remote_set_framebuffer(fb_remote_data *fb);
extern void lcd_remote_bitmap_part(const fb_remote_data *src, int src_x,
int src_y, int stride, int x, int y,
diff --git a/firmware/export/lcd.h b/firmware/export/lcd.h
index 052b368d9b..7e0e979821 100644
--- a/firmware/export/lcd.h
+++ b/firmware/export/lcd.h
@@ -529,6 +529,7 @@ extern void lcd_bitmap_part(const fb_data *src, int src_x, int src_y,
int stride, int x, int y, int width, int height);
extern void lcd_bitmap(const fb_data *src, int x, int y, int width,
int height);
+extern void lcd_set_framebuffer(fb_data *fb);
extern void lcd_scroll_step(int pixels);
diff --git a/lib/skin_parser/tag_table.c b/lib/skin_parser/tag_table.c
index 9a183986ce..a44b2ef251 100644
--- a/lib/skin_parser/tag_table.c
+++ b/lib/skin_parser/tag_table.c
@@ -204,6 +204,7 @@ static const struct tag_info legal_tags[] =
{ SKIN_TOKEN_VIEWPORT_BGCOLOUR, "Vb" , "s", SKIN_REFRESH_STATIC|NOBREAK },
{ SKIN_TOKEN_VIEWPORT_TEXTSTYLE, "Vs" , "S|s", SKIN_REFRESH_STATIC },
{ SKIN_TOKEN_VIEWPORT_GRADIENT_SETUP, "Vg" , "SS|s", SKIN_REFRESH_STATIC|NOBREAK },
+ { SKIN_TOKEN_VIEWPORT_DRAWONBG, "VB" , "", SKIN_REFRESH_STATIC|NOBREAK },
{ SKIN_TOKEN_VIEWPORT_CONDITIONAL, "Vl" , "SIIiii", 0 },
{ SKIN_TOKEN_UIVIEWPORT_LOAD, "Vi" , "sIIiii", 0 },
diff --git a/lib/skin_parser/tag_table.h b/lib/skin_parser/tag_table.h
index d14d31fcb2..cf0096f28d 100644
--- a/lib/skin_parser/tag_table.h
+++ b/lib/skin_parser/tag_table.h
@@ -92,7 +92,8 @@ enum skin_token_type {
SKIN_TOKEN_VIEWPORT_BGCOLOUR,
SKIN_TOKEN_VIEWPORT_TEXTSTYLE,
SKIN_TOKEN_VIEWPORT_GRADIENT_SETUP,
-
+ SKIN_TOKEN_VIEWPORT_DRAWONBG,
+
/* Battery */
SKIN_TOKEN_BATTERY_PERCENT,
SKIN_TOKEN_BATTERY_PERCENTBAR,
diff --git a/manual/appendix/wps_tags.tex b/manual/appendix/wps_tags.tex
index ba4cbd16ee..5890e20e93 100644
--- a/manual/appendix/wps_tags.tex
+++ b/manual/appendix/wps_tags.tex
@@ -91,6 +91,8 @@ show the information for the next song to be played.
\config{\%VI('label')} & Set the Info Viewport to use the viewport called
label, as declared with the previous tag.\\
+
+ \config{\%VB} & Draw this viewport on the backdrop layer.
\end{tagmap}
\section{Additional Fonts}