summaryrefslogtreecommitdiff
path: root/apps
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
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')
-rw-r--r--apps/alarm_menu.c5
-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
-rw-r--r--apps/menus/time_menu.c4
-rw-r--r--apps/misc.c4
-rw-r--r--apps/onplay.c11
-rw-r--r--apps/plugin.c12
-rw-r--r--apps/plugin.h7
-rw-r--r--apps/plugins/doom/i_video.c10
-rw-r--r--apps/plugins/fire.c5
-rw-r--r--apps/plugins/imageviewer/imageviewer.c11
-rw-r--r--apps/plugins/imageviewer/jpeg/yuv2rgb.c12
-rw-r--r--apps/plugins/invadrox.c12
-rw-r--r--apps/plugins/lib/grey.h2
-rw-r--r--apps/plugins/lib/grey_core.c13
-rw-r--r--apps/plugins/lib/grey_parm.c4
-rw-r--r--apps/plugins/lib/osd.c27
-rw-r--r--apps/plugins/lib/xlcd.h2
-rw-r--r--apps/plugins/lib/xlcd_core.c9
-rw-r--r--apps/plugins/lib/xlcd_draw.c14
-rw-r--r--apps/plugins/lib/xlcd_scroll.c107
-rw-r--r--apps/plugins/lua/rocklib_img.c8
-rw-r--r--apps/plugins/mpegplayer/mpegplayer.c12
-rw-r--r--apps/plugins/oscilloscope.c4
-rwxr-xr-xapps/plugins/pacbox/pacbox.c6
-rw-r--r--apps/plugins/pictureflow/pictureflow.c6
-rw-r--r--apps/plugins/plasma.c11
-rw-r--r--apps/plugins/puzzles/rockbox.c17
-rw-r--r--apps/plugins/rockboy/lcd.c15
-rw-r--r--apps/plugins/rockboy/sys_rockbox.c10
-rw-r--r--apps/plugins/sdl/src/video/rockbox/SDL_rockboxvideo.c11
-rw-r--r--apps/plugins/test_resize.c4
-rw-r--r--apps/plugins/test_viewports.c27
-rw-r--r--apps/plugins/xworld/sys.c21
-rw-r--r--apps/plugins/zxbox/zxvid_16bpp.c11
-rw-r--r--apps/plugins/zxbox/zxvid_2bpp.c13
-rw-r--r--apps/recorder/keyboard.c4
-rw-r--r--apps/screen_access.c21
-rw-r--r--apps/screen_access.h7
-rw-r--r--apps/screens.c5
54 files changed, 472 insertions, 172 deletions
diff --git a/apps/alarm_menu.c b/apps/alarm_menu.c
index 497747bd7b..62b54a84bb 100644
--- a/apps/alarm_menu.c
+++ b/apps/alarm_menu.c
@@ -60,6 +60,7 @@ int alarm_screen(void)
60 bool update = true; 60 bool update = true;
61 bool hour_wrapped = false; 61 bool hour_wrapped = false;
62 struct viewport vp[NB_SCREENS]; 62 struct viewport vp[NB_SCREENS];
63 struct viewport * last_vp;
63 64
64 rtc_get_alarm(&h, &m); 65 rtc_get_alarm(&h, &m);
65 66
@@ -91,11 +92,11 @@ int alarm_screen(void)
91 92
92 FOR_NB_SCREENS(i) 93 FOR_NB_SCREENS(i)
93 { 94 {
94 screens[i].set_viewport(&vp[i]); 95 last_vp = screens[i].set_viewport(&vp[i]);
95 screens[i].putsf(0, 1, str(LANG_ALARM_MOD_TIME)); 96 screens[i].putsf(0, 1, str(LANG_ALARM_MOD_TIME));
96 screens[i].putsf(0, 2, "%02d:%02d", h, m); 97 screens[i].putsf(0, 2, "%02d:%02d", h, m);
97 screens[i].update_viewport(); 98 screens[i].update_viewport();
98 screens[i].set_viewport(NULL); 99 screens[i].set_viewport(last_vp);
99 } 100 }
100 button = get_action(CONTEXT_SETTINGS,HZ); 101 button = get_action(CONTEXT_SETTINGS,HZ);
101 102
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
diff --git a/apps/menus/time_menu.c b/apps/menus/time_menu.c
index 6ebf005ffd..edd2e19a2b 100644
--- a/apps/menus/time_menu.c
+++ b/apps/menus/time_menu.c
@@ -169,7 +169,7 @@ static void draw_timedate(struct viewport *vp, struct screen *display)
169 const char *t = time, *d = date; 169 const char *t = time, *d = date;
170 if (vp->height == 0) 170 if (vp->height == 0)
171 return; 171 return;
172 display->set_viewport(vp); 172 struct viewport *last_vp = display->set_viewport(vp);
173 display->clear_viewport(); 173 display->clear_viewport();
174 if (viewport_get_nb_lines(vp) >= 4) 174 if (viewport_get_nb_lines(vp) >= 4)
175 line = 1; 175 line = 1;
@@ -200,7 +200,7 @@ static void draw_timedate(struct viewport *vp, struct screen *display)
200 display->puts(0, line, d); 200 display->puts(0, line, d);
201 201
202 display->update_viewport(); 202 display->update_viewport();
203 display->set_viewport(NULL); 203 display->set_viewport(last_vp);
204} 204}
205 205
206 206
diff --git a/apps/misc.c b/apps/misc.c
index 7d4ca97ff8..3a8798fec0 100644
--- a/apps/misc.c
+++ b/apps/misc.c
@@ -769,7 +769,9 @@ int show_logo( void )
769 lcd_remote_setfont(FONT_UI); 769 lcd_remote_setfont(FONT_UI);
770 lcd_remote_update(); 770 lcd_remote_update();
771#endif 771#endif
772 772#ifdef SIMULATOR
773 sleep(HZ); /* sim is too fast to see logo */
774#endif
773 return 0; 775 return 0;
774} 776}
775 777
diff --git a/apps/onplay.c b/apps/onplay.c
index f2ebd47630..ded2994c97 100644
--- a/apps/onplay.c
+++ b/apps/onplay.c
@@ -795,33 +795,34 @@ static int cat_playlist_callback(int action,
795 795
796static void draw_slider(void) 796static void draw_slider(void)
797{ 797{
798 struct viewport *last_vp;
798 FOR_NB_SCREENS(i) 799 FOR_NB_SCREENS(i)
799 { 800 {
800 struct viewport vp; 801 struct viewport vp;
801 int slider_height = 2*screens[i].getcharheight(); 802 int slider_height = 2*screens[i].getcharheight();
802 viewport_set_defaults(&vp, i); 803 viewport_set_defaults(&vp, i);
803 screens[i].set_viewport(&vp); 804 last_vp = screens[i].set_viewport(&vp);
804 show_busy_slider(&screens[i], 1, vp.height - slider_height, 805 show_busy_slider(&screens[i], 1, vp.height - slider_height,
805 vp.width-2, slider_height-1); 806 vp.width-2, slider_height-1);
806 screens[i].update_viewport(); 807 screens[i].update_viewport();
807 screens[i].set_viewport(NULL); 808 screens[i].set_viewport(last_vp);
808 } 809 }
809} 810}
810 811
811static void clear_display(bool update) 812static void clear_display(bool update)
812{ 813{
813 struct viewport vp; 814 struct viewport vp;
814 815 struct viewport *last_vp;
815 FOR_NB_SCREENS(i) 816 FOR_NB_SCREENS(i)
816 { 817 {
817 struct screen * screen = &screens[i]; 818 struct screen * screen = &screens[i];
818 viewport_set_defaults(&vp, screen->screen_type); 819 viewport_set_defaults(&vp, screen->screen_type);
819 screen->set_viewport(&vp); 820 last_vp = screen->set_viewport(&vp);
820 screen->clear_viewport(); 821 screen->clear_viewport();
821 if (update) { 822 if (update) {
822 screen->update_viewport(); 823 screen->update_viewport();
823 } 824 }
824 screen->set_viewport(NULL); 825 screen->set_viewport(last_vp);
825 } 826 }
826} 827}
827 828
diff --git a/apps/plugin.c b/apps/plugin.c
index 48f9dac487..4a50c2b3a3 100644
--- a/apps/plugin.c
+++ b/apps/plugin.c
@@ -194,9 +194,7 @@ static const struct plugin_api rockbox_api = {
194 lcd_putsf, 194 lcd_putsf,
195 lcd_puts_scroll, 195 lcd_puts_scroll,
196 lcd_scroll_stop, 196 lcd_scroll_stop,
197 &lcd_framebuffer,
198 lcd_set_viewport, 197 lcd_set_viewport,
199 lcd_set_framebuffer,
200 lcd_bmp_part, 198 lcd_bmp_part,
201 lcd_update_rect, 199 lcd_update_rect,
202 lcd_set_drawmode, 200 lcd_set_drawmode,
@@ -281,7 +279,6 @@ static const struct plugin_api rockbox_api = {
281 lcd_remote_mono_bitmap_part, 279 lcd_remote_mono_bitmap_part,
282 lcd_remote_mono_bitmap, 280 lcd_remote_mono_bitmap,
283 lcd_remote_putsxy, 281 lcd_remote_putsxy,
284 &lcd_remote_framebuffer;
285 lcd_remote_update, 282 lcd_remote_update,
286 lcd_remote_update_rect, 283 lcd_remote_update_rect,
287#if (LCD_REMOTE_DEPTH > 1) 284#if (LCD_REMOTE_DEPTH > 1)
@@ -303,6 +300,7 @@ static const struct plugin_api rockbox_api = {
303 viewportmanager_theme_enable, 300 viewportmanager_theme_enable,
304 viewportmanager_theme_undo, 301 viewportmanager_theme_undo,
305 viewport_set_fullscreen, 302 viewport_set_fullscreen,
303 viewport_set_buffer,
306 304
307#ifdef HAVE_BACKLIGHT 305#ifdef HAVE_BACKLIGHT
308 /* lcd backlight */ 306 /* lcd backlight */
@@ -869,11 +867,12 @@ int plugin_load(const char* plugin, const void* parameter)
869#endif 867#endif
870 868
871 *(p_hdr->api) = &rockbox_api; 869 *(p_hdr->api) = &rockbox_api;
872 870 lcd_set_viewport(NULL);
873 lcd_clear_display(); 871 lcd_clear_display();
874 lcd_update(); 872 lcd_update();
875 873
876#ifdef HAVE_REMOTE_LCD 874#ifdef HAVE_REMOTE_LCD
875 lcd_remote_set_viewport(NULL);
877 lcd_remote_clear_display(); 876 lcd_remote_clear_display();
878 lcd_remote_update(); 877 lcd_remote_update();
879#endif 878#endif
@@ -914,7 +913,8 @@ int plugin_load(const char* plugin, const void* parameter)
914#ifdef HAVE_TOUCHSCREEN 913#ifdef HAVE_TOUCHSCREEN
915 touchscreen_set_mode(global_settings.touch_mode); 914 touchscreen_set_mode(global_settings.touch_mode);
916#endif 915#endif
917 916 /* restore default vp */
917 lcd_set_viewport(NULL);
918 screen_helper_setfont(FONT_UI); 918 screen_helper_setfont(FONT_UI);
919#if LCD_DEPTH > 1 919#if LCD_DEPTH > 1
920#ifdef HAVE_LCD_COLOR 920#ifdef HAVE_LCD_COLOR
@@ -928,6 +928,8 @@ int plugin_load(const char* plugin, const void* parameter)
928#endif /* LCD_DEPTH */ 928#endif /* LCD_DEPTH */
929 929
930#ifdef HAVE_REMOTE_LCD 930#ifdef HAVE_REMOTE_LCD
931 lcd_remote_set_viewport(NULL);
932
931#if LCD_REMOTE_DEPTH > 1 933#if LCD_REMOTE_DEPTH > 1
932 lcd_remote_set_drawinfo(DRMODE_SOLID, LCD_REMOTE_DEFAULT_FG, 934 lcd_remote_set_drawinfo(DRMODE_SOLID, LCD_REMOTE_DEFAULT_FG,
933 LCD_REMOTE_DEFAULT_BG); 935 LCD_REMOTE_DEFAULT_BG);
diff --git a/apps/plugin.h b/apps/plugin.h
index 12fc5424f1..395caaddc0 100644
--- a/apps/plugin.h
+++ b/apps/plugin.h
@@ -204,9 +204,7 @@ struct plugin_api {
204 void (*lcd_putsf)(int x, int y, const unsigned char *fmt, ...); 204 void (*lcd_putsf)(int x, int y, const unsigned char *fmt, ...);
205 bool (*lcd_puts_scroll)(int x, int y, const unsigned char* string); 205 bool (*lcd_puts_scroll)(int x, int y, const unsigned char* string);
206 void (*lcd_scroll_stop)(void); 206 void (*lcd_scroll_stop)(void);
207 fb_data** lcd_framebuffer; 207 struct viewport* (*lcd_set_viewport)(struct viewport* vp);
208 void (*lcd_set_viewport)(struct viewport* vp);
209 void (*lcd_set_framebuffer)(fb_data *fb);
210 void (*lcd_bmp_part)(const struct bitmap *bm, int src_x, int src_y, 208 void (*lcd_bmp_part)(const struct bitmap *bm, int src_x, int src_y,
211 int x, int y, int width, int height); 209 int x, int y, int width, int height);
212 void (*lcd_update_rect)(int x, int y, int width, int height); 210 void (*lcd_update_rect)(int x, int y, int width, int height);
@@ -314,7 +312,6 @@ struct plugin_api {
314 void (*lcd_remote_mono_bitmap)(const unsigned char *src, int x, int y, 312 void (*lcd_remote_mono_bitmap)(const unsigned char *src, int x, int y,
315 int width, int height); 313 int width, int height);
316 void (*lcd_remote_putsxy)(int x, int y, const unsigned char *string); 314 void (*lcd_remote_putsxy)(int x, int y, const unsigned char *string);
317 fb_remote_data** lcd_remote_framebuffer;
318 void (*lcd_remote_update)(void); 315 void (*lcd_remote_update)(void);
319 void (*lcd_remote_update_rect)(int x, int y, int width, int height); 316 void (*lcd_remote_update_rect)(int x, int y, int width, int height);
320#if (LCD_REMOTE_DEPTH > 1) 317#if (LCD_REMOTE_DEPTH > 1)
@@ -338,6 +335,8 @@ struct plugin_api {
338 void (*viewportmanager_theme_undo)(enum screen_type screen, bool force_redraw); 335 void (*viewportmanager_theme_undo)(enum screen_type screen, bool force_redraw);
339 void (*viewport_set_fullscreen)(struct viewport *vp, 336 void (*viewport_set_fullscreen)(struct viewport *vp,
340 const enum screen_type screen); 337 const enum screen_type screen);
338 void (*viewport_set_buffer)(struct viewport *vp, struct frame_buffer_t *buffer,
339 const enum screen_type screen);
341 340
342#ifdef HAVE_BACKLIGHT 341#ifdef HAVE_BACKLIGHT
343 /* lcd backlight */ 342 /* lcd backlight */
diff --git a/apps/plugins/doom/i_video.c b/apps/plugins/doom/i_video.c
index 3186fac16d..99b4de827d 100644
--- a/apps/plugins/doom/i_video.c
+++ b/apps/plugins/doom/i_video.c
@@ -1052,6 +1052,12 @@ void I_FinishUpdate (void)
1052 rb->lcd_blit_pal256(src, 0, 0, 0, 0, LCD_WIDTH, LCD_HEIGHT); 1052 rb->lcd_blit_pal256(src, 0, 0, 0, 0, LCD_WIDTH, LCD_HEIGHT);
1053#endif 1053#endif
1054#elif defined(HAVE_LCD_COLOR) 1054#elif defined(HAVE_LCD_COLOR)
1055 static fb_data *lcd_fb = NULL;
1056 if (!lcd_fb)
1057 {
1058 struct viewport *vp_main = *(rb->screens[SCREEN_MAIN]->current_viewport);
1059 lcd_fb = vp_main->buffer->fb_ptr;
1060 }
1055#if(LCD_HEIGHT>LCD_WIDTH) 1061#if(LCD_HEIGHT>LCD_WIDTH)
1056 if(rotate_screen) 1062 if(rotate_screen)
1057 { 1063 {
@@ -1059,7 +1065,7 @@ void I_FinishUpdate (void)
1059 1065
1060 for (y = 1; y <= SCREENHEIGHT; y++) 1066 for (y = 1; y <= SCREENHEIGHT; y++)
1061 { 1067 {
1062 fb_data *dst = *rb->lcd_framebuffer + LCD_WIDTH - y; 1068 fb_data *dst = lcd_fb + LCD_WIDTH - y;
1063 count = SCREENWIDTH; 1069 count = SCREENWIDTH;
1064 1070
1065 do 1071 do
@@ -1073,7 +1079,7 @@ void I_FinishUpdate (void)
1073 else 1079 else
1074#endif 1080#endif
1075 { 1081 {
1076 fb_data *dst = *rb->lcd_framebuffer; 1082 fb_data *dst = lcd_fb;
1077 count = SCREENWIDTH*SCREENHEIGHT; 1083 count = SCREENWIDTH*SCREENHEIGHT;
1078 1084
1079 do 1085 do
diff --git a/apps/plugins/fire.c b/apps/plugins/fire.c
index 95edbf37c4..f3e6fb35e4 100644
--- a/apps/plugins/fire.c
+++ b/apps/plugins/fire.c
@@ -30,6 +30,7 @@
30#ifndef HAVE_LCD_COLOR 30#ifndef HAVE_LCD_COLOR
31#include "lib/grey.h" 31#include "lib/grey.h"
32#endif 32#endif
33static fb_data *lcd_fb = NULL;
33 34
34#if (LCD_WIDTH == 112) && (LCD_HEIGHT == 64) 35#if (LCD_WIDTH == 112) && (LCD_HEIGHT == 64)
35/* Archos has not enough plugin RAM for full-width fire :( */ 36/* Archos has not enough plugin RAM for full-width fire :( */
@@ -251,7 +252,7 @@ static inline void fire_draw(struct fire* fire)
251#ifndef HAVE_LCD_COLOR 252#ifndef HAVE_LCD_COLOR
252 dest = draw_buffer; 253 dest = draw_buffer;
253#else 254#else
254 dest = *rb->lcd_framebuffer + LCD_WIDTH * y + FIRE_XPOS; 255 dest = lcd_fb + LCD_WIDTH * y + FIRE_XPOS;
255#endif 256#endif
256 end = dest + FIRE_WIDTH; 257 end = dest + FIRE_WIDTH;
257 258
@@ -379,6 +380,8 @@ enum plugin_status plugin_start(const void* parameter)
379 rb->lcd_set_mode(LCD_MODE_PAL256); 380 rb->lcd_set_mode(LCD_MODE_PAL256);
380#endif 381#endif
381 382
383 struct viewport *vp_main = rb->lcd_set_viewport(NULL);
384 lcd_fb = vp_main->buffer->fb_ptr;
382 ret = main(); 385 ret = main();
383 386
384#if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_PAL256) 387#if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_PAL256)
diff --git a/apps/plugins/imageviewer/imageviewer.c b/apps/plugins/imageviewer/imageviewer.c
index 37c5838d73..4b1a982438 100644
--- a/apps/plugins/imageviewer/imageviewer.c
+++ b/apps/plugins/imageviewer/imageviewer.c
@@ -509,6 +509,13 @@ static void pan_view_up(struct image_info *info)
509 the bottom */ 509 the bottom */
510static void pan_view_down(struct image_info *info) 510static void pan_view_down(struct image_info *info)
511{ 511{
512 static fb_data *lcd_fb = NULL;
513 if (!lcd_fb)
514 {
515 struct viewport *vp_main = *(rb->screens[SCREEN_MAIN]->current_viewport);
516 lcd_fb = vp_main->buffer->fb_ptr;
517 }
518
512 int move; 519 int move;
513 520
514 move = MIN(VSCROLL, info->height - info->y - LCD_HEIGHT); 521 move = MIN(VSCROLL, info->height - info->y - LCD_HEIGHT);
@@ -526,7 +533,7 @@ static void pan_view_down(struct image_info *info)
526 */ 533 */
527 move++, info->y--; 534 move++, info->y--;
528 rb->memcpy(rgb_linebuf, 535 rb->memcpy(rgb_linebuf,
529 *rb->lcd_framebuffer + (LCD_HEIGHT - move)*LCD_WIDTH, 536 lcd_fb + (LCD_HEIGHT - move)*LCD_WIDTH,
530 LCD_WIDTH*sizeof (fb_data)); 537 LCD_WIDTH*sizeof (fb_data));
531 } 538 }
532#endif 539#endif
@@ -539,7 +546,7 @@ static void pan_view_down(struct image_info *info)
539 && settings.jpeg_dither_mode == DITHER_DIFFUSION) 546 && settings.jpeg_dither_mode == DITHER_DIFFUSION)
540 { 547 {
541 /* Cover the first row drawn with previous image data. */ 548 /* Cover the first row drawn with previous image data. */
542 rb->memcpy(*rb->lcd_framebuffer + (LCD_HEIGHT - move)*LCD_WIDTH, 549 rb->memcpy(lcd_fb + (LCD_HEIGHT - move)*LCD_WIDTH,
543 rgb_linebuf, LCD_WIDTH*sizeof (fb_data)); 550 rgb_linebuf, LCD_WIDTH*sizeof (fb_data));
544 info->y++; 551 info->y++;
545 } 552 }
diff --git a/apps/plugins/imageviewer/jpeg/yuv2rgb.c b/apps/plugins/imageviewer/jpeg/yuv2rgb.c
index 5504e425e6..d0d5cb683b 100644
--- a/apps/plugins/imageviewer/jpeg/yuv2rgb.c
+++ b/apps/plugins/imageviewer/jpeg/yuv2rgb.c
@@ -236,15 +236,15 @@ static fb_data (* const pixel_funcs[COLOUR_NUM_MODES][DITHER_NUM_MODES])(void) =
236 [DITHER_DIFFUSION] = pixel_fsdither_to_lcd, 236 [DITHER_DIFFUSION] = pixel_fsdither_to_lcd,
237 }, 237 },
238}; 238};
239 239static fb_data *lcd_fb = NULL;
240/* These defines are used fornormal horizontal strides and vertical strides. */ 240/* These defines are used fornormal horizontal strides and vertical strides. */
241#if defined(LCD_STRIDEFORMAT) && LCD_STRIDEFORMAT == VERTICAL_STRIDE 241#if defined(LCD_STRIDEFORMAT) && LCD_STRIDEFORMAT == VERTICAL_STRIDE
242#define LCDADDR(x, y) (*rb->lcd_framebuffer + LCD_HEIGHT*(x) + (y)) 242#define LCDADDR(x, y) (lcd_fb + LCD_HEIGHT*(x) + (y))
243#define ROWENDOFFSET (width*LCD_HEIGHT) 243#define ROWENDOFFSET (width*LCD_HEIGHT)
244#define ROWOFFSET (1) 244#define ROWOFFSET (1)
245#define COLOFFSET (LCD_HEIGHT) 245#define COLOFFSET (LCD_HEIGHT)
246#else 246#else
247#define LCDADDR(x, y) (*rb->lcd_framebuffer + LCD_WIDTH*(y) + (x)) 247#define LCDADDR(x, y) (lcd_fb + LCD_WIDTH*(y) + (x))
248#define ROWENDOFFSET (width) 248#define ROWENDOFFSET (width)
249#define ROWOFFSET (LCD_WIDTH) 249#define ROWOFFSET (LCD_WIDTH)
250#define COLOFFSET (1) 250#define COLOFFSET (1)
@@ -261,6 +261,12 @@ void yuv_bitmap_part(unsigned char *src[3], int csub_x, int csub_y,
261 int x, int y, int width, int height, 261 int x, int y, int width, int height,
262 int colour_mode, int dither_mode) 262 int colour_mode, int dither_mode)
263{ 263{
264 if (!lcd_fb)
265 {
266 struct viewport *vp_main = *(rb->screens[SCREEN_MAIN]->current_viewport);
267 lcd_fb = vp_main->buffer->fb_ptr;
268 }
269
264 fb_data *dst, *dst_end; 270 fb_data *dst, *dst_end;
265 fb_data (*pixel_func)(void); 271 fb_data (*pixel_func)(void);
266 struct rgb_pixel px; 272 struct rgb_pixel px;
diff --git a/apps/plugins/invadrox.c b/apps/plugins/invadrox.c
index 0b26581b30..1c39a01c87 100644
--- a/apps/plugins/invadrox.c
+++ b/apps/plugins/invadrox.c
@@ -768,7 +768,7 @@ int curr_alien, aliens_paralyzed, gamespeed;
768int ufo_state, ufo_x; 768int ufo_state, ufo_x;
769bool level_finished; 769bool level_finished;
770bool aliens_down, aliens_right, hit_left_border, hit_right_border; 770bool aliens_down, aliens_right, hit_left_border, hit_right_border;
771 771static fb_data *lcd_fb;
772 772
773/* No standard get_pixel function yet, use this hack instead */ 773/* No standard get_pixel function yet, use this hack instead */
774#if (LCD_DEPTH >= 8) 774#if (LCD_DEPTH >= 8)
@@ -776,12 +776,12 @@ bool aliens_down, aliens_right, hit_left_border, hit_right_border;
776#if defined(LCD_STRIDEFORMAT) && LCD_STRIDEFORMAT == VERTICAL_STRIDE 776#if defined(LCD_STRIDEFORMAT) && LCD_STRIDEFORMAT == VERTICAL_STRIDE
777static inline fb_data get_pixel(int x, int y) 777static inline fb_data get_pixel(int x, int y)
778{ 778{
779 return *rb->lcd_framebuffer[x*LCD_HEIGHT+y]; 779 return lcd_fb[x*LCD_HEIGHT+y];
780} 780}
781#else 781#else
782static inline fb_data get_pixel(int x, int y) 782static inline fb_data get_pixel(int x, int y)
783{ 783{
784 return *rb->lcd_framebuffer[ytab[y] + x]; 784 return lcd_fb[ytab[y] + x];
785} 785}
786#endif 786#endif
787 787
@@ -794,7 +794,7 @@ static const unsigned char shifts[4] = {
794/* Horizontal packing */ 794/* Horizontal packing */
795static inline fb_data get_pixel(int x, int y) 795static inline fb_data get_pixel(int x, int y)
796{ 796{
797 return (*rb->lcd_framebuffer[ytab[y] + (x >> 2)] >> shifts[x & 3]) & 3; 797 return (lcd_fb[ytab[y] + (x >> 2)] >> shifts[x & 3]) & 3;
798} 798}
799#else 799#else
800/* Vertical packing */ 800/* Vertical packing */
@@ -803,7 +803,7 @@ static const unsigned char shifts[4] = {
803}; 803};
804static inline fb_data get_pixel(int x, int y) 804static inline fb_data get_pixel(int x, int y)
805{ 805{
806 return (*rb->lcd_framebuffer[ytab[y] + x] >> shifts[y & 3]) & 3; 806 return (lcd_fb[ytab[y] + x] >> shifts[y & 3]) & 3;
807} 807}
808#endif /* Horizontal/Vertical packing */ 808#endif /* Horizontal/Vertical packing */
809 809
@@ -1902,6 +1902,8 @@ enum plugin_status plugin_start(UNUSED const void* parameter)
1902#ifdef HAVE_BACKLIGHT 1902#ifdef HAVE_BACKLIGHT
1903 backlight_ignore_timeout(); 1903 backlight_ignore_timeout();
1904#endif 1904#endif
1905 struct viewport *vp_main = rb->lcd_set_viewport(NULL);
1906 lcd_fb = vp_main->buffer->fb_ptr;
1905 /* now go ahead and have fun! */ 1907 /* now go ahead and have fun! */
1906 game_loop(); 1908 game_loop();
1907 1909
diff --git a/apps/plugins/lib/grey.h b/apps/plugins/lib/grey.h
index 0e064f46b2..5cafc6a83e 100644
--- a/apps/plugins/lib/grey.h
+++ b/apps/plugins/lib/grey.h
@@ -62,7 +62,7 @@ void grey_deferred_lcd_update(void);
62 62
63/* Viewports and framebuffers */ 63/* Viewports and framebuffers */
64void grey_clear_viewport(void); 64void grey_clear_viewport(void);
65void grey_set_viewport(struct viewport *vp); 65struct viewport *grey_set_viewport(struct viewport *vp);
66void grey_viewport_set_fullscreen(struct viewport *vp, 66void grey_viewport_set_fullscreen(struct viewport *vp,
67 const enum screen_type screen); 67 const enum screen_type screen);
68void grey_viewport_set_pos(struct viewport *vp, 68void grey_viewport_set_pos(struct viewport *vp,
diff --git a/apps/plugins/lib/grey_core.c b/apps/plugins/lib/grey_core.c
index 9686f1d021..e3543aeba2 100644
--- a/apps/plugins/lib/grey_core.c
+++ b/apps/plugins/lib/grey_core.c
@@ -765,6 +765,11 @@ static const unsigned char colorindex[4] = {128, 85, 43, 0};
765 content (b&w and greyscale overlay) to an 8-bit BMP file. */ 765 content (b&w and greyscale overlay) to an 8-bit BMP file. */
766static void grey_screendump_hook(int fd) 766static void grey_screendump_hook(int fd)
767{ 767{
768 fb_data *lcd_fb;
769 struct viewport *vp_main = rb->lcd_set_viewport(NULL);
770 rb->viewport_set_fullscreen(vp_main, SCREEN_MAIN);
771 lcd_fb = vp_main->buffer->fb_ptr;
772
768 int i; 773 int i;
769 int y, gx, gy; 774 int y, gx, gy;
770#if LCD_PIXELFORMAT == VERTICAL_PACKING 775#if LCD_PIXELFORMAT == VERTICAL_PACKING
@@ -845,7 +850,7 @@ static void grey_screendump_hook(int fd)
845 gsrc = _grey_info.values + _GREY_MULUQ(_grey_info.width, gy); 850 gsrc = _grey_info.values + _GREY_MULUQ(_grey_info.width, gy);
846 851
847#if LCD_DEPTH == 2 852#if LCD_DEPTH == 2
848 src = *rb->lcd_framebuffer + _GREY_MULUQ(LCD_FBWIDTH, y); 853 src = lcd_fb + _GREY_MULUQ(LCD_FBWIDTH, y);
849 854
850 do 855 do
851 { 856 {
@@ -876,7 +881,7 @@ static void grey_screendump_hook(int fd)
876 881
877#if LCD_DEPTH == 1 882#if LCD_DEPTH == 1
878 mask = BIT_N(y & 7); 883 mask = BIT_N(y & 7);
879 src = *rb->lcd_framebuffer + _GREY_MULUQ(LCD_WIDTH, y >> 3); 884 src = lcd_fb + _GREY_MULUQ(LCD_WIDTH, y >> 3);
880 885
881 do 886 do
882 { 887 {
@@ -908,7 +913,7 @@ static void grey_screendump_hook(int fd)
908 913
909#elif LCD_DEPTH == 2 914#elif LCD_DEPTH == 2
910 shift = 2 * (y & 3); 915 shift = 2 * (y & 3);
911 src = *rb->lcd_framebuffer + _GREY_MULUQ(LCD_WIDTH, y >> 2); 916 src = lcd_fb + _GREY_MULUQ(LCD_WIDTH, y >> 2);
912 917
913 do 918 do
914 { 919 {
@@ -933,7 +938,7 @@ static void grey_screendump_hook(int fd)
933 938
934#if LCD_DEPTH == 2 939#if LCD_DEPTH == 2
935 shift = y & 7; 940 shift = y & 7;
936 src = *rb->lcd_framebuffer + _GREY_MULUQ(LCD_WIDTH, y >> 3); 941 src = lcd_fb + _GREY_MULUQ(LCD_WIDTH, y >> 3);
937 942
938 do 943 do
939 { 944 {
diff --git a/apps/plugins/lib/grey_parm.c b/apps/plugins/lib/grey_parm.c
index d2dfde42f1..700b6f0026 100644
--- a/apps/plugins/lib/grey_parm.c
+++ b/apps/plugins/lib/grey_parm.c
@@ -154,8 +154,9 @@ static void grey_update_clip_rect(void)
154} 154}
155 155
156/* Set current grey viewport for draw routines */ 156/* Set current grey viewport for draw routines */
157void grey_set_viewport(struct viewport *vp) 157struct viewport *grey_set_viewport(struct viewport *vp)
158{ 158{
159 struct viewport *last_vp = _grey_info.vp;
159 if (vp == NULL) 160 if (vp == NULL)
160 vp = &_grey_default_vp; 161 vp = &_grey_default_vp;
161 162
@@ -164,6 +165,7 @@ void grey_set_viewport(struct viewport *vp)
164 _grey_info.vp = vp; 165 _grey_info.vp = vp;
165 grey_update_clip_rect(); 166 grey_update_clip_rect();
166 } 167 }
168 return last_vp;
167} 169}
168 170
169/* Set viewport to default settings */ 171/* Set viewport to default settings */
diff --git a/apps/plugins/lib/osd.c b/apps/plugins/lib/osd.c
index 97db09cc1e..7d6e10a410 100644
--- a/apps/plugins/lib/osd.c
+++ b/apps/plugins/lib/osd.c
@@ -52,6 +52,7 @@ struct osd
52 OSD_ERASED, /* Erased in preparation for regular drawing */ 52 OSD_ERASED, /* Erased in preparation for regular drawing */
53 } status; /* View status */ 53 } status; /* View status */
54 struct viewport vp; /* Clipping viewport */ 54 struct viewport vp; /* Clipping viewport */
55 struct frame_buffer_t framebuf; /* Holds framebuffer reference */
55 int lcd_bitmap_stride; /* Stride of LCD bitmap */ 56 int lcd_bitmap_stride; /* Stride of LCD bitmap */
56 void *lcd_bitmap_data; /* Backbuffer framebuffer data */ 57 void *lcd_bitmap_data; /* Backbuffer framebuffer data */
57 int back_bitmap_stride; /* Stride of backbuffer bitmap */ 58 int back_bitmap_stride; /* Stride of backbuffer bitmap */
@@ -68,7 +69,7 @@ struct osd
68 int height); 69 int height);
69 void (*lcd_update)(void); 70 void (*lcd_update)(void);
70 void (*lcd_update_rect)(int x, int y, int width, int height); 71 void (*lcd_update_rect)(int x, int y, int width, int height);
71 void (*lcd_set_viewport)(struct viewport *vp); 72 struct viewport *(*lcd_set_viewport)(struct viewport *vp);
72 void (*lcd_set_framebuffer)(void *buf); 73 void (*lcd_set_framebuffer)(void *buf);
73 void (*lcd_framebuffer_set_pos)(int x, int y, int width, int height); 74 void (*lcd_framebuffer_set_pos)(int x, int y, int width, int height);
74 void (*lcd_bitmap_part)(const void *src, int src_x, int src_y, 75 void (*lcd_bitmap_part)(const void *src, int src_x, int src_y,
@@ -227,7 +228,8 @@ static void * _osd_lcd_init_buffers(struct osd *osd, unsigned flags,
227 osd->back_bitmap_stride = w; 228 osd->back_bitmap_stride = w;
228#endif /* end stride type selection */ 229#endif /* end stride type selection */
229 230
230 osd->lcd_bitmap_data = (void *)*rb->lcd_framebuffer; 231 /* vp is currently initialized to the default framebuffer */
232 osd->lcd_bitmap_data = osd->vp.buffer->data;
231 osd->back_bitmap_data = buf; 233 osd->back_bitmap_data = buf;
232 234
233 osd->maxwidth = w; 235 osd->maxwidth = w;
@@ -686,6 +688,25 @@ static void _osd_lcd_update_rect(struct osd *osd,
686 osd->lcd_update_rect(x, y, width, height); 688 osd->lcd_update_rect(x, y, width, height);
687} 689}
688 690
691static void _osd_lcd_viewport_set_buffer(void *buffer)
692{
693 if (buffer)
694 {
695 native_osd.framebuf.data = buffer;
696 native_osd.framebuf.elems = native_osd.maxheight * native_osd.maxwidth;
697 native_osd.framebuf.get_address_fn = NULL; /*Default iterator*/
698
699 if (buffer == native_osd.back_bitmap_data)
700 native_osd.framebuf.stride = (native_osd.back_bitmap_stride);
701 else
702 native_osd.framebuf.stride = (native_osd.lcd_bitmap_stride);
703
704 rb->viewport_set_buffer(NULL, &native_osd.framebuf, SCREEN_MAIN);
705 }
706 else
707 rb->viewport_set_buffer(NULL, NULL, SCREEN_MAIN);
708}
709
689/* Native LCD, public */ 710/* Native LCD, public */
690bool osd_init(unsigned flags, void *backbuf, size_t backbuf_size, 711bool osd_init(unsigned flags, void *backbuf, size_t backbuf_size,
691 osd_draw_cb_fn_t draw_cb, int *width, int *height, 712 osd_draw_cb_fn_t draw_cb, int *width, int *height,
@@ -696,7 +717,7 @@ bool osd_init(unsigned flags, void *backbuf, size_t backbuf_size,
696 native_osd.lcd_update = rb->lcd_update; 717 native_osd.lcd_update = rb->lcd_update;
697 native_osd.lcd_update_rect = rb->lcd_update_rect; 718 native_osd.lcd_update_rect = rb->lcd_update_rect;
698 native_osd.lcd_set_viewport = rb->lcd_set_viewport; 719 native_osd.lcd_set_viewport = rb->lcd_set_viewport;
699 native_osd.lcd_set_framebuffer = (void *)rb->lcd_set_framebuffer; 720 native_osd.lcd_set_framebuffer = (void *)_osd_lcd_viewport_set_buffer;
700#if LCD_DEPTH < 4 721#if LCD_DEPTH < 4
701 native_osd.lcd_framebuffer_set_pos = NULL; 722 native_osd.lcd_framebuffer_set_pos = NULL;
702#endif /* LCD_DEPTH < 4 */ 723#endif /* LCD_DEPTH < 4 */
diff --git a/apps/plugins/lib/xlcd.h b/apps/plugins/lib/xlcd.h
index 963c7c4831..069cc00508 100644
--- a/apps/plugins/lib/xlcd.h
+++ b/apps/plugins/lib/xlcd.h
@@ -34,6 +34,8 @@ void xlcd_fillcircle_screen(struct screen* display, int cx, int cy, int radius);
34void xlcd_drawcircle(int cx, int cy, int radius); 34void xlcd_drawcircle(int cx, int cy, int radius);
35void xlcd_drawcircle_screen(struct screen* display, int cx, int cy, int radius); 35void xlcd_drawcircle_screen(struct screen* display, int cx, int cy, int radius);
36 36
37fb_data* get_framebuffer(struct viewport *vp, size_t *stride); /*CORE*/
38
37#if LCD_DEPTH >= 8 39#if LCD_DEPTH >= 8
38void xlcd_gray_bitmap_part(const unsigned char *src, int src_x, int src_y, 40void xlcd_gray_bitmap_part(const unsigned char *src, int src_x, int src_y,
39 int stride, int x, int y, int width, int height); 41 int stride, int x, int y, int width, int height);
diff --git a/apps/plugins/lib/xlcd_core.c b/apps/plugins/lib/xlcd_core.c
index 47875a51a9..9a274cb48d 100644
--- a/apps/plugins/lib/xlcd_core.c
+++ b/apps/plugins/lib/xlcd_core.c
@@ -26,3 +26,12 @@
26 26
27#include "xlcd.h" 27#include "xlcd.h"
28 28
29fb_data* get_framebuffer(struct viewport *vp, size_t *stride)
30{
31 struct viewport *vp_main = *(rb->screens[SCREEN_MAIN]->current_viewport);
32 if (vp)
33 *vp = *vp_main;
34 if (stride)
35 *stride = vp_main->buffer->stride;
36 return vp_main->buffer->fb_ptr;
37}
diff --git a/apps/plugins/lib/xlcd_draw.c b/apps/plugins/lib/xlcd_draw.c
index b6ed403353..0bd1c7a9e2 100644
--- a/apps/plugins/lib/xlcd_draw.c
+++ b/apps/plugins/lib/xlcd_draw.c
@@ -349,6 +349,9 @@ static const fb_data graylut[256] = {
349void xlcd_gray_bitmap_part(const unsigned char *src, int src_x, int src_y, 349void xlcd_gray_bitmap_part(const unsigned char *src, int src_x, int src_y,
350 int stride, int x, int y, int width, int height) 350 int stride, int x, int y, int width, int height)
351{ 351{
352 size_t dst_stride;
353 fb_data *lcd_fb = get_framebuffer(NULL, &dst_stride);
354
352 const unsigned char *src_end; 355 const unsigned char *src_end;
353 fb_data *dst; 356 fb_data *dst;
354 357
@@ -377,7 +380,7 @@ void xlcd_gray_bitmap_part(const unsigned char *src, int src_x, int src_y,
377 380
378 src += stride * src_y + src_x; /* move starting point */ 381 src += stride * src_y + src_x; /* move starting point */
379 src_end = src + stride * height; 382 src_end = src + stride * height;
380 dst = *rb->lcd_framebuffer + LCD_WIDTH * y + x; 383 dst = lcd_fb + dst_stride * y + x;
381 384
382 do 385 do
383 { 386 {
@@ -398,7 +401,7 @@ void xlcd_gray_bitmap_part(const unsigned char *src, int src_x, int src_y,
398#endif 401#endif
399 402
400 src += stride; 403 src += stride;
401 dst += LCD_WIDTH; 404 dst += dst_stride;
402 } 405 }
403 while (src < src_end); 406 while (src < src_end);
404} 407}
@@ -416,6 +419,9 @@ void xlcd_gray_bitmap(const unsigned char *src, int x, int y, int width,
416void xlcd_color_bitmap_part(const unsigned char *src, int src_x, int src_y, 419void xlcd_color_bitmap_part(const unsigned char *src, int src_x, int src_y,
417 int stride, int x, int y, int width, int height) 420 int stride, int x, int y, int width, int height)
418{ 421{
422 size_t dst_stride;
423 fb_data *lcd_fb = get_framebuffer(NULL, &dst_stride);
424
419 const unsigned char *src_end; 425 const unsigned char *src_end;
420 fb_data *dst; 426 fb_data *dst;
421 427
@@ -444,7 +450,7 @@ void xlcd_color_bitmap_part(const unsigned char *src, int src_x, int src_y,
444 450
445 src += 3 * (stride * src_y + src_x); /* move starting point */ 451 src += 3 * (stride * src_y + src_x); /* move starting point */
446 src_end = src + 3 * stride * height; 452 src_end = src + 3 * stride * height;
447 dst = *rb->lcd_framebuffer + LCD_WIDTH * y + x; 453 dst = lcd_fb + dst_stride * y + x;
448 454
449 do 455 do
450 { 456 {
@@ -471,7 +477,7 @@ void xlcd_color_bitmap_part(const unsigned char *src, int src_x, int src_y,
471 while (src_row < row_end); 477 while (src_row < row_end);
472 478
473 src += 3 * stride; 479 src += 3 * stride;
474 dst += LCD_WIDTH; 480 dst += dst_stride;
475 } 481 }
476 while (src < src_end); 482 while (src < src_end);
477} 483}
diff --git a/apps/plugins/lib/xlcd_scroll.c b/apps/plugins/lib/xlcd_scroll.c
index ab9ee1c4cb..89427b6118 100644
--- a/apps/plugins/lib/xlcd_scroll.c
+++ b/apps/plugins/lib/xlcd_scroll.c
@@ -33,6 +33,11 @@ static const unsigned short patterns[4] = {0xFFFF, 0xFF00, 0x00FF, 0x0000};
33#if defined(LCD_STRIDEFORMAT) && LCD_STRIDEFORMAT == VERTICAL_STRIDE 33#if defined(LCD_STRIDEFORMAT) && LCD_STRIDEFORMAT == VERTICAL_STRIDE
34void xlcd_scroll_left(int count) 34void xlcd_scroll_left(int count)
35{ 35{
36 /*size_t dst_stride;*/
37 /*struct viewport *vp_main = NULL;*/
38 fb_data *lcd_fb = get_framebuffer(NULL, NULL);
39
40
36 int length, oldmode; 41 int length, oldmode;
37 42
38 if ((unsigned)count >= LCD_WIDTH) 43 if ((unsigned)count >= LCD_WIDTH)
@@ -43,8 +48,7 @@ void xlcd_scroll_left(int count)
43 48
44 length = (LCD_WIDTH-count)*LCD_FBHEIGHT; 49 length = (LCD_WIDTH-count)*LCD_FBHEIGHT;
45 50
46 rb->memmove(*rb->lcd_framebuffer, *rb->lcd_framebuffer + LCD_HEIGHT*count, 51 rb->memmove(lcd_fb, lcd_fb + LCD_HEIGHT*count, length * sizeof(fb_data));
47 length * sizeof(fb_data));
48 52
49 oldmode = rb->lcd_get_drawmode(); 53 oldmode = rb->lcd_get_drawmode();
50 rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); 54 rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
@@ -55,6 +59,11 @@ void xlcd_scroll_left(int count)
55/* Scroll right */ 59/* Scroll right */
56void xlcd_scroll_right(int count) 60void xlcd_scroll_right(int count)
57{ 61{
62 /*size_t dst_stride;*/
63 /*struct viewport *vp_main = NULL;*/
64 fb_data *lcd_fb = get_framebuffer(NULL, NULL);
65
66
58 int length, oldmode; 67 int length, oldmode;
59 68
60 if ((unsigned)count >= LCD_WIDTH) 69 if ((unsigned)count >= LCD_WIDTH)
@@ -65,8 +74,8 @@ void xlcd_scroll_right(int count)
65 74
66 length = (LCD_WIDTH-count)*LCD_FBHEIGHT; 75 length = (LCD_WIDTH-count)*LCD_FBHEIGHT;
67 76
68 rb->memmove(*rb->lcd_framebuffer + LCD_HEIGHT*count, 77 rb->memmove(lcd_fb + LCD_HEIGHT*count,
69 *rb->lcd_framebuffer, length * sizeof(fb_data)); 78 lcd_fb, length * sizeof(fb_data));
70 79
71 oldmode = rb->lcd_get_drawmode(); 80 oldmode = rb->lcd_get_drawmode();
72 rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); 81 rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
@@ -77,6 +86,11 @@ void xlcd_scroll_right(int count)
77/* Scroll up */ 86/* Scroll up */
78void xlcd_scroll_up(int count) 87void xlcd_scroll_up(int count)
79{ 88{
89 /*size_t dst_stride;*/
90 /*struct viewport *vp_main = NULL;*/
91 fb_data *lcd_fb = get_framebuffer(NULL, NULL);
92
93
80 int width, length, oldmode; 94 int width, length, oldmode;
81 95
82 fb_data *data; 96 fb_data *data;
@@ -90,7 +104,7 @@ void xlcd_scroll_up(int count)
90 length = LCD_HEIGHT - count; 104 length = LCD_HEIGHT - count;
91 105
92 width = LCD_WIDTH-1; 106 width = LCD_WIDTH-1;
93 data = *rb->lcd_framebuffer; 107 data = lcd_fb;
94 108
95 do { 109 do {
96 rb->memmove(data,data + count,length * sizeof(fb_data)); 110 rb->memmove(data,data + count,length * sizeof(fb_data));
@@ -106,6 +120,11 @@ void xlcd_scroll_up(int count)
106/* Scroll down */ 120/* Scroll down */
107void xlcd_scroll_down(int count) 121void xlcd_scroll_down(int count)
108{ 122{
123 /*size_t dst_stride;*/
124 /*struct viewport *vp_main = NULL;*/
125 fb_data *lcd_fb = get_framebuffer(NULL, NULL);
126
127
109 int width, length, oldmode; 128 int width, length, oldmode;
110 129
111 fb_data *data; 130 fb_data *data;
@@ -119,7 +138,7 @@ void xlcd_scroll_down(int count)
119 length = LCD_HEIGHT - count; 138 length = LCD_HEIGHT - count;
120 139
121 width = LCD_WIDTH-1; 140 width = LCD_WIDTH-1;
122 data = *rb->lcd_framebuffer; 141 data = lcd_fb;
123 142
124 do { 143 do {
125 rb->memmove(data + count, data, length * sizeof(fb_data)); 144 rb->memmove(data + count, data, length * sizeof(fb_data));
@@ -138,6 +157,11 @@ void xlcd_scroll_down(int count)
138/* Scroll left */ 157/* Scroll left */
139void xlcd_scroll_left(int count) 158void xlcd_scroll_left(int count)
140{ 159{
160 /*size_t dst_stride;*/
161 /*struct viewport *vp_main = NULL;*/
162 fb_data *lcd_fb = get_framebuffer(NULL, NULL);
163
164
141 int bitcount=0, oldmode; 165 int bitcount=0, oldmode;
142 int blockcount=0, blocklen; 166 int blockcount=0, blocklen;
143 167
@@ -155,7 +179,7 @@ void xlcd_scroll_left(int count)
155 179
156 if (blockcount) 180 if (blockcount)
157 { 181 {
158 unsigned char *data = *rb->lcd_framebuffer; 182 unsigned char *data = lcd_fb;
159 unsigned char *data_end = data + LCD_FBWIDTH*LCD_HEIGHT; 183 unsigned char *data_end = data + LCD_FBWIDTH*LCD_HEIGHT;
160 184
161 do 185 do
@@ -168,7 +192,7 @@ void xlcd_scroll_left(int count)
168 if (bitcount) 192 if (bitcount)
169 { 193 {
170 int bx, y; 194 int bx, y;
171 unsigned char *addr = *rb->lcd_framebuffer + blocklen; 195 unsigned char *addr = lcd_fb + blocklen;
172#if LCD_DEPTH == 2 196#if LCD_DEPTH == 2
173 unsigned fill = (0x55 * (~rb->lcd_get_background() & 3)) << bitcount; 197 unsigned fill = (0x55 * (~rb->lcd_get_background() & 3)) << bitcount;
174#endif 198#endif
@@ -196,6 +220,11 @@ void xlcd_scroll_left(int count)
196/* Scroll right */ 220/* Scroll right */
197void xlcd_scroll_right(int count) 221void xlcd_scroll_right(int count)
198{ 222{
223 /*size_t dst_stride;*/
224 /*struct viewport *vp_main = NULL;*/
225 fb_data *lcd_fb = get_framebuffer(NULL, NULL);
226
227
199 int bitcount=0, oldmode; 228 int bitcount=0, oldmode;
200 int blockcount=0, blocklen; 229 int blockcount=0, blocklen;
201 230
@@ -213,7 +242,7 @@ void xlcd_scroll_right(int count)
213 242
214 if (blockcount) 243 if (blockcount)
215 { 244 {
216 unsigned char *data = *rb->lcd_framebuffer; 245 unsigned char *data = lcd_fb;
217 unsigned char *data_end = data + LCD_FBWIDTH*LCD_HEIGHT; 246 unsigned char *data_end = data + LCD_FBWIDTH*LCD_HEIGHT;
218 247
219 do 248 do
@@ -226,7 +255,7 @@ void xlcd_scroll_right(int count)
226 if (bitcount) 255 if (bitcount)
227 { 256 {
228 int bx, y; 257 int bx, y;
229 unsigned char *addr = *rb->lcd_framebuffer + blockcount; 258 unsigned char *addr = lcd_fb + blockcount;
230#if LCD_DEPTH == 2 259#if LCD_DEPTH == 2
231 unsigned fill = 0x55 * (~rb->lcd_get_background() & 3); 260 unsigned fill = 0x55 * (~rb->lcd_get_background() & 3);
232#endif 261#endif
@@ -256,6 +285,11 @@ void xlcd_scroll_right(int count)
256/* Scroll left */ 285/* Scroll left */
257void xlcd_scroll_left(int count) 286void xlcd_scroll_left(int count)
258{ 287{
288 /*size_t dst_stride;*/
289 /*struct viewport *vp_main = NULL;*/
290 fb_data *lcd_fb = get_framebuffer(NULL, NULL);
291
292
259 fb_data *data, *data_end; 293 fb_data *data, *data_end;
260 int length, oldmode; 294 int length, oldmode;
261 295
@@ -265,7 +299,7 @@ void xlcd_scroll_left(int count)
265 return; 299 return;
266 } 300 }
267 301
268 data = *rb->lcd_framebuffer; 302 data = lcd_fb;
269 data_end = data + LCD_WIDTH*LCD_FBHEIGHT; 303 data_end = data + LCD_WIDTH*LCD_FBHEIGHT;
270 length = LCD_WIDTH - count; 304 length = LCD_WIDTH - count;
271 305
@@ -285,6 +319,11 @@ void xlcd_scroll_left(int count)
285/* Scroll right */ 319/* Scroll right */
286void xlcd_scroll_right(int count) 320void xlcd_scroll_right(int count)
287{ 321{
322 /*size_t dst_stride;*/
323 /*struct viewport *vp_main = NULL;*/
324 fb_data *lcd_fb = get_framebuffer(NULL, NULL);
325
326
288 fb_data *data, *data_end; 327 fb_data *data, *data_end;
289 int length, oldmode; 328 int length, oldmode;
290 329
@@ -294,7 +333,7 @@ void xlcd_scroll_right(int count)
294 return; 333 return;
295 } 334 }
296 335
297 data = *rb->lcd_framebuffer; 336 data = lcd_fb;
298 data_end = data + LCD_WIDTH*LCD_FBHEIGHT; 337 data_end = data + LCD_WIDTH*LCD_FBHEIGHT;
299 length = LCD_WIDTH - count; 338 length = LCD_WIDTH - count;
300 339
@@ -318,6 +357,10 @@ void xlcd_scroll_right(int count)
318/* Scroll up */ 357/* Scroll up */
319void xlcd_scroll_up(int count) 358void xlcd_scroll_up(int count)
320{ 359{
360 /*size_t dst_stride;*/
361 /*struct viewport *vp_main = NULL;*/
362 fb_data *lcd_fb = get_framebuffer(NULL, NULL);
363
321 int length, oldmode; 364 int length, oldmode;
322 365
323 if ((unsigned)count >= LCD_HEIGHT) 366 if ((unsigned)count >= LCD_HEIGHT)
@@ -328,8 +371,8 @@ void xlcd_scroll_up(int count)
328 371
329 length = LCD_HEIGHT - count; 372 length = LCD_HEIGHT - count;
330 373
331 rb->memmove(*rb->lcd_framebuffer, 374 rb->memmove(lcd_fb,
332 *rb->lcd_framebuffer + count * LCD_FBWIDTH, 375 lcd_fb + count * LCD_FBWIDTH,
333 length * LCD_FBWIDTH * sizeof(fb_data)); 376 length * LCD_FBWIDTH * sizeof(fb_data));
334 377
335 oldmode = rb->lcd_get_drawmode(); 378 oldmode = rb->lcd_get_drawmode();
@@ -341,6 +384,10 @@ void xlcd_scroll_up(int count)
341/* Scroll down */ 384/* Scroll down */
342void xlcd_scroll_down(int count) 385void xlcd_scroll_down(int count)
343{ 386{
387 /*size_t dst_stride;*/
388 /*struct viewport *vp_main = NULL;*/
389 fb_data *lcd_fb = get_framebuffer(NULL, NULL);
390
344 int length, oldmode; 391 int length, oldmode;
345 392
346 if ((unsigned)count >= LCD_HEIGHT) 393 if ((unsigned)count >= LCD_HEIGHT)
@@ -351,8 +398,8 @@ void xlcd_scroll_down(int count)
351 398
352 length = LCD_HEIGHT - count; 399 length = LCD_HEIGHT - count;
353 400
354 rb->memmove(*rb->lcd_framebuffer + count * LCD_FBWIDTH, 401 rb->memmove(lcd_fb + count * LCD_FBWIDTH,
355 *rb->lcd_framebuffer, 402 lcd_fb,
356 length * LCD_FBWIDTH * sizeof(fb_data)); 403 length * LCD_FBWIDTH * sizeof(fb_data));
357 404
358 oldmode = rb->lcd_get_drawmode(); 405 oldmode = rb->lcd_get_drawmode();
@@ -367,6 +414,10 @@ void xlcd_scroll_down(int count)
367/* Scroll up */ 414/* Scroll up */
368void xlcd_scroll_up(int count) 415void xlcd_scroll_up(int count)
369{ 416{
417 /*size_t dst_stride;*/
418 /*struct viewport *vp_main = NULL;*/
419 fb_data *lcd_fb = get_framebuffer(NULL, NULL);
420
370 int bitcount=0, oldmode; 421 int bitcount=0, oldmode;
371 int blockcount=0, blocklen; 422 int blockcount=0, blocklen;
372 423
@@ -388,8 +439,8 @@ void xlcd_scroll_up(int count)
388 439
389 if (blockcount) 440 if (blockcount)
390 { 441 {
391 rb->memmove(*rb->lcd_framebuffer, 442 rb->memmove(lcd_fb,
392 *rb->lcd_framebuffer + blockcount * LCD_FBWIDTH, 443 lcd_fb + blockcount * LCD_FBWIDTH,
393 blocklen * LCD_FBWIDTH * sizeof(fb_data)); 444 blocklen * LCD_FBWIDTH * sizeof(fb_data));
394 } 445 }
395 if (bitcount) 446 if (bitcount)
@@ -424,7 +475,7 @@ void xlcd_scroll_up(int count)
424 : /* inputs */ 475 : /* inputs */
425 [wide]"r"(LCD_FBWIDTH), 476 [wide]"r"(LCD_FBWIDTH),
426 [rows]"r"(blocklen), 477 [rows]"r"(blocklen),
427 [addr]"a"(*rb->lcd_framebuffer + blocklen * LCD_FBWIDTH), 478 [addr]"a"(lcd_fb + blocklen * LCD_FBWIDTH),
428 [cnt] "d"(bitcount), 479 [cnt] "d"(bitcount),
429 [bkg] "d"(0x55 * (~rb->lcd_get_background() & 3)) 480 [bkg] "d"(0x55 * (~rb->lcd_get_background() & 3))
430 : /* clobbers */ 481 : /* clobbers */
@@ -432,7 +483,7 @@ void xlcd_scroll_up(int count)
432 ); 483 );
433#else /* C version */ 484#else /* C version */
434 int x, by; 485 int x, by;
435 unsigned char *addr = *rb->lcd_framebuffer + blocklen * LCD_FBWIDTH; 486 unsigned char *addr = lcd_fb + blocklen * LCD_FBWIDTH;
436#if LCD_DEPTH == 2 487#if LCD_DEPTH == 2
437 unsigned fill = 0x55 * (~rb->lcd_get_background() & 3); 488 unsigned fill = 0x55 * (~rb->lcd_get_background() & 3);
438#else 489#else
@@ -457,7 +508,7 @@ void xlcd_scroll_up(int count)
457 508
458#if LCD_DEPTH == 2 509#if LCD_DEPTH == 2
459 int x, by; 510 int x, by;
460 fb_data *addr = *rb->lcd_framebuffer + blocklen * LCD_FBWIDTH; 511 fb_data *addr = lcd_fb + blocklen * LCD_FBWIDTH;
461 unsigned fill, mask; 512 unsigned fill, mask;
462 513
463 fill = patterns[rb->lcd_get_background() & 3] << 8; 514 fill = patterns[rb->lcd_get_background() & 3] << 8;
@@ -491,6 +542,10 @@ void xlcd_scroll_up(int count)
491/* Scroll up */ 542/* Scroll up */
492void xlcd_scroll_down(int count) 543void xlcd_scroll_down(int count)
493{ 544{
545 /*size_t dst_stride;*/
546 /*struct viewport *vp_main = NULL;*/
547 fb_data *lcd_fb = get_framebuffer(NULL, NULL);
548
494 int bitcount=0, oldmode; 549 int bitcount=0, oldmode;
495 int blockcount=0, blocklen; 550 int blockcount=0, blocklen;
496 551
@@ -512,8 +567,8 @@ void xlcd_scroll_down(int count)
512 567
513 if (blockcount) 568 if (blockcount)
514 { 569 {
515 rb->memmove(*rb->lcd_framebuffer + blockcount * LCD_FBWIDTH, 570 rb->memmove(lcd_fb + blockcount * LCD_FBWIDTH,
516 *rb->lcd_framebuffer, 571 lcd_fb,
517 blocklen * LCD_FBWIDTH * sizeof(fb_data)); 572 blocklen * LCD_FBWIDTH * sizeof(fb_data));
518 } 573 }
519 if (bitcount) 574 if (bitcount)
@@ -548,7 +603,7 @@ void xlcd_scroll_down(int count)
548 : /* inputs */ 603 : /* inputs */
549 [wide]"r"(LCD_WIDTH), 604 [wide]"r"(LCD_WIDTH),
550 [rows]"r"(blocklen), 605 [rows]"r"(blocklen),
551 [addr]"a"(*rb->lcd_framebuffer + blockcount * LCD_FBWIDTH), 606 [addr]"a"(lcd_fb + blockcount * LCD_FBWIDTH),
552 [cnt] "d"(bitcount), 607 [cnt] "d"(bitcount),
553 [bkg] "d"((0x55 * (~rb->lcd_get_background() & 3)) << bitcount) 608 [bkg] "d"((0x55 * (~rb->lcd_get_background() & 3)) << bitcount)
554 : /* clobbers */ 609 : /* clobbers */
@@ -556,7 +611,7 @@ void xlcd_scroll_down(int count)
556 ); 611 );
557#else /* C version */ 612#else /* C version */
558 int x, by; 613 int x, by;
559 unsigned char *addr = *rb->lcd_framebuffer + blockcount * LCD_FBWIDTH; 614 unsigned char *addr = lcd_fb + blockcount * LCD_FBWIDTH;
560#if LCD_DEPTH == 2 615#if LCD_DEPTH == 2
561 unsigned fill = (0x55 * (~rb->lcd_get_background() & 3)) << bitcount; 616 unsigned fill = (0x55 * (~rb->lcd_get_background() & 3)) << bitcount;
562#else 617#else
@@ -581,7 +636,7 @@ void xlcd_scroll_down(int count)
581 636
582#if LCD_DEPTH == 2 637#if LCD_DEPTH == 2
583 int x, by; 638 int x, by;
584 fb_data *addr = *rb->lcd_framebuffer + blockcount * LCD_FBWIDTH; 639 fb_data *addr = lcd_fb + blockcount * LCD_FBWIDTH;
585 unsigned fill, mask; 640 unsigned fill, mask;
586 641
587 fill = patterns[rb->lcd_get_background() & 3] >> (8 - bitcount); 642 fill = patterns[rb->lcd_get_background() & 3] >> (8 - bitcount);
diff --git a/apps/plugins/lua/rocklib_img.c b/apps/plugins/lua/rocklib_img.c
index da3ef4b52c..887ef984d0 100644
--- a/apps/plugins/lua/rocklib_img.c
+++ b/apps/plugins/lua/rocklib_img.c
@@ -1242,6 +1242,7 @@ static int get_screen(lua_State *L, int narg)
1242 return screen; 1242 return screen;
1243} 1243}
1244#else /* only SCREEN_MAIN exists */ 1244#else /* only SCREEN_MAIN exists */
1245#define get_screen(a,b) (SCREEN_MAIN)
1245#define RB_SCREEN_STRUCT(luastate, narg) \ 1246#define RB_SCREEN_STRUCT(luastate, narg) \
1246 rb->screens[SCREEN_MAIN] 1247 rb->screens[SCREEN_MAIN]
1247#define RB_SCREENS(luastate, narg, func, ...) \ 1248#define RB_SCREENS(luastate, narg, func, ...) \
@@ -1379,7 +1380,12 @@ RB_WRAP(font_getstringsize)
1379 1380
1380RB_WRAP(lcd_framebuffer) 1381RB_WRAP(lcd_framebuffer)
1381{ 1382{
1382 rli_wrap(L, *rb->lcd_framebuffer, LCD_WIDTH, LCD_HEIGHT); 1383 int screen = get_screen(L, 1);
1384 static struct viewport vp;
1385 rb->viewport_set_fullscreen(&vp, screen);
1386 rli_wrap(L, vp.buffer->data,
1387 RB_SCREEN_STRUCT(L, 1)->lcdwidth,
1388 RB_SCREEN_STRUCT(L, 1)->lcdheight);
1383 return 1; 1389 return 1;
1384} 1390}
1385 1391
diff --git a/apps/plugins/mpegplayer/mpegplayer.c b/apps/plugins/mpegplayer/mpegplayer.c
index e72d2828e3..619be8f1ef 100644
--- a/apps/plugins/mpegplayer/mpegplayer.c
+++ b/apps/plugins/mpegplayer/mpegplayer.c
@@ -620,6 +620,14 @@ struct fps
620static struct osd osd; 620static struct osd osd;
621static struct fps fps NOCACHEBSS_ATTR; /* Accessed on other processor */ 621static struct fps fps NOCACHEBSS_ATTR; /* Accessed on other processor */
622 622
623#ifdef LCD_PORTRAIT
624static fb_data* get_framebuffer(void)
625{
626 struct viewport *vp_main = *(rb->screens[SCREEN_MAIN]->current_viewport);
627 return vp_main->buffer->fb_ptr;
628}
629#endif
630
623static void osd_show(unsigned show); 631static void osd_show(unsigned show);
624 632
625#ifdef LCD_LANDSCAPE 633#ifdef LCD_LANDSCAPE
@@ -821,7 +829,7 @@ static void draw_oriented_mono_bitmap_part(const unsigned char *src,
821 src_y &= 7; 829 src_y &= 7;
822 src_end = src + width; 830 src_end = src + width;
823 831
824 dst = *rb->lcd_framebuffer + (LCD_WIDTH - y) + x*LCD_WIDTH; 832 dst = get_framebuffer() + (LCD_WIDTH - y) + x*LCD_WIDTH;
825 do 833 do
826 { 834 {
827 const unsigned char *src_col = src++; 835 const unsigned char *src_col = src++;
@@ -953,7 +961,7 @@ static void draw_oriented_alpha_bitmap_part(const unsigned char *src,
953 fg_pattern = rb->lcd_get_foreground(); 961 fg_pattern = rb->lcd_get_foreground();
954 /*bg_pattern=*/ rb->lcd_get_background(); 962 /*bg_pattern=*/ rb->lcd_get_background();
955 963
956 dst_start = *rb->lcd_framebuffer + (LCD_WIDTH - y - 1) + x*LCD_WIDTH; 964 dst_start = get_framebuffer() + (LCD_WIDTH - y - 1) + x*LCD_WIDTH;
957 int col, row = height; 965 int col, row = height;
958 unsigned data, pixels; 966 unsigned data, pixels;
959 unsigned skip_end = (stride - width); 967 unsigned skip_end = (stride - width);
diff --git a/apps/plugins/oscilloscope.c b/apps/plugins/oscilloscope.c
index d8bef0ae7f..62c11b91c9 100644
--- a/apps/plugins/oscilloscope.c
+++ b/apps/plugins/oscilloscope.c
@@ -838,10 +838,10 @@ static void osc_osd_show_message(int id, int val)
838 int width, height; 838 int width, height;
839 int maxwidth, maxheight; 839 int maxwidth, maxheight;
840 840
841 rb->lcd_set_viewport(osd_get_viewport()); 841 struct viewport *last_vp = rb->lcd_set_viewport(osd_get_viewport());
842 osd_get_max_dims(&maxwidth, &maxheight); 842 osd_get_max_dims(&maxwidth, &maxheight);
843 rb->lcd_getstringsize(osc_osd_message, &width, &height); 843 rb->lcd_getstringsize(osc_osd_message, &width, &height);
844 rb->lcd_set_viewport(NULL); /* to regular viewport */ 844 rb->lcd_set_viewport(last_vp); /* to regular viewport */
845 845
846 width += 2 + 2*OSC_OSD_MARGIN_SIZE; 846 width += 2 + 2*OSC_OSD_MARGIN_SIZE;
847 if (width > maxwidth) 847 if (width > maxwidth)
diff --git a/apps/plugins/pacbox/pacbox.c b/apps/plugins/pacbox/pacbox.c
index 262ab3e836..71c9751cad 100755
--- a/apps/plugins/pacbox/pacbox.c
+++ b/apps/plugins/pacbox/pacbox.c
@@ -35,6 +35,7 @@
35#include "lib/configfile.h" 35#include "lib/configfile.h"
36#include "lib/playback_control.h" 36#include "lib/playback_control.h"
37#include "lib/helper.h" 37#include "lib/helper.h"
38static fb_data *lcd_fb;
38 39
39/*Allows split screen jump and makes pacman invincible if you start at 18 credits (for testing purposes)*/ 40/*Allows split screen jump and makes pacman invincible if you start at 18 credits (for testing purposes)*/
40//#define CHEATS 1 41//#define CHEATS 1
@@ -704,7 +705,7 @@ static int gameProc( void )
704 rb->lcd_blit_pal256( video_buffer, 0, 0, XOFS, YOFS, 705 rb->lcd_blit_pal256( video_buffer, 0, 0, XOFS, YOFS,
705 ScreenWidth, ScreenHeight); 706 ScreenWidth, ScreenHeight);
706#else 707#else
707 blit_display(*rb->lcd_framebuffer,video_buffer); 708 blit_display(lcd_fb ,video_buffer);
708#endif 709#endif
709 710
710 if (settings.showfps) { 711 if (settings.showfps) {
@@ -743,6 +744,9 @@ enum plugin_status plugin_start(const void* parameter)
743 rb->lcd_clear_display(); 744 rb->lcd_clear_display();
744 rb->lcd_update(); 745 rb->lcd_update();
745 746
747 struct viewport *vp_main = rb->lcd_set_viewport(NULL);
748 lcd_fb = vp_main->buffer->fb_ptr;
749
746 /* Set the default settings */ 750 /* Set the default settings */
747 settings.difficulty = 0; /* Normal */ 751 settings.difficulty = 0; /* Normal */
748 settings.numlives = 2; /* 3 lives */ 752 settings.numlives = 2; /* 3 lives */
diff --git a/apps/plugins/pictureflow/pictureflow.c b/apps/plugins/pictureflow/pictureflow.c
index eadf9c3d0a..5f700aac83 100644
--- a/apps/plugins/pictureflow/pictureflow.c
+++ b/apps/plugins/pictureflow/pictureflow.c
@@ -35,6 +35,7 @@
35#include "lib/feature_wrappers.h" 35#include "lib/feature_wrappers.h"
36 36
37/******************************* Globals ***********************************/ 37/******************************* Globals ***********************************/
38static fb_data *lcd_fb;
38 39
39/* 40/*
40 * Targets which use plugin_get_audio_buffer() can't have playback from 41 * Targets which use plugin_get_audio_buffer() can't have playback from
@@ -190,7 +191,7 @@ GREY_INFO_STRUCT
190#define BUFFER_HEIGHT _grey_info.height 191#define BUFFER_HEIGHT _grey_info.height
191typedef unsigned char pix_t; 192typedef unsigned char pix_t;
192#else /* LCD_DEPTH >= 8 */ 193#else /* LCD_DEPTH >= 8 */
193#define LCD_BUF *rb->lcd_framebuffer 194#define LCD_BUF lcd_fb
194#define G_PIX LCD_RGBPACK 195#define G_PIX LCD_RGBPACK
195#define N_PIX LCD_RGBPACK 196#define N_PIX LCD_RGBPACK
196#define G_BRIGHT(y) LCD_RGBPACK(y,y,y) 197#define G_BRIGHT(y) LCD_RGBPACK(y,y,y)
@@ -3847,6 +3848,9 @@ static int pictureflow_main(void)
3847 3848
3848enum plugin_status plugin_start(const void *parameter) 3849enum plugin_status plugin_start(const void *parameter)
3849{ 3850{
3851 struct viewport *vp_main = rb->lcd_set_viewport(NULL);
3852 lcd_fb = vp_main->buffer->fb_ptr;
3853
3850 int ret; 3854 int ret;
3851 (void) parameter; 3855 (void) parameter;
3852 3856
diff --git a/apps/plugins/plasma.c b/apps/plugins/plasma.c
index 9e2e3832a3..f944d3d775 100644
--- a/apps/plugins/plasma.c
+++ b/apps/plugins/plasma.c
@@ -36,6 +36,8 @@
36 36
37 37
38/******************************* Globals ***********************************/ 38/******************************* Globals ***********************************/
39static fb_data *lcd_fb;
40
39 41
40static unsigned char wave_array[256]; /* Pre calculated wave array */ 42static unsigned char wave_array[256]; /* Pre calculated wave array */
41#ifdef HAVE_LCD_COLOR 43#ifdef HAVE_LCD_COLOR
@@ -201,9 +203,9 @@ int main(void)
201#ifdef HAVE_LCD_COLOR 203#ifdef HAVE_LCD_COLOR
202 shades_generate(time++); /* dynamically */ 204 shades_generate(time++); /* dynamically */
203#if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_PAL256) 205#if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_PAL256)
204 ptr = (unsigned char*)*rb->lcd_framebuffer; 206 ptr = (unsigned char*)lcd_fb;
205#else 207#else
206 ptr = *rb->lcd_framebuffer; 208 ptr = lcd_fb;
207#endif 209#endif
208 210
209#else 211#else
@@ -237,7 +239,7 @@ int main(void)
237 p4-=sp4; 239 p4-=sp4;
238#ifdef HAVE_LCD_COLOR 240#ifdef HAVE_LCD_COLOR
239#if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_PAL256) 241#if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_PAL256)
240 rb->lcd_blit_pal256( (unsigned char*)*rb->lcd_framebuffer, 242 rb->lcd_blit_pal256( (unsigned char*)lcd_fb,
241 0,0,0,0,LCD_WIDTH,LCD_HEIGHT); 243 0,0,0,0,LCD_WIDTH,LCD_HEIGHT);
242#else 244#else
243 rb->lcd_update(); 245 rb->lcd_update();
@@ -326,5 +328,8 @@ enum plugin_status plugin_start(const void* parameter)
326#if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_PAL256) 328#if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_PAL256)
327 rb->lcd_set_mode(LCD_MODE_PAL256); 329 rb->lcd_set_mode(LCD_MODE_PAL256);
328#endif 330#endif
331 struct viewport *vp_main = rb->lcd_set_viewport(NULL);
332 lcd_fb = vp_main->buffer->fb_ptr;
333
329 return main(); 334 return main();
330} 335}
diff --git a/apps/plugins/puzzles/rockbox.c b/apps/plugins/puzzles/rockbox.c
index ed58bd900a..08581db1c6 100644
--- a/apps/plugins/puzzles/rockbox.c
+++ b/apps/plugins/puzzles/rockbox.c
@@ -310,6 +310,7 @@ static int help_times = 0;
310#endif 310#endif
311 311
312/* clipping stuff */ 312/* clipping stuff */
313static fb_data *lcd_fb;
313static struct viewport clip_rect; 314static struct viewport clip_rect;
314static bool clipped = false, zoom_enabled = false, view_mode = true, mouse_mode = false; 315static bool clipped = false, zoom_enabled = false, view_mode = true, mouse_mode = false;
315 316
@@ -1016,7 +1017,7 @@ static void rb_draw_line(void *handle, int x1, int y1, int x2, int y2,
1016 } 1017 }
1017 else 1018 else
1018#endif 1019#endif
1019 draw_antialiased_line(*rb->lcd_framebuffer, LCD_WIDTH, LCD_HEIGHT, x1, y1, x2, y2); 1020 draw_antialiased_line(lcd_fb, LCD_WIDTH, LCD_HEIGHT, x1, y1, x2, y2);
1020 } 1021 }
1021 else 1022 else
1022 { 1023 {
@@ -1294,7 +1295,7 @@ static void rb_draw_poly(void *handle, int *coords, int npoints,
1294 x2, y2); 1295 x2, y2);
1295 } 1296 }
1296 else 1297 else
1297 draw_antialiased_line(*rb->lcd_framebuffer, LCD_WIDTH, LCD_HEIGHT, x1, y1, x2, y2); 1298 draw_antialiased_line(lcd_fb, LCD_WIDTH, LCD_HEIGHT, x1, y1, x2, y2);
1298 1299
1299#ifdef DEBUG_MENU 1300#ifdef DEBUG_MENU
1300 if(debug_settings.polyanim) 1301 if(debug_settings.polyanim)
@@ -1319,7 +1320,7 @@ static void rb_draw_poly(void *handle, int *coords, int npoints,
1319 x2, y2); 1320 x2, y2);
1320 } 1321 }
1321 else 1322 else
1322 draw_antialiased_line(*rb->lcd_framebuffer, LCD_WIDTH, LCD_HEIGHT, x1, y1, x2, y2); 1323 draw_antialiased_line(lcd_fb, LCD_WIDTH, LCD_HEIGHT, x1, y1, x2, y2);
1323 } 1324 }
1324 else 1325 else
1325 { 1326 {
@@ -1474,7 +1475,7 @@ static void rb_blitter_save(void *handle, blitter *bl, int x, int y)
1474 1475
1475 trim_rect(&x, &y, &w, &h); 1476 trim_rect(&x, &y, &w, &h);
1476 1477
1477 fb_data *fb = zoom_enabled ? zoom_fb : *rb->lcd_framebuffer; 1478 fb_data *fb = zoom_enabled ? zoom_fb : lcd_fb;
1478 LOGF("rb_blitter_save(%d, %d, %d, %d)", x, y, w, h); 1479 LOGF("rb_blitter_save(%d, %d, %d, %d)", x, y, w, h);
1479 for(int i = 0; i < h; ++i) 1480 for(int i = 0; i < h; ++i)
1480 { 1481 {
@@ -1778,9 +1779,9 @@ static void timer_cb(void)
1778 static bool what = false; 1779 static bool what = false;
1779 what = !what; 1780 what = !what;
1780 if(what) 1781 if(what)
1781 *rb->lcd_framebuffer[0] = LCD_BLACK; 1782 lcd_fb[0] = LCD_BLACK;
1782 else 1783 else
1783 *rb->lcd_framebuffer[0] = LCD_WHITE; 1784 lcd_fb[0] = LCD_WHITE;
1784 rb->lcd_update(); 1785 rb->lcd_update();
1785 } 1786 }
1786#endif 1787#endif
@@ -2909,7 +2910,7 @@ static void bench_aa(void)
2909 int i = 0; 2910 int i = 0;
2910 while(*rb->current_tick < next) 2911 while(*rb->current_tick < next)
2911 { 2912 {
2912 draw_antialiased_line(*rb->lcd_framebuffer, LCD_WIDTH, LCD_HEIGHT, 0, 0, 20, 31); 2913 draw_antialiased_line(lcd_fb, LCD_WIDTH, LCD_HEIGHT, 0, 0, 20, 31);
2913 ++i; 2914 ++i;
2914 } 2915 }
2915 rb->splashf(HZ, "%d AA lines/sec", i); 2916 rb->splashf(HZ, "%d AA lines/sec", i);
@@ -3843,6 +3844,8 @@ enum plugin_status plugin_start(const void *param)
3843 3844
3844 giant_buffer = rb->plugin_get_buffer(&giant_buffer_len); 3845 giant_buffer = rb->plugin_get_buffer(&giant_buffer_len);
3845 init_tlsf(); 3846 init_tlsf();
3847 struct viewport *vp_main = rb->lcd_set_viewport(NULL);
3848 lcd_fb = vp_main->buffer->fb_ptr;
3846 3849
3847 if(!strcmp(thegame.name, "Solo")) 3850 if(!strcmp(thegame.name, "Solo"))
3848 { 3851 {
diff --git a/apps/plugins/rockboy/lcd.c b/apps/plugins/rockboy/lcd.c
index 387a88c3df..92db851ee8 100644
--- a/apps/plugins/rockboy/lcd.c
+++ b/apps/plugins/rockboy/lcd.c
@@ -64,6 +64,12 @@ unsigned char *vdest;
64fb_data *vdest; 64fb_data *vdest;
65#endif 65#endif
66 66
67static fb_data* get_framebuffer(void)
68{
69 struct viewport *vp_main = *(rb->screens[SCREEN_MAIN]->current_viewport);
70 return vp_main->buffer->fb_ptr;
71}
72
67#ifndef ASM_UPDATEPATPIX 73#ifndef ASM_UPDATEPATPIX
68static void updatepatpix(void) ICODE_ATTR; 74static void updatepatpix(void) ICODE_ATTR;
69static void updatepatpix(void) 75static void updatepatpix(void)
@@ -741,10 +747,11 @@ static void spr_scan(void)
741 747
742void lcd_begin(void) 748void lcd_begin(void)
743{ 749{
750 fb_data *lcd_fb = get_framebuffer();
744#if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_PAL256) 751#if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_PAL256)
745 vdest=(unsigned char*)*rb->lcd_framebuffer; 752 vdest=(unsigned char*)lcd_fb;
746#else 753#else
747 vdest=*rb->lcd_framebuffer; 754 vdest=lcd_fb;
748#endif 755#endif
749 756
750#ifdef HAVE_LCD_COLOR 757#ifdef HAVE_LCD_COLOR
@@ -975,9 +982,9 @@ void lcd_refreshline(void)
975 982
976#if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_PAL256) 983#if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_PAL256)
977 if(options.scaling==3) { 984 if(options.scaling==3) {
978 rb->lcd_blit_pal256((unsigned char*)*rb->lcd_framebuffer,(LCD_WIDTH-160)/2, (LCD_HEIGHT-144)/2, (LCD_WIDTH-160)/2, (LCD_HEIGHT-144)/2, 160, 144); 985 rb->lcd_blit_pal256((unsigned char*)lcd_fb,(LCD_WIDTH-160)/2, (LCD_HEIGHT-144)/2, (LCD_WIDTH-160)/2, (LCD_HEIGHT-144)/2, 160, 144);
979 } else { 986 } else {
980 rb->lcd_blit_pal256((unsigned char*)*rb->lcd_framebuffer,0,0,0,0,LCD_WIDTH,LCD_HEIGHT); 987 rb->lcd_blit_pal256((unsigned char*)lcd_fb,0,0,0,0,LCD_WIDTH,LCD_HEIGHT);
981 } 988 }
982#else 989#else
983 if(options.scaling==3) { 990 if(options.scaling==3) {
diff --git a/apps/plugins/rockboy/sys_rockbox.c b/apps/plugins/rockboy/sys_rockbox.c
index 364176ce2d..64acd37563 100644
--- a/apps/plugins/rockboy/sys_rockbox.c
+++ b/apps/plugins/rockboy/sys_rockbox.c
@@ -282,6 +282,12 @@ fb_data *frameb;
282void vid_update(int scanline) 282void vid_update(int scanline)
283{ 283{
284 register int cnt=0; 284 register int cnt=0;
285 static fb_data *lcd_fb = NULL;
286 if (!lcd_fb)
287 {
288 struct viewport *vp_main = *(rb->screens[SCREEN_MAIN]->current_viewport);
289 lcd_fb = vp_main->buffer->fb_ptr;
290 }
285 int scanline_remapped; 291 int scanline_remapped;
286#if (LCD_HEIGHT == 64) && (LCD_DEPTH == 1) /* Archos, Clip, m200v4 */ 292#if (LCD_HEIGHT == 64) && (LCD_DEPTH == 1) /* Archos, Clip, m200v4 */
287 int balance = 0; 293 int balance = 0;
@@ -290,7 +296,7 @@ void vid_update(int scanline)
290 else if (fb.mode==2) 296 else if (fb.mode==2)
291 scanline-=8; 297 scanline-=8;
292 scanline_remapped = scanline / 16; 298 scanline_remapped = scanline / 16;
293 frameb = *rb->lcd_framebuffer + scanline_remapped * LCD_WIDTH; 299 frameb = lcd_fb + scanline_remapped * LCD_WIDTH;
294 while (cnt < 160) { 300 while (cnt < 160) {
295 balance += LCD_WIDTH; 301 balance += LCD_WIDTH;
296 if (balance > 0) 302 if (balance > 0)
@@ -316,7 +322,7 @@ void vid_update(int scanline)
316 else if (fb.mode==2) 322 else if (fb.mode==2)
317 scanline-=8; 323 scanline-=8;
318 scanline_remapped = scanline / 4; 324 scanline_remapped = scanline / 4;
319 frameb = *rb->lcd_framebuffer + scanline_remapped * LCD_WIDTH; 325 frameb = lcd_fb + scanline_remapped * LCD_WIDTH;
320 while (cnt < 160) { 326 while (cnt < 160) {
321 *(frameb++) = (scan.buf[0][cnt]&0x3) | 327 *(frameb++) = (scan.buf[0][cnt]&0x3) |
322 ((scan.buf[1][cnt]&0x3)<<2) | 328 ((scan.buf[1][cnt]&0x3)<<2) |
diff --git a/apps/plugins/sdl/src/video/rockbox/SDL_rockboxvideo.c b/apps/plugins/sdl/src/video/rockbox/SDL_rockboxvideo.c
index 5e0ccfb167..85c245ed9c 100644
--- a/apps/plugins/sdl/src/video/rockbox/SDL_rockboxvideo.c
+++ b/apps/plugins/sdl/src/video/rockbox/SDL_rockboxvideo.c
@@ -67,6 +67,7 @@
67#define RBSDL_EXTRA0 SDLK_0 67#define RBSDL_EXTRA0 SDLK_0
68 68
69/* Initialization/Query functions */ 69/* Initialization/Query functions */
70static fb_data *lcd_fb;
70static int ROCKBOX_VideoInit(_THIS, SDL_PixelFormat *vformat); 71static int ROCKBOX_VideoInit(_THIS, SDL_PixelFormat *vformat);
71static SDL_Rect **ROCKBOX_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags); 72static SDL_Rect **ROCKBOX_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
72static SDL_Surface *ROCKBOX_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags); 73static SDL_Surface *ROCKBOX_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
@@ -447,6 +448,8 @@ static void rb_pixelformat(SDL_PixelFormat *vformat)
447 448
448int ROCKBOX_VideoInit(_THIS, SDL_PixelFormat *vformat) 449int ROCKBOX_VideoInit(_THIS, SDL_PixelFormat *vformat)
449{ 450{
451 struct viewport *vp_main = *(rb->screens[SCREEN_MAIN]->current_viewport);
452 lcd_fb = vp_main->buffer->fb_ptr;
450 /* we change this during the SDL_SetVideoMode implementation... */ 453 /* we change this during the SDL_SetVideoMode implementation... */
451 rb_pixelformat(vformat); 454 rb_pixelformat(vformat);
452 455
@@ -639,7 +642,7 @@ SDL_Surface *ROCKBOX_SetVideoMode(_THIS, SDL_Surface *current,
639 this->hidden->w = current->w = width; 642 this->hidden->w = current->w = width;
640 this->hidden->h = current->h = height; 643 this->hidden->h = current->h = height;
641 current->pitch = current->w * (bpp / 8); 644 current->pitch = current->w * (bpp / 8);
642 current->pixels = this->hidden->direct ? *rb->lcd_framebuffer : this->hidden->buffer; 645 current->pixels = this->hidden->direct ? lcd_fb : this->hidden->buffer;
643 646
644 /* We're done */ 647 /* We're done */
645 return(current); 648 return(current);
@@ -674,7 +677,7 @@ static void flip_pixels(int x, int y, int w, int h)
674 for(int x_0 = x; x_0 < x + w; ++x_0) 677 for(int x_0 = x; x_0 < x + w; ++x_0)
675 { 678 {
676 /* swap pixels directly in the framebuffer */ 679 /* swap pixels directly in the framebuffer */
677 *rb->lcd_framebuffer[y_0 * LCD_WIDTH + x_0] = swap16(*rb->lcd_framebuffer[y_0 * LCD_WIDTH + x_0]); 680 lcd_fb[y_0 * LCD_WIDTH + x_0] = swap16(lcd_fb[y_0 * LCD_WIDTH + x_0]);
678 } 681 }
679 } 682 }
680} 683}
@@ -684,7 +687,7 @@ static void blit_rotated(fb_data *src, int x, int y, int w, int h)
684{ 687{
685 for(int y_0 = y; y_0 < y + h; ++y_0) 688 for(int y_0 = y; y_0 < y + h; ++y_0)
686 for(int x_0 = x; x_0 < x + w; ++x_0) 689 for(int x_0 = x; x_0 < x + w; ++x_0)
687 *rb->lcd_framebuffer[x_0 * LCD_WIDTH + y_0] = src[(LCD_WIDTH - y_0) * LCD_HEIGHT + x_0]; 690 lcd_fb[x_0 * LCD_WIDTH + y_0] = src[(LCD_WIDTH - y_0) * LCD_HEIGHT + x_0];
688} 691}
689 692
690static void ROCKBOX_UpdateRects(_THIS, int numrects, SDL_Rect *rects) 693static void ROCKBOX_UpdateRects(_THIS, int numrects, SDL_Rect *rects)
@@ -720,7 +723,7 @@ static void ROCKBOX_UpdateRects(_THIS, int numrects, SDL_Rect *rects)
720 723
721 out_bmp.width = LCD_WIDTH; 724 out_bmp.width = LCD_WIDTH;
722 out_bmp.height = LCD_HEIGHT; 725 out_bmp.height = LCD_HEIGHT;
723 out_bmp.data = (char*)*rb->lcd_framebuffer; 726 out_bmp.data = (char*)lcd_fb;
724 simple_resize_bitmap(&in_bmp, &out_bmp); 727 simple_resize_bitmap(&in_bmp, &out_bmp);
725 } 728 }
726 else 729 else
diff --git a/apps/plugins/test_resize.c b/apps/plugins/test_resize.c
index 3e50bdc8cc..443067c7e1 100644
--- a/apps/plugins/test_resize.c
+++ b/apps/plugins/test_resize.c
@@ -64,8 +64,8 @@ static fb_data output_bmp_data[MAX_OUTPUT_WIDTH*MAX_OUTPUT_HEIGHT];
64enum plugin_status plugin_start(const void* parameter) 64enum plugin_status plugin_start(const void* parameter)
65{ 65{
66 (void)parameter; 66 (void)parameter;
67 67 struct viewport *vp_main = rb->lcd_set_viewport(NULL);
68 b = *rb->lcd_framebuffer; 68 b = vp_main->buffer->fb_ptr;
69 69
70 rb->lcd_set_background(LCD_RGBPACK(0,0,0)); 70 rb->lcd_set_background(LCD_RGBPACK(0,0,0));
71 rb->lcd_clear_display(); // TODO: Optimizes this by e.g. invalidating rects 71 rb->lcd_clear_display(); // TODO: Optimizes this by e.g. invalidating rects
diff --git a/apps/plugins/test_viewports.c b/apps/plugins/test_viewports.c
index 465a832399..60c6672456 100644
--- a/apps/plugins/test_viewports.c
+++ b/apps/plugins/test_viewports.c
@@ -35,7 +35,7 @@ static struct viewport vp0 =
35{ 35{
36 .x = 0, 36 .x = 0,
37 .y = 0, 37 .y = 0,
38 .width = LCD_WIDTH, 38 .width = LCD_WIDTH/ 2 + LCD_WIDTH / 3,
39 .height = 20, 39 .height = 20,
40 .font = FONT_UI, 40 .font = FONT_UI,
41 .drawmode = DRMODE_SOLID, 41 .drawmode = DRMODE_SOLID,
@@ -120,15 +120,37 @@ static struct viewport rvp1 =
120 120
121#endif 121#endif
122 122
123static void *test_address_fn(int x, int y)
124{
125 struct frame_buffer_t *fb = vp0.buffer;
126
127#if defined(LCD_STRIDEFORMAT) && LCD_STRIDEFORMAT == VERTICAL_STRIDE
128 size_t element = (x * LCD_NATIVE_STRIDE(fb->stride)) + y;
129#else
130 size_t element = (y * LCD_NATIVE_STRIDE(fb->stride)) + x;
131#endif
132 return fb->fb_ptr + (element % fb->elems);
133}
123 134
124enum plugin_status plugin_start(const void* parameter) 135enum plugin_status plugin_start(const void* parameter)
125{ 136{
126 (void)parameter; 137 (void)parameter;
127 char buf[80]; 138 char buf[80];
128 int i,y; 139 int i,y;
140 fb_data vp_buffer[LCD_NBELEMS(vp0.width, vp0.height)];
129 141
142 struct frame_buffer_t fb;
143
144 fb.stride = STRIDE_MAIN(vp0.width, vp0.height);
145
146 fb.fb_ptr = vp_buffer;
147 fb.elems = LCD_NBELEMS(vp0.width, vp0.height);
148 fb.get_address_fn = &test_address_fn;
149
150 rb->viewport_set_buffer(&vp0, &fb, SCREEN_MAIN);
130 rb->screens[SCREEN_MAIN]->set_viewport(&vp0); 151 rb->screens[SCREEN_MAIN]->set_viewport(&vp0);
131 rb->screens[SCREEN_MAIN]->clear_viewport(); 152 rb->screens[SCREEN_MAIN]->clear_viewport();
153
132 rb->screens[SCREEN_MAIN]->puts_scroll(0,0,"Viewport testing plugin - this is a scrolling title"); 154 rb->screens[SCREEN_MAIN]->puts_scroll(0,0,"Viewport testing plugin - this is a scrolling title");
133 155
134 rb->screens[SCREEN_MAIN]->set_viewport(&vp1); 156 rb->screens[SCREEN_MAIN]->set_viewport(&vp1);
@@ -192,6 +214,9 @@ enum plugin_status plugin_start(const void* parameter)
192 214
193 rb->screens[SCREEN_REMOTE]->update(); 215 rb->screens[SCREEN_REMOTE]->update();
194#endif 216#endif
217 rb->button_clear_queue();
218 while(rb->button_get(true) <= BUTTON_NONE)
219 ;;
195 220
196 rb->button_get(true); 221 rb->button_get(true);
197 222
diff --git a/apps/plugins/xworld/sys.c b/apps/plugins/xworld/sys.c
index 0bd1e0dc08..c57da9456b 100644
--- a/apps/plugins/xworld/sys.c
+++ b/apps/plugins/xworld/sys.c
@@ -40,6 +40,7 @@
40#include "engine.h" 40#include "engine.h"
41 41
42static struct System* save_sys; 42static struct System* save_sys;
43static fb_data *lcd_fb = NULL;
43 44
44static bool sys_save_settings(struct System* sys) 45static bool sys_save_settings(struct System* sys)
45{ 46{
@@ -438,6 +439,8 @@ void sys_init(struct System* sys, const char* title)
438 { 439 {
439 sys_reset_settings(sys); 440 sys_reset_settings(sys);
440 } 441 }
442 struct viewport *vp_main = rb->lcd_set_viewport(NULL);
443 lcd_fb = vp_main->buffer->fb_ptr;
441} 444}
442 445
443void sys_destroy(struct System* sys) 446void sys_destroy(struct System* sys)
@@ -584,7 +587,7 @@ void sys_copyRect(struct System* sys, uint16_t x, uint16_t y, uint16_t w, uint16
584 struct bitmap out_bmp; 587 struct bitmap out_bmp;
585 out_bmp.width = LCD_WIDTH; 588 out_bmp.width = LCD_WIDTH;
586 out_bmp.height = LCD_HEIGHT; 589 out_bmp.height = LCD_HEIGHT;
587 out_bmp.data = (unsigned char*) *rb->lcd_framebuffer; 590 out_bmp.data = (unsigned char*) lcd_fb;
588 591
589#ifdef HAVE_LCD_COLOR 592#ifdef HAVE_LCD_COLOR
590 if(sys->settings.scaling_quality == 1) 593 if(sys->settings.scaling_quality == 1)
@@ -631,25 +634,25 @@ void sys_copyRect(struct System* sys, uint16_t x, uint16_t y, uint16_t w, uint16
631 { 634 {
632#ifdef HAVE_LCD_COLOR 635#ifdef HAVE_LCD_COLOR
633 int r, g, b; 636 int r, g, b;
634 fb_data pix = *rb->lcd_framebuffer[y * LCD_WIDTH + x]; 637 fb_data pix = lcd_fb[y * LCD_WIDTH + x];
635#if (LCD_DEPTH > 24) 638#if (LCD_DEPTH > 24)
636 r = 0xff - pix.r; 639 r = 0xff - pix.r;
637 g = 0xff - pix.g; 640 g = 0xff - pix.g;
638 b = 0xff - pix.b; 641 b = 0xff - pix.b;
639 *rb->lcd_framebuffer[y * LCD_WIDTH + x] = (fb_data) { b, g, r, 255 }; 642 lcd_fb[y * LCD_WIDTH + x] = (fb_data) { b, g, r, 255 };
640#elif (LCD_DEPTH == 24) 643#elif (LCD_DEPTH == 24)
641 r = 0xff - pix.r; 644 r = 0xff - pix.r;
642 g = 0xff - pix.g; 645 g = 0xff - pix.g;
643 b = 0xff - pix.b; 646 b = 0xff - pix.b;
644 *rb->lcd_framebuffer[y * LCD_WIDTH + x] = (fb_data) { b, g, r }; 647 lcd_fb[y * LCD_WIDTH + x] = (fb_data) { b, g, r };
645#else 648#else
646 r = RGB_UNPACK_RED (pix); 649 r = RGB_UNPACK_RED (pix);
647 g = RGB_UNPACK_GREEN(pix); 650 g = RGB_UNPACK_GREEN(pix);
648 b = RGB_UNPACK_BLUE (pix); 651 b = RGB_UNPACK_BLUE (pix);
649 *rb->lcd_framebuffer[y * LCD_WIDTH + x] = LCD_RGBPACK(0xff - r, 0xff - g, 0xff - b); 652 lcd_fb[y * LCD_WIDTH + x] = LCD_RGBPACK(0xff - r, 0xff - g, 0xff - b);
650#endif 653#endif
651#else 654#else
652 *rb->lcd_framebuffer[y * LCD_WIDTH + x] = LCD_BRIGHTNESS(0xff - *rb->lcd_framebuffer[y * LCD_WIDTH + x]); 655 lcd_fb[y * LCD_WIDTH + x] = LCD_BRIGHTNESS(0xff - lcd_fb[y * LCD_WIDTH + x]);
653#endif 656#endif
654 } 657 }
655 } 658 }
@@ -671,14 +674,14 @@ void sys_copyRect(struct System* sys, uint16_t x, uint16_t y, uint16_t w, uint16
671 if(prev_frames && orig_fb) 674 if(prev_frames && orig_fb)
672 { 675 {
673 676
674 rb->memcpy(orig_fb, *rb->lcd_framebuffer, sizeof(fb_data) * LCD_WIDTH * LCD_HEIGHT); 677 rb->memcpy(orig_fb, lcd_fb, sizeof(fb_data) * LCD_WIDTH * LCD_HEIGHT);
675 /* fancy useless slow motion blur */ 678 /* fancy useless slow motion blur */
676 for(int y = 0; y < LCD_HEIGHT; ++y) 679 for(int y = 0; y < LCD_HEIGHT; ++y)
677 { 680 {
678 for(int x = 0; x < LCD_WIDTH; ++x) 681 for(int x = 0; x < LCD_WIDTH; ++x)
679 { 682 {
680 int r, g, b; 683 int r, g, b;
681 fb_data pix = *rb->lcd_framebuffer[y * LCD_WIDTH + x]; 684 fb_data pix = lcd_fb[y * LCD_WIDTH + x];
682 r = RGB_UNPACK_RED (pix); 685 r = RGB_UNPACK_RED (pix);
683 g = RGB_UNPACK_GREEN(pix); 686 g = RGB_UNPACK_GREEN(pix);
684 b = RGB_UNPACK_BLUE (pix); 687 b = RGB_UNPACK_BLUE (pix);
@@ -695,7 +698,7 @@ void sys_copyRect(struct System* sys, uint16_t x, uint16_t y, uint16_t w, uint16
695 r /= (BLUR_FRAMES + 1) / 2 * (1 + BLUR_FRAMES + 1); 698 r /= (BLUR_FRAMES + 1) / 2 * (1 + BLUR_FRAMES + 1);
696 g /= (BLUR_FRAMES + 1) / 2 * (1 + BLUR_FRAMES + 1); 699 g /= (BLUR_FRAMES + 1) / 2 * (1 + BLUR_FRAMES + 1);
697 b /= (BLUR_FRAMES + 1) / 2 * (1 + BLUR_FRAMES + 1); 700 b /= (BLUR_FRAMES + 1) / 2 * (1 + BLUR_FRAMES + 1);
698 *rb->lcd_framebuffer[y * LCD_WIDTH + x] = LCD_RGBPACK(r, g, b); 701 lcd_fb[y * LCD_WIDTH + x] = LCD_RGBPACK(r, g, b);
699 } 702 }
700 } 703 }
701 prev_baseidx -= LCD_WIDTH * LCD_HEIGHT; 704 prev_baseidx -= LCD_WIDTH * LCD_HEIGHT;
diff --git a/apps/plugins/zxbox/zxvid_16bpp.c b/apps/plugins/zxbox/zxvid_16bpp.c
index f8482e3147..f0e2cee5ac 100644
--- a/apps/plugins/zxbox/zxvid_16bpp.c
+++ b/apps/plugins/zxbox/zxvid_16bpp.c
@@ -33,6 +33,8 @@ static const unsigned _16bpp_colors[32] = {
33 LCD_RGBPACK(IB1, IB1, IB0), LCD_RGBPACK(IB1, IB1, IB1), 33 LCD_RGBPACK(IB1, IB1, IB0), LCD_RGBPACK(IB1, IB1, IB1),
34}; 34};
35 35
36static fb_data *lcd_fb = NULL;
37
36void init_spect_scr(void) 38void init_spect_scr(void)
37{ 39{
38 int i; 40 int i;
@@ -49,6 +51,11 @@ void init_spect_scr(void)
49 51
50void update_screen(void) 52void update_screen(void)
51{ 53{
54 if (!lcd_fb)
55 {
56 struct viewport *vp_main = rb->lcd_set_viewport(NULL);
57 lcd_fb = vp_main->buffer->fb_ptr;
58 }
52 fb_data *frameb; 59 fb_data *frameb;
53 60
54 int y=0; 61 int y=0;
@@ -58,7 +65,7 @@ void update_screen(void)
58 byte *scrptr; 65 byte *scrptr;
59 scrptr = (byte *) SPNM(image); 66 scrptr = (byte *) SPNM(image);
60 */ 67 */
61 frameb = *rb->lcd_framebuffer; 68 frameb = lcd_fb;
62 for ( y = 0 ; y < HEIGHT*WIDTH; y++ ){ 69 for ( y = 0 ; y < HEIGHT*WIDTH; y++ ){
63 frameb[y] = FB_SCALARPACK(_16bpp_colors[(unsigned)sp_image[y]]); 70 frameb[y] = FB_SCALARPACK(_16bpp_colors[(unsigned)sp_image[y]]);
64 } 71 }
@@ -68,7 +75,7 @@ void update_screen(void)
68 int srcx, srcy=0; /* x / y coordinates in source image */ 75 int srcx, srcy=0; /* x / y coordinates in source image */
69 unsigned char* image; 76 unsigned char* image;
70 image = sp_image + ( (Y_OFF)*(WIDTH) ) + X_OFF; 77 image = sp_image + ( (Y_OFF)*(WIDTH) ) + X_OFF;
71 frameb = *rb->lcd_framebuffer; 78 frameb = lcd_fb;
72 for(y = 0; y < LCD_HEIGHT; y++) 79 for(y = 0; y < LCD_HEIGHT; y++)
73 { 80 {
74 srcx = 0; /* reset our x counter before each row... */ 81 srcx = 0; /* reset our x counter before each row... */
diff --git a/apps/plugins/zxbox/zxvid_2bpp.c b/apps/plugins/zxbox/zxvid_2bpp.c
index 9772625387..97e6a5de76 100644
--- a/apps/plugins/zxbox/zxvid_2bpp.c
+++ b/apps/plugins/zxbox/zxvid_2bpp.c
@@ -26,6 +26,8 @@ static const unsigned char graylevels[16] = {
26 0, 1, 1, 1, 2, 2, 3, 3 26 0, 1, 1, 1, 2, 2, 3, 3
27}; 27};
28 28
29static fb_data *lcd_fb = NULL;
30
29void init_spect_scr(void) 31void init_spect_scr(void)
30{ 32{
31 int i; 33 int i;
@@ -41,6 +43,11 @@ void init_spect_scr(void)
41} 43}
42void update_screen(void) 44void update_screen(void)
43{ 45{
46 if (!lcd_fb)
47 {
48 struct viewport *vp_main = rb->lcd_set_viewport(NULL);
49 lcd_fb = vp_main->buffer->fb_ptr;
50 }
44 fb_data *frameb; 51 fb_data *frameb;
45 int y=0; 52 int y=0;
46 int x=0; 53 int x=0;
@@ -51,7 +58,7 @@ void update_screen(void)
51#if LCD_PIXELFORMAT == HORIZONTAL_PACKING 58#if LCD_PIXELFORMAT == HORIZONTAL_PACKING
52 for(y = 0; y < LCD_HEIGHT; y++) 59 for(y = 0; y < LCD_HEIGHT; y++)
53 { 60 {
54 frameb = *rb->lcd_framebuffer + (y) * FB_WIDTH; 61 frameb = lcd_fb + (y) * FB_WIDTH;
55 srcx = 0; /* reset our x counter before each row... */ 62 srcx = 0; /* reset our x counter before each row... */
56 for(x = 0; x < LCD_WIDTH; x++) 63 for(x = 0; x < LCD_WIDTH; x++)
57 { 64 {
@@ -67,7 +74,7 @@ void update_screen(void)
67 int shift; 74 int shift;
68 for(y = 0; y < LCD_HEIGHT; y++) 75 for(y = 0; y < LCD_HEIGHT; y++)
69 { 76 {
70 frameb = *rb->lcd_framebuffer + (y/4) * LCD_WIDTH; 77 frameb = lcd_fb + (y/4) * LCD_WIDTH;
71 srcx = 0; /* reset our x counter before each row... */ 78 srcx = 0; /* reset our x counter before each row... */
72 shift = ((y & 3 ) * 2 ); 79 shift = ((y & 3 ) * 2 );
73 mask = ~pixmask[y & 3]; 80 mask = ~pixmask[y & 3];
@@ -84,7 +91,7 @@ void update_screen(void)
84 int shift; 91 int shift;
85 for(y = 0; y < LCD_HEIGHT; y++) 92 for(y = 0; y < LCD_HEIGHT; y++)
86 { 93 {
87 frameb = *rb->lcd_framebuffer + (y/8) * LCD_WIDTH; 94 frameb = lcd_fb + (y/8) * LCD_WIDTH;
88 srcx = 0; /* reset our x counter before each row... */ 95 srcx = 0; /* reset our x counter before each row... */
89 shift = (y & 7); 96 shift = (y & 7);
90 mask = ~pixmask[y & 7]; 97 mask = ~pixmask[y & 7];
diff --git a/apps/recorder/keyboard.c b/apps/recorder/keyboard.c
index f735afe84d..b211fad331 100644
--- a/apps/recorder/keyboard.c
+++ b/apps/recorder/keyboard.c
@@ -1009,7 +1009,7 @@ static void kbd_draw_buttons(struct keyboard_parameters *pm, struct screen *sc)
1009 int sc_w = sc->getwidth(), sc_h = sc->getheight(); 1009 int sc_w = sc->getwidth(), sc_h = sc->getheight();
1010 viewport_set_defaults(&vp, sc->screen_type); 1010 viewport_set_defaults(&vp, sc->screen_type);
1011 vp.flags |= VP_FLAG_ALIGN_CENTER; 1011 vp.flags |= VP_FLAG_ALIGN_CENTER;
1012 sc->set_viewport(&vp); 1012 struct viewport *last_vp = sc->set_viewport(&vp);
1013 text_h = sc->getcharheight(); 1013 text_h = sc->getcharheight();
1014 button_h = GRID_SIZE(sc->screen_type, text_h); 1014 button_h = GRID_SIZE(sc->screen_type, text_h);
1015 text_y = (button_h - text_h) / 2 + 1; 1015 text_y = (button_h - text_h) / 2 + 1;
@@ -1039,7 +1039,7 @@ static void kbd_draw_buttons(struct keyboard_parameters *pm, struct screen *sc)
1039 vp.x += vp.width; 1039 vp.x += vp.width;
1040 sc->vline(0, 0, button_h); 1040 sc->vline(0, 0, button_h);
1041 sc->putsxy(0, text_y, str(LANG_KBD_CANCEL)); 1041 sc->putsxy(0, text_y, str(LANG_KBD_CANCEL));
1042 sc->set_viewport(NULL); 1042 sc->set_viewport(last_vp);
1043} 1043}
1044 1044
1045static int keyboard_touchscreen(struct keyboard_parameters *pm, 1045static int keyboard_touchscreen(struct keyboard_parameters *pm,
diff --git a/apps/screen_access.c b/apps/screen_access.c
index 44e90742b0..390fb2ad4e 100644
--- a/apps/screen_access.c
+++ b/apps/screen_access.c
@@ -35,6 +35,7 @@
35#include "backlight.h" 35#include "backlight.h"
36#include "screen_access.h" 36#include "screen_access.h"
37#include "backdrop.h" 37#include "backdrop.h"
38#include "viewport.h"
38 39
39/* some helper functions to calculate metrics on the fly */ 40/* some helper functions to calculate metrics on the fly */
40static int screen_helper_getcharwidth(void) 41static int screen_helper_getcharwidth(void)
@@ -87,7 +88,17 @@ static void screen_helper_put_line(int x, int y, struct line_desc *line,
87 va_end(ap); 88 va_end(ap);
88} 89}
89 90
91void screen_helper_lcd_viewport_set_buffer(struct viewport *vp, struct frame_buffer_t *buffer)
92{
93 viewport_set_buffer(vp, buffer, SCREEN_MAIN);
94}
95
90#if NB_SCREENS == 2 96#if NB_SCREENS == 2
97void screen_helper_lcd_remote_viewport_set_buffer(struct viewport *vp, struct frame_buffer_t *buffer)
98{
99 viewport_set_buffer(vp, buffer, SCREEN_REMOTE);
100}
101
91static int screen_helper_remote_getcharwidth(void) 102static int screen_helper_remote_getcharwidth(void)
92{ 103{
93 return font_get(lcd_remote_getfont())->maxwidth; 104 return font_get(lcd_remote_getfont())->maxwidth;
@@ -156,7 +167,11 @@ struct screen screens[NB_SCREENS] =
156 .has_disk_led=true, 167 .has_disk_led=true,
157#endif 168#endif
158 .set_drawmode=&screen_helper_set_drawmode, 169 .set_drawmode=&screen_helper_set_drawmode,
170 .init_viewport=&lcd_init_viewport,
159 .set_viewport=&lcd_set_viewport, 171 .set_viewport=&lcd_set_viewport,
172 .set_viewport_ex=&lcd_set_viewport_ex,
173 .viewport_set_buffer = &screen_helper_lcd_viewport_set_buffer,
174 .current_viewport = &lcd_current_viewport,
160 .getwidth=&lcd_getwidth, 175 .getwidth=&lcd_getwidth,
161 .getheight=&lcd_getheight, 176 .getheight=&lcd_getheight,
162 .getstringsize=&lcd_getstringsize, 177 .getstringsize=&lcd_getstringsize,
@@ -221,7 +236,6 @@ struct screen screens[NB_SCREENS] =
221 .backdrop_load=&backdrop_load, 236 .backdrop_load=&backdrop_load,
222 .backdrop_show=&backdrop_show, 237 .backdrop_show=&backdrop_show,
223#endif 238#endif
224 .set_framebuffer = (void*)lcd_set_framebuffer,
225#if defined(HAVE_LCD_COLOR) 239#if defined(HAVE_LCD_COLOR)
226 .gradient_fillrect = lcd_gradient_fillrect, 240 .gradient_fillrect = lcd_gradient_fillrect,
227 .gradient_fillrect_part = lcd_gradient_fillrect_part, 241 .gradient_fillrect_part = lcd_gradient_fillrect_part,
@@ -241,7 +255,11 @@ struct screen screens[NB_SCREENS] =
241 .getcharheight=screen_helper_remote_getcharheight, 255 .getcharheight=screen_helper_remote_getcharheight,
242 .has_disk_led=false, 256 .has_disk_led=false,
243 .set_drawmode=&lcd_remote_set_drawmode, 257 .set_drawmode=&lcd_remote_set_drawmode,
258 .init_viewport=&lcd_remote_init_viewport,
244 .set_viewport=&lcd_remote_set_viewport, 259 .set_viewport=&lcd_remote_set_viewport,
260 .set_viewport_ex=&lcd_remote_set_viewport_ex,
261 .viewport_set_buffer = &screen_helper_lcd_remote_viewport_set_buffer,
262 .current_viewport = &lcd_remote_current_viewport,
245 .getwidth=&lcd_remote_getwidth, 263 .getwidth=&lcd_remote_getwidth,
246 .getheight=&lcd_remote_getheight, 264 .getheight=&lcd_remote_getheight,
247 .getstringsize=&lcd_remote_getstringsize, 265 .getstringsize=&lcd_remote_getstringsize,
@@ -307,7 +325,6 @@ struct screen screens[NB_SCREENS] =
307 .backdrop_load=&remote_backdrop_load, 325 .backdrop_load=&remote_backdrop_load,
308 .backdrop_show=&remote_backdrop_show, 326 .backdrop_show=&remote_backdrop_show,
309#endif 327#endif
310 .set_framebuffer = (void*)lcd_remote_set_framebuffer,
311 .put_line = screen_helper_remote_put_line, 328 .put_line = screen_helper_remote_put_line,
312 } 329 }
313#endif /* NB_SCREENS == 2 */ 330#endif /* NB_SCREENS == 2 */
diff --git a/apps/screen_access.h b/apps/screen_access.h
index 79ad79c153..81c7cb2a85 100644
--- a/apps/screen_access.h
+++ b/apps/screen_access.h
@@ -58,7 +58,11 @@ struct screen
58 bool has_disk_led; 58 bool has_disk_led;
59#endif 59#endif
60 void (*set_drawmode)(int mode); 60 void (*set_drawmode)(int mode);
61 void (*set_viewport)(struct viewport* vp); 61 struct viewport* (*init_viewport)(struct viewport* vp);
62 struct viewport* (*set_viewport)(struct viewport* vp);
63 struct viewport* (*set_viewport_ex)(struct viewport* vp, int flags);
64 void (*viewport_set_buffer)(struct viewport *vp, struct frame_buffer_t *buffer);
65 struct viewport** current_viewport;
62 int (*getwidth)(void); 66 int (*getwidth)(void);
63 int (*getheight)(void); 67 int (*getheight)(void);
64 int (*getstringsize)(const unsigned char *str, int *w, int *h); 68 int (*getstringsize)(const unsigned char *str, int *w, int *h);
@@ -126,7 +130,6 @@ struct screen
126 bool (*backdrop_load)(const char *filename, char* backdrop_buffer); 130 bool (*backdrop_load)(const char *filename, char* backdrop_buffer);
127 void (*backdrop_show)(char* backdrop_buffer); 131 void (*backdrop_show)(char* backdrop_buffer);
128#endif 132#endif
129 void (*set_framebuffer)(void *framebuffer);
130#if defined(HAVE_LCD_COLOR) 133#if defined(HAVE_LCD_COLOR)
131 void (*gradient_fillrect)(int x, int y, int width, int height, 134 void (*gradient_fillrect)(int x, int y, int width, int height,
132 unsigned start, unsigned end); 135 unsigned start, unsigned end);
diff --git a/apps/screens.c b/apps/screens.c
index 020d0a3021..fde99912d5 100644
--- a/apps/screens.c
+++ b/apps/screens.c
@@ -207,12 +207,13 @@ bool set_time_screen(const char* title, struct tm *tm)
207 /* 6 possible cursor possitions, 2 values stored for each: x, y */ 207 /* 6 possible cursor possitions, 2 values stored for each: x, y */
208 unsigned int cursor[6][2]; 208 unsigned int cursor[6][2];
209 struct viewport *vp = &viewports[s]; 209 struct viewport *vp = &viewports[s];
210 struct viewport *last_vp;
210 struct screen *screen = &screens[s]; 211 struct screen *screen = &screens[s];
211 static unsigned char rtl_idx[] = 212 static unsigned char rtl_idx[] =
212 { IDX_SECONDS, IDX_MINUTES, IDX_HOURS, IDX_DAY, IDX_MONTH, IDX_YEAR }; 213 { IDX_SECONDS, IDX_MINUTES, IDX_HOURS, IDX_DAY, IDX_MONTH, IDX_YEAR };
213 214
214 viewport_set_defaults(vp, s); 215 viewport_set_defaults(vp, s);
215 screen->set_viewport(vp); 216 last_vp = screen->set_viewport(vp);
216 nb_lines = viewport_get_nb_lines(vp); 217 nb_lines = viewport_get_nb_lines(vp);
217 218
218 /* minimum lines needed is 2 + title line */ 219 /* minimum lines needed is 2 + title line */
@@ -283,7 +284,7 @@ bool set_time_screen(const char* title, struct tm *tm)
283 if (nb_lines > 5) 284 if (nb_lines > 5)
284 screen->puts(0, 5, str(LANG_TIME_REVERT)); 285 screen->puts(0, 5, str(LANG_TIME_REVERT));
285 screen->update_viewport(); 286 screen->update_viewport();
286 screen->set_viewport(NULL); 287 screen->set_viewport(last_vp);
287 } 288 }
288 289
289 /* set the most common numbers */ 290 /* set the most common numbers */