summaryrefslogtreecommitdiff
path: root/apps/gui
diff options
context:
space:
mode:
authorWilliam Wilgus <wilgus.william@gmail.com>2020-10-07 02:01:35 -0400
committerWilliam Wilgus <wilgus.william@gmail.com>2020-10-26 12:28:48 -0400
commit3237ae4a4ff9296a377ff9194a11038da161208f (patch)
treeaf4338c78467b9b0845d76c39da1fbe10f25e23e /apps/gui
parent12f3ed1699d6bef25bed90ba95cbcc1a6bb4934a (diff)
downloadrockbox-3237ae4a4ff9296a377ff9194a11038da161208f.tar.gz
rockbox-3237ae4a4ff9296a377ff9194a11038da161208f.zip
LCD core move buf ptr and address look up function viewport struct
I'm currently running up against the limitations of the lcd_draw functions I want these functions to be able to be used on any size buffer not just buffers with a stride matching the underlying device [DONE] allow the framebuffer to be decoupled from the device framebuffer [DONE need examples] allow for some simple blit like transformations [DONE] remove the device framebuffer from the plugin api [DONE}ditto remote framebuffer [DONE] remove _viewport_get_framebuffer you can call struct *vp = lcd_set_viewport(NULL) and vp->buffer->fb_ptr while remote lcds may compile (and work in the sim) its not been tested on targets [FIXED] backdrops need work to be screen agnostic [FIXED] screen statusbar is not being combined into the main viewport correctly yet [FIXED] screen elements are displayed incorrectly after switch to void* [FIXED] core didn't restore proper viewport on splash etc. [NEEDS TESTING] remote lcd garbled data [FIXED] osd lib garbled screen on bmp_part [FIXED] grey_set_vp needs to return old viewport like lcd_set_viewport [FIXED] Viewport update now handles viewports with differing buffers/strides by copying to the main buffer [FIXED] splash on top of WPS leaves old framebuffer data (doesn't redraw) [UPDATE] refined this a bit more to have clear_viewport set the clean bit and have skin_render do its own screen clear scrolling viewports no longer trigger wps refresh also fixed a bug where guisyncyesno was displaying and then disappearing [ADDED!] New LCD macros that allow you to create properly size frame buffers in you desired size without wasting bytes (LCD_ and LCD_REMOTE_) LCD_STRIDE(w, h) same as STRIDE_MAIN LCD_FBSTRIDE(w, h) returns target specific stride for a buffer W x H LCD_NBELEMS(w, h) returns the number of fb_data sized elemenst needed for a buffer W x H LCD_NATIVE_STRIDE(s) conversion between rockbox native vertical and lcd native stride (2bitH) test_viewports.c has an example of usage [FIXED!!] 2bit targets don't respect non-native strides [FIXED] Few define snags Change-Id: I0d04c3834e464eca84a5a715743a297a0cefd0af
Diffstat (limited to 'apps/gui')
-rw-r--r--apps/gui/bitmap/list.c4
-rw-r--r--apps/gui/color_picker.c8
-rw-r--r--apps/gui/pitchscreen.c5
-rw-r--r--apps/gui/quickscreen.c4
-rw-r--r--apps/gui/skin_engine/skin_backdrops.c25
-rw-r--r--apps/gui/skin_engine/skin_engine.c6
-rw-r--r--apps/gui/skin_engine/skin_engine.h2
-rw-r--r--apps/gui/skin_engine/skin_parser.c8
-rw-r--r--apps/gui/skin_engine/skin_render.c45
-rw-r--r--apps/gui/skin_engine/wps_internals.h1
-rw-r--r--apps/gui/splash.c4
-rw-r--r--apps/gui/statusbar.c5
-rw-r--r--apps/gui/usb_screen.c5
-rw-r--r--apps/gui/viewport.c26
-rw-r--r--apps/gui/viewport.h3
-rw-r--r--apps/gui/yesno.c9
16 files changed, 111 insertions, 49 deletions
diff --git a/apps/gui/bitmap/list.c b/apps/gui/bitmap/list.c
index 2d3141b8cc..27121eac56 100644
--- a/apps/gui/bitmap/list.c
+++ b/apps/gui/bitmap/list.c
@@ -146,7 +146,7 @@ void list_draw(struct screen *display, struct gui_synclist *list)
146 struct viewport *list_text_vp = &list_text[screen]; 146 struct viewport *list_text_vp = &list_text[screen];
147 int indent = 0; 147 int indent = 0;
148 148
149 display->set_viewport(parent); 149 struct viewport * last_vp = display->set_viewport(parent);
150 display->clear_viewport(); 150 display->clear_viewport();
151 display->scroll_stop_viewport(list_text_vp); 151 display->scroll_stop_viewport(list_text_vp);
152 *list_text_vp = *parent; 152 *list_text_vp = *parent;
@@ -332,7 +332,7 @@ void list_draw(struct screen *display, struct gui_synclist *list)
332 } 332 }
333 display->set_viewport(parent); 333 display->set_viewport(parent);
334 display->update_viewport(); 334 display->update_viewport();
335 display->set_viewport(NULL); 335 display->set_viewport(last_vp);
336} 336}
337 337
338#if defined(HAVE_TOUCHSCREEN) 338#if defined(HAVE_TOUCHSCREEN)
diff --git a/apps/gui/color_picker.c b/apps/gui/color_picker.c
index 03096e5589..a32f1ee179 100644
--- a/apps/gui/color_picker.c
+++ b/apps/gui/color_picker.c
@@ -164,7 +164,7 @@ static void draw_screen(struct screen *display, char *title,
164 struct viewport vp; 164 struct viewport vp;
165 165
166 viewport_set_defaults(&vp, display->screen_type); 166 viewport_set_defaults(&vp, display->screen_type);
167 display->set_viewport(&vp); 167 struct viewport * last_vp = display->set_viewport(&vp);
168 168
169 display->clear_viewport(); 169 display->clear_viewport();
170 170
@@ -323,7 +323,7 @@ static void draw_screen(struct screen *display, char *title,
323 } 323 }
324 324
325 display->update_viewport(); 325 display->update_viewport();
326 display->set_viewport(NULL); 326 display->set_viewport(last_vp);
327} 327}
328 328
329#ifdef HAVE_TOUCHSCREEN 329#ifdef HAVE_TOUCHSCREEN
@@ -341,7 +341,7 @@ static int touchscreen_slider(struct screen *display,
341 struct viewport vp; 341 struct viewport vp;
342 342
343 viewport_set_defaults(&vp, display->screen_type); 343 viewport_set_defaults(&vp, display->screen_type);
344 display->set_viewport(&vp); 344 struct viewport *last_vp = display->set_viewport(&vp);
345 345
346 button = action_get_touchscreen_press_in_vp(&x, &y, &vp); 346 button = action_get_touchscreen_press_in_vp(&x, &y, &vp);
347 if (button == ACTION_UNKNOWN || button == BUTTON_NONE) 347 if (button == ACTION_UNKNOWN || button == BUTTON_NONE)
@@ -373,7 +373,7 @@ static int touchscreen_slider(struct screen *display,
373 char_height*2 + /* + margins for bottom */ 373 char_height*2 + /* + margins for bottom */
374 MARGIN_BOTTOM; /* colored rectangle */ 374 MARGIN_BOTTOM; /* colored rectangle */
375 375
376 display->set_viewport(NULL); 376 display->set_viewport(last_vp);
377 377
378 if (y < text_top) 378 if (y < text_top)
379 { 379 {
diff --git a/apps/gui/pitchscreen.c b/apps/gui/pitchscreen.c
index 0d31193fa6..b5b719ef02 100644
--- a/apps/gui/pitchscreen.c
+++ b/apps/gui/pitchscreen.c
@@ -239,6 +239,7 @@ static void pitchscreen_draw(struct screen *display, int max_lines,
239 char buf[32]; 239 char buf[32];
240 int w, h; 240 int w, h;
241 bool show_lang_pitch; 241 bool show_lang_pitch;
242 struct viewport *last_vp = NULL;
242 243
243 /* "Pitch up/Pitch down" - hide for a small screen, 244 /* "Pitch up/Pitch down" - hide for a small screen,
244 * the text is drawn centered automatically 245 * the text is drawn centered automatically
@@ -249,7 +250,7 @@ static void pitchscreen_draw(struct screen *display, int max_lines,
249 { 250 {
250 int w, h; 251 int w, h;
251 struct viewport *vp = &pitch_viewports[PITCH_TOP]; 252 struct viewport *vp = &pitch_viewports[PITCH_TOP];
252 display->set_viewport(vp); 253 last_vp = display->set_viewport(vp);
253 display->clear_viewport(); 254 display->clear_viewport();
254#ifdef HAVE_TOUCHSCREEN 255#ifdef HAVE_TOUCHSCREEN
255 /* two arrows in the top row, left and right column */ 256 /* two arrows in the top row, left and right column */
@@ -405,7 +406,7 @@ static void pitchscreen_draw(struct screen *display, int max_lines,
405 rightlabel); 406 rightlabel);
406 } 407 }
407 display->update_viewport(); 408 display->update_viewport();
408 display->set_viewport(NULL); 409 display->set_viewport(last_vp);
409} 410}
410 411
411static int32_t pitch_increase(int32_t pitch, int32_t pitch_delta, bool allow_cutoff 412static int32_t pitch_increase(int32_t pitch, int32_t pitch_delta, bool allow_cutoff
diff --git a/apps/gui/quickscreen.c b/apps/gui/quickscreen.c
index 704133c1c4..421cc267ca 100644
--- a/apps/gui/quickscreen.c
+++ b/apps/gui/quickscreen.c
@@ -172,7 +172,7 @@ static void gui_quickscreen_draw(const struct gui_quickscreen *qs,
172 char buf[MAX_PATH]; 172 char buf[MAX_PATH];
173 unsigned const char *title, *value; 173 unsigned const char *title, *value;
174 int temp; 174 int temp;
175 display->set_viewport(parent); 175 struct viewport *last_vp = display->set_viewport(parent);
176 display->clear_viewport(); 176 display->clear_viewport();
177 177
178 for (i = 0; i < QUICKSCREEN_ITEM_COUNT; i++) 178 for (i = 0; i < QUICKSCREEN_ITEM_COUNT; i++)
@@ -225,7 +225,7 @@ static void gui_quickscreen_draw(const struct gui_quickscreen *qs,
225 225
226 display->set_viewport(parent); 226 display->set_viewport(parent);
227 display->update_viewport(); 227 display->update_viewport();
228 display->set_viewport(NULL); 228 display->set_viewport(last_vp);
229} 229}
230 230
231static void talk_qs_option(const struct settings_list *opt, bool enqueue) 231static void talk_qs_option(const struct settings_list *opt, bool enqueue)
diff --git a/apps/gui/skin_engine/skin_backdrops.c b/apps/gui/skin_engine/skin_backdrops.c
index 243fc30a3a..caf705af54 100644
--- a/apps/gui/skin_engine/skin_backdrops.c
+++ b/apps/gui/skin_engine/skin_backdrops.c
@@ -204,11 +204,28 @@ bool skin_backdrops_preload(void)
204 return retval; 204 return retval;
205} 205}
206 206
207void* skin_backdrop_get_buffer(int backdrop_id) 207void skin_backdrop_set_buffer(int backdrop_id, struct skin_viewport *svp)
208{ 208{
209 if (backdrop_id < 0) 209 if (UNLIKELY(!svp))
210 return NULL; 210 return;
211 return backdrops[backdrop_id].buffer; 211 else if (backdrop_id < 0)
212 {
213 svp->vp.buffer = NULL; /*Default*/
214 return;
215 }
216
217 enum screen_type screen = backdrops[backdrop_id].screen;
218 svp->framebuf.ch_ptr = backdrops[backdrop_id].buffer;
219#if defined(HAVE_REMOTE_LCD)
220 if (screen == SCREEN_REMOTE)
221 svp->framebuf.elems = REMOTE_LCD_BACKDROP_BYTES / sizeof(fb_remote_data);
222 else
223#endif
224 {
225 svp->framebuf.elems = LCD_BACKDROP_BYTES / sizeof(fb_data);
226 }
227 svp->framebuf.get_address_fn = NULL; /*Default iterator*/
228 screens[screen].viewport_set_buffer(&svp->vp, &svp->framebuf);
212} 229}
213 230
214void skin_backdrop_show(int backdrop_id) 231void skin_backdrop_show(int backdrop_id)
diff --git a/apps/gui/skin_engine/skin_engine.c b/apps/gui/skin_engine/skin_engine.c
index cd763def1c..049629b181 100644
--- a/apps/gui/skin_engine/skin_engine.c
+++ b/apps/gui/skin_engine/skin_engine.c
@@ -312,7 +312,11 @@ struct wps_state *skin_get_global_state(void)
312bool skin_do_full_update(enum skinnable_screens skin, 312bool skin_do_full_update(enum skinnable_screens skin,
313 enum screen_type screen) 313 enum screen_type screen)
314{ 314{
315 bool ret = skins[skin][screen].needs_full_update; 315 struct viewport *vp = *(screens[screen].current_viewport);
316
317 bool vp_is_dirty = ((vp->flags & VP_FLAG_VP_SET_CLEAN) == VP_FLAG_VP_DIRTY);
318
319 bool ret = (skins[skin][screen].needs_full_update || vp_is_dirty);
316 skins[skin][screen].needs_full_update = false; 320 skins[skin][screen].needs_full_update = false;
317 return ret; 321 return ret;
318} 322}
diff --git a/apps/gui/skin_engine/skin_engine.h b/apps/gui/skin_engine/skin_engine.h
index 55839608be..3b757a5f8b 100644
--- a/apps/gui/skin_engine/skin_engine.h
+++ b/apps/gui/skin_engine/skin_engine.h
@@ -70,7 +70,7 @@ void skin_backdrop_show(int backdrop_id);
70void skin_backdrop_load_setting(void); 70void skin_backdrop_load_setting(void);
71void skin_backdrop_unload(int backdrop_id); 71void skin_backdrop_unload(int backdrop_id);
72#define BACKDROP_BUFFERNAME "#backdrop_buffer#" 72#define BACKDROP_BUFFERNAME "#backdrop_buffer#"
73void* skin_backdrop_get_buffer(int backdrop_id); 73void skin_backdrop_set_buffer(int backdrop_id, struct skin_viewport *svp);
74 74
75/* do the button loop as often as required for the peak meters to update 75/* do the button loop as often as required for the peak meters to update
76 * with a good refresh rate. 76 * with a good refresh rate.
diff --git a/apps/gui/skin_engine/skin_parser.c b/apps/gui/skin_engine/skin_parser.c
index f3a23377ef..e1a8118190 100644
--- a/apps/gui/skin_engine/skin_parser.c
+++ b/apps/gui/skin_engine/skin_parser.c
@@ -259,7 +259,7 @@ static int parse_statusbar_tags(struct skin_element* element,
259 } 259 }
260 else 260 else
261 { 261 {
262 struct skin_viewport *default_vp = SKINOFFSETTOPTR(skin_buffer, first_viewport->data); 262 struct skin_viewport *skin_default = SKINOFFSETTOPTR(skin_buffer, first_viewport->data);
263 if (first_viewport->params_count == 0) 263 if (first_viewport->params_count == 0)
264 { 264 {
265 wps_data->wps_sb_tag = true; 265 wps_data->wps_sb_tag = true;
@@ -267,11 +267,11 @@ static int parse_statusbar_tags(struct skin_element* element,
267 } 267 }
268 if (wps_data->show_sb_on_wps) 268 if (wps_data->show_sb_on_wps)
269 { 269 {
270 viewport_set_defaults(&default_vp->vp, curr_screen); 270 viewport_set_defaults(&skin_default->vp, curr_screen);
271 } 271 }
272 else 272 else
273 { 273 {
274 viewport_set_fullscreen(&default_vp->vp, curr_screen); 274 viewport_set_fullscreen(&skin_default->vp, curr_screen);
275 } 275 }
276#ifdef HAVE_REMOTE_LCD 276#ifdef HAVE_REMOTE_LCD
277 /* This parser requires viewports which will use the settings font to 277 /* This parser requires viewports which will use the settings font to
@@ -279,7 +279,7 @@ static int parse_statusbar_tags(struct skin_element* element,
279 * the current real font id. So force 1 here it will be set correctly 279 * the current real font id. So force 1 here it will be set correctly
280 * at the end 280 * at the end
281 */ 281 */
282 default_vp->vp.font = 1; 282 skin_default->vp.font = 1;
283#endif 283#endif
284 } 284 }
285 return 0; 285 return 0;
diff --git a/apps/gui/skin_engine/skin_render.c b/apps/gui/skin_engine/skin_render.c
index 51c58fc196..00981f5b67 100644
--- a/apps/gui/skin_engine/skin_render.c
+++ b/apps/gui/skin_engine/skin_render.c
@@ -349,6 +349,8 @@ static void do_tags_in_hidden_conditional(struct skin_element* branch,
349{ 349{
350 struct gui_wps *gwps = info->gwps; 350 struct gui_wps *gwps = info->gwps;
351 struct wps_data *data = gwps->data; 351 struct wps_data *data = gwps->data;
352 struct viewport *last_vp;
353
352 /* Tags here are ones which need to be "turned off" or cleared 354 /* Tags here are ones which need to be "turned off" or cleared
353 * if they are in a conditional branch which isnt being used */ 355 * if they are in a conditional branch which isnt being used */
354 if (branch->type == LINE_ALTERNATOR) 356 if (branch->type == LINE_ALTERNATOR)
@@ -420,22 +422,23 @@ static void do_tags_in_hidden_conditional(struct skin_element* branch,
420#if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)) 422#if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1))
421 if (skin_viewport->output_to_backdrop_buffer) 423 if (skin_viewport->output_to_backdrop_buffer)
422 { 424 {
423 void *backdrop = skin_backdrop_get_buffer(data->backdrop_id); 425 skin_backdrop_set_buffer(data->backdrop_id, skin_viewport);
424 gwps->display->set_framebuffer(backdrop);
425 skin_backdrop_show(-1); 426 skin_backdrop_show(-1);
426 } 427 }
427#endif 428#endif
428 gwps->display->set_viewport(&skin_viewport->vp); 429 last_vp = gwps->display->set_viewport(&skin_viewport->vp);
429 gwps->display->clear_viewport(); 430 gwps->display->clear_viewport();
430 gwps->display->set_viewport(&info->skin_vp->vp); 431 gwps->display->set_viewport_ex(&info->skin_vp->vp, 0);
431 skin_viewport->hidden_flags |= VP_DRAW_HIDDEN; 432 skin_viewport->hidden_flags |= VP_DRAW_HIDDEN;
432 433
433#if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)) 434#if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1))
434 if (skin_viewport->output_to_backdrop_buffer) 435 if (skin_viewport->output_to_backdrop_buffer)
435 { 436 {
436 gwps->display->set_framebuffer(NULL); 437 gwps->display->set_viewport_ex(last_vp, 0);
437 skin_backdrop_show(data->backdrop_id); 438 skin_backdrop_show(data->backdrop_id);
438 } 439 }
440#else
441 (void)last_vp;
439#endif 442#endif
440 } 443 }
441 } 444 }
@@ -792,6 +795,7 @@ void skin_render_viewport(struct skin_element* viewport, struct gui_wps *gwps,
792 795
793void skin_render(struct gui_wps *gwps, unsigned refresh_mode) 796void skin_render(struct gui_wps *gwps, unsigned refresh_mode)
794{ 797{
798 const int vp_is_appearing = (VP_DRAW_WASHIDDEN|VP_DRAW_HIDEABLE);
795 struct wps_data *data = gwps->data; 799 struct wps_data *data = gwps->data;
796 struct screen *display = gwps->display; 800 struct screen *display = gwps->display;
797 801
@@ -801,7 +805,20 @@ void skin_render(struct gui_wps *gwps, unsigned refresh_mode)
801 805
802 int old_refresh_mode = refresh_mode; 806 int old_refresh_mode = refresh_mode;
803 skin_buffer = get_skin_buffer(gwps->data); 807 skin_buffer = get_skin_buffer(gwps->data);
804 808
809 struct viewport* first_vp;
810 /* should already be the default buffer */
811 first_vp = display->set_viewport(NULL);
812
813 /* Framebuffer is likely dirty */
814 if ((refresh_mode&SKIN_REFRESH_ALL) == SKIN_REFRESH_ALL)
815 {
816 if ((first_vp->flags & VP_FLAG_VP_SET_CLEAN) == VP_FLAG_VP_DIRTY &&
817 get_current_activity() == ACTIVITY_WPS) /* only clear if in WPS */
818 {
819 display->clear_viewport();
820 }
821 }
805 822
806 viewport = SKINOFFSETTOPTR(skin_buffer, data->tree); 823 viewport = SKINOFFSETTOPTR(skin_buffer, data->tree);
807 skin_viewport = SKINOFFSETTOPTR(skin_buffer, viewport->data); 824 skin_viewport = SKINOFFSETTOPTR(skin_buffer, viewport->data);
@@ -822,12 +839,12 @@ void skin_render(struct gui_wps *gwps, unsigned refresh_mode)
822#if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1) 839#if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1)
823 if (skin_viewport->output_to_backdrop_buffer) 840 if (skin_viewport->output_to_backdrop_buffer)
824 { 841 {
825 display->set_framebuffer(skin_backdrop_get_buffer(data->backdrop_id)); 842 skin_backdrop_set_buffer(data->backdrop_id, skin_viewport);
826 skin_backdrop_show(-1); 843 skin_backdrop_show(-1);
827 } 844 }
828 else 845 else
829 { 846 {
830 display->set_framebuffer(NULL); 847 skin_backdrop_set_buffer(-1, skin_viewport);
831 skin_backdrop_show(data->backdrop_id); 848 skin_backdrop_show(data->backdrop_id);
832 } 849 }
833#endif 850#endif
@@ -842,15 +859,14 @@ void skin_render(struct gui_wps *gwps, unsigned refresh_mode)
842 skin_viewport->hidden_flags |= VP_DRAW_WASHIDDEN; 859 skin_viewport->hidden_flags |= VP_DRAW_WASHIDDEN;
843 continue; 860 continue;
844 } 861 }
845 else if (((skin_viewport->hidden_flags& 862 else if ((skin_viewport->hidden_flags & vp_is_appearing) == vp_is_appearing)
846 (VP_DRAW_WASHIDDEN|VP_DRAW_HIDEABLE))
847 == (VP_DRAW_WASHIDDEN|VP_DRAW_HIDEABLE)))
848 { 863 {
849 vp_refresh_mode = SKIN_REFRESH_ALL; 864 vp_refresh_mode = SKIN_REFRESH_ALL;
850 skin_viewport->hidden_flags = VP_DRAW_HIDEABLE; 865 skin_viewport->hidden_flags = VP_DRAW_HIDEABLE;
851 } 866 }
852 867
853 display->set_viewport(&skin_viewport->vp); 868 display->set_viewport_ex(&skin_viewport->vp, VP_FLAG_VP_SET_CLEAN);
869
854 if ((vp_refresh_mode&SKIN_REFRESH_ALL) == SKIN_REFRESH_ALL) 870 if ((vp_refresh_mode&SKIN_REFRESH_ALL) == SKIN_REFRESH_ALL)
855 { 871 {
856 display->clear_viewport(); 872 display->clear_viewport();
@@ -862,7 +878,6 @@ void skin_render(struct gui_wps *gwps, unsigned refresh_mode)
862 refresh_mode = old_refresh_mode; 878 refresh_mode = old_refresh_mode;
863 } 879 }
864#if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)) 880#if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1))
865 display->set_framebuffer(NULL);
866 skin_backdrop_show(data->backdrop_id); 881 skin_backdrop_show(data->backdrop_id);
867#endif 882#endif
868 883
@@ -872,8 +887,8 @@ void skin_render(struct gui_wps *gwps, unsigned refresh_mode)
872 * to redraw itself */ 887 * to redraw itself */
873 send_event(GUI_EVENT_NEED_UI_UPDATE, NULL); 888 send_event(GUI_EVENT_NEED_UI_UPDATE, NULL);
874 } 889 }
875 /* Restore the default viewport */ 890 /* Restore the first viewport */
876 display->set_viewport(NULL); 891 display->set_viewport_ex(first_vp, VP_FLAG_VP_SET_CLEAN);
877 display->update(); 892 display->update();
878} 893}
879 894
diff --git a/apps/gui/skin_engine/wps_internals.h b/apps/gui/skin_engine/wps_internals.h
index b7d7ff35d0..bf7f52bdbf 100644
--- a/apps/gui/skin_engine/wps_internals.h
+++ b/apps/gui/skin_engine/wps_internals.h
@@ -175,6 +175,7 @@ struct gradient_config {
175#define VP_DEFAULT_LABEL_STRING "|" 175#define VP_DEFAULT_LABEL_STRING "|"
176struct skin_viewport { 176struct skin_viewport {
177 struct viewport vp; /* The LCD viewport struct */ 177 struct viewport vp; /* The LCD viewport struct */
178 struct frame_buffer_t framebuf;
178 char hidden_flags; 179 char hidden_flags;
179 bool is_infovp; 180 bool is_infovp;
180 OFFSETTYPE(char*) label; 181 OFFSETTYPE(char*) label;
diff --git a/apps/gui/splash.c b/apps/gui/splash.c
index 5bcac80169..1415d47a70 100644
--- a/apps/gui/splash.c
+++ b/apps/gui/splash.c
@@ -53,7 +53,7 @@ static void splash_internal(struct screen * screen, const char *fmt, va_list ap)
53 int maxw = 0; 53 int maxw = 0;
54 54
55 viewport_set_defaults(&vp, screen->screen_type); 55 viewport_set_defaults(&vp, screen->screen_type);
56 screen->set_viewport(&vp); 56 struct viewport *last_vp = screen->set_viewport(&vp);
57 57
58 screen->getstringsize(" ", &space_w, &h); 58 screen->getstringsize(" ", &space_w, &h);
59 y = h; 59 y = h;
@@ -157,7 +157,7 @@ static void splash_internal(struct screen * screen, const char *fmt, va_list ap)
157 } 157 }
158 screen->update_viewport(); 158 screen->update_viewport();
159end: 159end:
160 screen->set_viewport(NULL); 160 screen->set_viewport(last_vp);
161} 161}
162 162
163void splashf(int ticks, const char *fmt, ...) 163void splashf(int ticks, const char *fmt, ...)
diff --git a/apps/gui/statusbar.c b/apps/gui/statusbar.c
index cf70b7bb39..708624b23e 100644
--- a/apps/gui/statusbar.c
+++ b/apps/gui/statusbar.c
@@ -183,6 +183,7 @@ static void gui_statusbar_init(struct gui_statusbar * bar)
183void gui_statusbar_draw(struct gui_statusbar * bar, bool force_redraw, struct viewport *vp) 183void gui_statusbar_draw(struct gui_statusbar * bar, bool force_redraw, struct viewport *vp)
184{ 184{
185 struct screen * display = bar->display; 185 struct screen * display = bar->display;
186 struct viewport *last_vp = NULL;
186 187
187 if (!display) 188 if (!display)
188 return; 189 return;
@@ -267,7 +268,7 @@ void gui_statusbar_draw(struct gui_statusbar * bar, bool force_redraw, struct vi
267#endif 268#endif
268 memcmp(&(bar->info), &(bar->lastinfo), sizeof(struct status_info))) 269 memcmp(&(bar->info), &(bar->lastinfo), sizeof(struct status_info)))
269 { 270 {
270 display->set_viewport(vp); 271 last_vp = display->set_viewport(vp);
271 display->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); 272 display->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
272 display->fill_viewport(); 273 display->fill_viewport();
273 display->set_drawmode(DRMODE_SOLID); 274 display->set_drawmode(DRMODE_SOLID);
@@ -343,7 +344,7 @@ void gui_statusbar_draw(struct gui_statusbar * bar, bool force_redraw, struct vi
343 gui_statusbar_led(display); 344 gui_statusbar_led(display);
344#endif 345#endif
345 display->update_viewport(); 346 display->update_viewport();
346 display->set_viewport(NULL); 347 display->set_viewport(last_vp);
347 bar->lastinfo = bar->info; 348 bar->lastinfo = bar->info;
348 } 349 }
349} 350}
diff --git a/apps/gui/usb_screen.c b/apps/gui/usb_screen.c
index 3169831322..31321ec005 100644
--- a/apps/gui/usb_screen.c
+++ b/apps/gui/usb_screen.c
@@ -179,6 +179,7 @@ static void usb_screen_fix_viewports(struct screen *screen,
179 179
180static void usb_screens_draw(struct usb_screen_vps_t *usb_screen_vps_ar) 180static void usb_screens_draw(struct usb_screen_vps_t *usb_screen_vps_ar)
181{ 181{
182 struct viewport *last_vp;
182 static const struct bitmap* logos[NB_SCREENS] = { 183 static const struct bitmap* logos[NB_SCREENS] = {
183 &bm_usblogo, 184 &bm_usblogo,
184#ifdef HAVE_REMOTE_LCD 185#ifdef HAVE_REMOTE_LCD
@@ -194,7 +195,7 @@ static void usb_screens_draw(struct usb_screen_vps_t *usb_screen_vps_ar)
194 struct viewport *parent = &usb_screen_vps->parent; 195 struct viewport *parent = &usb_screen_vps->parent;
195 struct viewport *logo = &usb_screen_vps->logo; 196 struct viewport *logo = &usb_screen_vps->logo;
196 197
197 screen->set_viewport(parent); 198 last_vp = screen->set_viewport(parent);
198 screen->clear_viewport(); 199 screen->clear_viewport();
199 screen->backlight_on(); 200 screen->backlight_on();
200 201
@@ -217,7 +218,7 @@ static void usb_screens_draw(struct usb_screen_vps_t *usb_screen_vps_ar)
217 } 218 }
218 screen->set_viewport(parent); 219 screen->set_viewport(parent);
219 220
220 screen->set_viewport(NULL); 221 screen->set_viewport(last_vp);
221 screen->update_viewport(); 222 screen->update_viewport();
222 } 223 }
223} 224}
diff --git a/apps/gui/viewport.c b/apps/gui/viewport.c
index db58b5d72d..9fdf88e8f0 100644
--- a/apps/gui/viewport.c
+++ b/apps/gui/viewport.c
@@ -31,6 +31,7 @@
31#include "settings.h" 31#include "settings.h"
32#include "misc.h" 32#include "misc.h"
33#include "list.h" 33#include "list.h"
34
34/*some short cuts for fg/bg/line selector handling */ 35/*some short cuts for fg/bg/line selector handling */
35#ifdef HAVE_LCD_COLOR 36#ifdef HAVE_LCD_COLOR
36#define FG_FALLBACK global_settings.fg_color 37#define FG_FALLBACK global_settings.fg_color
@@ -44,7 +45,6 @@
44#define REMOTE_BG_FALLBACK LCD_REMOTE_DEFAULT_BG 45#define REMOTE_BG_FALLBACK LCD_REMOTE_DEFAULT_BG
45#endif 46#endif
46 47
47
48/* all below isn't needed for pc tools (i.e. checkwps/wps editor) 48/* all below isn't needed for pc tools (i.e. checkwps/wps editor)
49 * only viewport_parse_viewport() is */ 49 * only viewport_parse_viewport() is */
50#ifndef __PCTOOL__ 50#ifndef __PCTOOL__
@@ -101,6 +101,7 @@ static void toggle_theme(enum screen_type screen, bool force)
101 bool enable_event = false; 101 bool enable_event = false;
102 static bool was_enabled[NB_SCREENS] = {false}; 102 static bool was_enabled[NB_SCREENS] = {false};
103 static bool after_boot[NB_SCREENS] = {false}; 103 static bool after_boot[NB_SCREENS] = {false};
104 struct viewport *last_vp;
104 105
105 FOR_NB_SCREENS(i) 106 FOR_NB_SCREENS(i)
106 { 107 {
@@ -111,6 +112,7 @@ static void toggle_theme(enum screen_type screen, bool force)
111 112
112 if (is_theme_enabled(screen)) 113 if (is_theme_enabled(screen))
113 { 114 {
115 last_vp = screens[screen].set_viewport(NULL);
114 bool first_boot = theme_stack_top[screen] == 0; 116 bool first_boot = theme_stack_top[screen] == 0;
115 /* remove the left overs from the previous screen. 117 /* remove the left overs from the previous screen.
116 * could cause a tiny flicker. Redo your screen code if that happens */ 118 * could cause a tiny flicker. Redo your screen code if that happens */
@@ -162,7 +164,7 @@ static void toggle_theme(enum screen_type screen, bool force)
162 screens[screen].clear_viewport(); 164 screens[screen].clear_viewport();
163 screens[screen].update_viewport(); 165 screens[screen].update_viewport();
164 } 166 }
165 screens[screen].set_viewport(NULL); 167 screens[screen].set_viewport(last_vp);
166 } 168 }
167 intptr_t force = first_boot?0:1; 169 intptr_t force = first_boot?0:1;
168 170
@@ -282,11 +284,11 @@ static void set_default_align_flags(struct viewport *vp)
282void viewport_set_fullscreen(struct viewport *vp, 284void viewport_set_fullscreen(struct viewport *vp,
283 const enum screen_type screen) 285 const enum screen_type screen)
284{ 286{
287 screens[screen].init_viewport(vp);
285 vp->x = 0; 288 vp->x = 0;
286 vp->y = 0; 289 vp->y = 0;
287 vp->width = screens[screen].lcdwidth; 290 vp->width = screens[screen].lcdwidth;
288 vp->height = screens[screen].lcdheight; 291 vp->height = screens[screen].lcdheight;
289
290#ifndef __PCTOOL__ 292#ifndef __PCTOOL__
291 set_default_align_flags(vp); 293 set_default_align_flags(vp);
292#endif 294#endif
@@ -312,9 +314,25 @@ void viewport_set_fullscreen(struct viewport *vp,
312#endif 314#endif
313} 315}
314 316
317void viewport_set_buffer(struct viewport *vp, struct frame_buffer_t *buffer,
318 const enum screen_type screen)
319{
320 if (!vp) /* NULL vp grabs current framebuffer */
321 vp = *(screens[screen].current_viewport);
322
323 /* NULL sets default buffer */
324 if (buffer && buffer->elems == 0)
325 vp->buffer = NULL;
326 else
327 vp->buffer = buffer;
328 screens[screen].init_viewport(vp);
329}
330
315void viewport_set_defaults(struct viewport *vp, 331void viewport_set_defaults(struct viewport *vp,
316 const enum screen_type screen) 332 const enum screen_type screen)
317{ 333{
334 vp->buffer = NULL; /* use default frame_buffer */
335
318#if !defined(__PCTOOL__) 336#if !defined(__PCTOOL__)
319 struct viewport *sbs_area = NULL; 337 struct viewport *sbs_area = NULL;
320 if (!is_theme_enabled(screen)) 338 if (!is_theme_enabled(screen))
@@ -323,7 +341,7 @@ void viewport_set_defaults(struct viewport *vp,
323 return; 341 return;
324 } 342 }
325 sbs_area = sb_skin_get_info_vp(screen); 343 sbs_area = sb_skin_get_info_vp(screen);
326 344
327 if (sbs_area) 345 if (sbs_area)
328 *vp = *sbs_area; 346 *vp = *sbs_area;
329 else 347 else
diff --git a/apps/gui/viewport.h b/apps/gui/viewport.h
index 683c36fe76..be80e44721 100644
--- a/apps/gui/viewport.h
+++ b/apps/gui/viewport.h
@@ -63,6 +63,9 @@ void viewportmanager_theme_undo(enum screen_type screen, bool force_redraw);
63/* call this when a theme changed */ 63/* call this when a theme changed */
64void viewportmanager_theme_changed(const int); 64void viewportmanager_theme_changed(const int);
65 65
66void viewport_set_buffer(struct viewport *vp, struct frame_buffer_t *buffer,
67 const enum screen_type screen);
68
66#ifdef HAVE_TOUCHSCREEN 69#ifdef HAVE_TOUCHSCREEN
67bool viewport_point_within_vp(const struct viewport *vp, 70bool viewport_point_within_vp(const struct viewport *vp,
68 const int x, const int y); 71 const int x, const int y);
diff --git a/apps/gui/yesno.c b/apps/gui/yesno.c
index 1a1645047a..d70b66f230 100644
--- a/apps/gui/yesno.c
+++ b/apps/gui/yesno.c
@@ -78,8 +78,9 @@ static void gui_yesno_draw(struct gui_yesno * yn)
78 struct screen * display=yn->display; 78 struct screen * display=yn->display;
79 struct viewport *vp = yn->vp; 79 struct viewport *vp = yn->vp;
80 int nb_lines, vp_lines, line_shift=0; 80 int nb_lines, vp_lines, line_shift=0;
81 struct viewport *last_vp;
81 82
82 display->set_viewport(vp); 83 last_vp = display->set_viewport(vp);
83 display->clear_viewport(); 84 display->clear_viewport();
84 nb_lines = yn->main_message->nb_lines; 85 nb_lines = yn->main_message->nb_lines;
85 vp_lines = viewport_get_nb_lines(vp); 86 vp_lines = viewport_get_nb_lines(vp);
@@ -116,7 +117,7 @@ static void gui_yesno_draw(struct gui_yesno * yn)
116 } 117 }
117#endif 118#endif
118 display->update_viewport(); 119 display->update_viewport();
119 display->set_viewport(NULL); 120 display->set_viewport(last_vp);
120} 121}
121 122
122/* 123/*
@@ -133,11 +134,11 @@ static bool gui_yesno_draw_result(struct gui_yesno * yn, enum yesno_res result)
133 struct screen * display=yn->display; 134 struct screen * display=yn->display;
134 if(message==NULL) 135 if(message==NULL)
135 return false; 136 return false;
136 display->set_viewport(vp); 137 struct viewport *last_vp = display->set_viewport(vp);
137 display->clear_viewport(); 138 display->clear_viewport();
138 put_message(yn->display, message, 0, viewport_get_nb_lines(vp)); 139 put_message(yn->display, message, 0, viewport_get_nb_lines(vp));
139 display->update_viewport(); 140 display->update_viewport();
140 display->set_viewport(NULL); 141 display->set_viewport(last_vp);
141 return(true); 142 return(true);
142} 143}
143 144