summaryrefslogtreecommitdiff
path: root/firmware/drivers/lcd-16bit.c
diff options
context:
space:
mode:
authorDave Chapman <dave@dchapman.com>2008-01-07 20:34:11 +0000
committerDave Chapman <dave@dchapman.com>2008-01-07 20:34:11 +0000
commit945c8a221ade41c462a93f8452320a806e5645b3 (patch)
tree2a17823e286e6252e60c44c7f4753d5c18ef5172 /firmware/drivers/lcd-16bit.c
parent2a8f39820b49f116820356c2ca224f82f2106c21 (diff)
downloadrockbox-945c8a221ade41c462a93f8452320a806e5645b3.tar.gz
rockbox-945c8a221ade41c462a93f8452320a806e5645b3.zip
Add viewport capabilities to all the LCD drivers, and adapt scrolling code. This is the firmware/ part of FS#8385 - the changes to the WPS code still need more work and will be committed at a later date. NOTE: There are no user-visible changes with this commit - just the infrastructure.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@16018 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/drivers/lcd-16bit.c')
-rw-r--r--firmware/drivers/lcd-16bit.c478
1 files changed, 290 insertions, 188 deletions
diff --git a/firmware/drivers/lcd-16bit.c b/firmware/drivers/lcd-16bit.c
index b990f556d3..cc5a6c5ab7 100644
--- a/firmware/drivers/lcd-16bit.c
+++ b/firmware/drivers/lcd-16bit.c
@@ -49,25 +49,31 @@ fb_data lcd_framebuffer[LCD_FBHEIGHT][LCD_FBWIDTH]
49static fb_data* lcd_backdrop = NULL; 49static fb_data* lcd_backdrop = NULL;
50static long lcd_backdrop_offset IDATA_ATTR = 0; 50static long lcd_backdrop_offset IDATA_ATTR = 0;
51 51
52static struct viewport default_vp =
53{
54 .x = 0,
55 .y = 0,
56 .width = LCD_WIDTH,
57 .height = LCD_HEIGHT,
58 .font = FONT_SYSFIXED,
59 .drawmode = DRMODE_SOLID,
60 .xmargin = 0,
61 .ymargin = 0,
62 .fg_pattern = LCD_DEFAULT_FG,
63 .bg_pattern = LCD_DEFAULT_BG,
64 .lss_pattern = LCD_DEFAULT_BG,
65 .lse_pattern = LCD_DEFAULT_BG,
66 .lst_pattern = LCD_DEFAULT_BG,
67};
68
69/* The Gigabeat target build requires access to the current fg_pattern
70 in lcd-meg-fx.c */
52#if !defined(TOSHIBA_GIGABEAT_F) || defined(SIMULATOR) 71#if !defined(TOSHIBA_GIGABEAT_F) || defined(SIMULATOR)
53static unsigned fg_pattern IDATA_ATTR = LCD_DEFAULT_FG; 72static struct viewport* current_vp IDATA_ATTR = &default_vp;
54static unsigned bg_pattern IDATA_ATTR = LCD_DEFAULT_BG;
55static unsigned lss_pattern IDATA_ATTR = LCD_DEFAULT_LS;
56static unsigned lse_pattern IDATA_ATTR = LCD_DEFAULT_BG;
57static unsigned lst_pattern IDATA_ATTR = LCD_DEFAULT_FG;
58#else 73#else
59unsigned fg_pattern IDATA_ATTR = LCD_DEFAULT_FG; 74struct viewport* current_vp IDATA_ATTR = &default_vp;
60unsigned bg_pattern IDATA_ATTR = LCD_DEFAULT_BG;
61unsigned lss_pattern IDATA_ATTR = LCD_DEFAULT_LS;
62unsigned lse_pattern IDATA_ATTR = LCD_DEFAULT_BG;
63unsigned lst_pattern IDATA_ATTR = LCD_DEFAULT_FG;
64#endif 75#endif
65 76
66static int drawmode = DRMODE_SOLID;
67static int xmargin = 0;
68static int ymargin = 0;
69static int curfont = FONT_SYSFIXED;
70
71/* LCD init */ 77/* LCD init */
72void lcd_init(void) 78void lcd_init(void)
73{ 79{
@@ -78,84 +84,115 @@ void lcd_init(void)
78 scroll_init(); 84 scroll_init();
79} 85}
80 86
87/*** Viewports ***/
88
89void lcd_set_viewport(struct viewport* vp)
90{
91 if (vp == NULL)
92 current_vp = &default_vp;
93 else
94 current_vp = vp;
95}
96
97void lcd_update_viewport(void)
98{
99 lcd_update_rect(current_vp->x, current_vp->y,
100 current_vp->width, current_vp->height);
101}
102
103void lcd_update_viewport_rect(int x, int y, int width, int height)
104{
105 lcd_update_rect(current_vp->x + x, current_vp->y + y, width, height);
106}
107
81/*** parameter handling ***/ 108/*** parameter handling ***/
82 109
83void lcd_set_drawmode(int mode) 110void lcd_set_drawmode(int mode)
84{ 111{
85 drawmode = mode & (DRMODE_SOLID|DRMODE_INVERSEVID); 112 current_vp->drawmode = mode & (DRMODE_SOLID|DRMODE_INVERSEVID);
86} 113}
87 114
88int lcd_get_drawmode(void) 115int lcd_get_drawmode(void)
89{ 116{
90 return drawmode; 117 return current_vp->drawmode;
91} 118}
92 119
93void lcd_set_foreground(unsigned color) 120void lcd_set_foreground(unsigned color)
94{ 121{
95 fg_pattern = color; 122 current_vp->fg_pattern = color;
96} 123}
97 124
98unsigned lcd_get_foreground(void) 125unsigned lcd_get_foreground(void)
99{ 126{
100 return fg_pattern; 127 return current_vp->fg_pattern;
101} 128}
102 129
103void lcd_set_background(unsigned color) 130void lcd_set_background(unsigned color)
104{ 131{
105 bg_pattern = color; 132 current_vp->bg_pattern = color;
106} 133}
107 134
108unsigned lcd_get_background(void) 135unsigned lcd_get_background(void)
109{ 136{
110 return bg_pattern; 137 return current_vp->bg_pattern;
111} 138}
112 139
113void lcd_set_selector_start(unsigned color) 140void lcd_set_selector_start(unsigned color)
114{ 141{
115 lss_pattern = color; 142 current_vp->lss_pattern = color;
116} 143}
117 144
118void lcd_set_selector_end(unsigned color) 145void lcd_set_selector_end(unsigned color)
119{ 146{
120 lse_pattern = color; 147 current_vp->lse_pattern = color;
121} 148}
122 149
123void lcd_set_selector_text(unsigned color) 150void lcd_set_selector_text(unsigned color)
124{ 151{
125 lst_pattern = color; 152 current_vp->lst_pattern = color;
126} 153}
127 154
128void lcd_set_drawinfo(int mode, unsigned fg_color, unsigned bg_color) 155void lcd_set_drawinfo(int mode, unsigned fg_color, unsigned bg_color)
129{ 156{
130 lcd_set_drawmode(mode); 157 lcd_set_drawmode(mode);
131 fg_pattern = fg_color; 158 current_vp->fg_pattern = fg_color;
132 bg_pattern = bg_color; 159 current_vp->bg_pattern = bg_color;
133} 160}
134 161
135void lcd_setmargins(int x, int y) 162void lcd_setmargins(int x, int y)
136{ 163{
137 xmargin = x; 164 current_vp->xmargin = x;
138 ymargin = y; 165 current_vp->ymargin = y;
166}
167
168int lcd_getwidth(void)
169{
170 return current_vp->width;
171}
172
173int lcd_getheight(void)
174{
175 return current_vp->height;
139} 176}
140 177
141int lcd_getxmargin(void) 178int lcd_getxmargin(void)
142{ 179{
143 return xmargin; 180 return current_vp->xmargin;
144} 181}
145 182
146int lcd_getymargin(void) 183int lcd_getymargin(void)
147{ 184{
148 return ymargin; 185 return current_vp->ymargin;
149} 186}
150 187
151void lcd_setfont(int newfont) 188void lcd_setfont(int newfont)
152{ 189{
153 curfont = newfont; 190 current_vp->font = newfont;
154} 191}
155 192
156int lcd_getstringsize(const unsigned char *str, int *w, int *h) 193int lcd_getstringsize(const unsigned char *str, int *w, int *h)
157{ 194{
158 return font_getstringsize(str, w, h, curfont); 195 return font_getstringsize(str, w, h, current_vp->font);
159} 196}
160 197
161/*** low-level drawing functions ***/ 198/*** low-level drawing functions ***/
@@ -165,13 +202,13 @@ int lcd_getstringsize(const unsigned char *str, int *w, int *h)
165static void setpixel(fb_data *address) ICODE_ATTR; 202static void setpixel(fb_data *address) ICODE_ATTR;
166static void setpixel(fb_data *address) 203static void setpixel(fb_data *address)
167{ 204{
168 *address = fg_pattern; 205 *address = current_vp->fg_pattern;
169} 206}
170 207
171static void clearpixel(fb_data *address) ICODE_ATTR; 208static void clearpixel(fb_data *address) ICODE_ATTR;
172static void clearpixel(fb_data *address) 209static void clearpixel(fb_data *address)
173{ 210{
174 *address = bg_pattern; 211 *address = current_vp->bg_pattern;
175} 212}
176 213
177static void clearimgpixel(fb_data *address) ICODE_ATTR; 214static void clearimgpixel(fb_data *address) ICODE_ATTR;
@@ -226,31 +263,74 @@ fb_data* lcd_get_backdrop(void)
226 263
227/*** drawing functions ***/ 264/*** drawing functions ***/
228 265
229/* Clear the whole display */ 266/* Clear the current viewport */
230void lcd_clear_display(void) 267void lcd_clear_viewport(void)
231{ 268{
232 fb_data *dst = LCDADDR(0, 0); 269 fb_data *dst, *dst_end;
270
271 dst = LCDADDR(current_vp->x, current_vp->y);
272 dst_end = dst + current_vp->height * LCD_WIDTH;
233 273
234 if (drawmode & DRMODE_INVERSEVID) 274 if (current_vp->drawmode & DRMODE_INVERSEVID)
235 { 275 {
236 memset16(dst, fg_pattern, LCD_WIDTH*LCD_HEIGHT); 276 do
277 {
278 memset16(dst, current_vp->fg_pattern, current_vp->width);
279 dst += LCD_WIDTH;
280 }
281 while (dst < dst_end);
237 } 282 }
238 else 283 else
239 { 284 {
240 if (!lcd_backdrop) 285 if (!lcd_backdrop)
241 memset16(dst, bg_pattern, LCD_WIDTH*LCD_HEIGHT); 286 {
287 do
288 {
289 memset16(dst, current_vp->bg_pattern, current_vp->width);
290 dst += LCD_WIDTH;
291 }
292 while (dst < dst_end);
293 }
242 else 294 else
243 memcpy(dst, lcd_backdrop, sizeof(lcd_framebuffer)); 295 {
296 do
297 {
298 memcpy(dst, (void *)((long)dst + lcd_backdrop_offset),
299 current_vp->width * sizeof(fb_data));
300 dst += LCD_WIDTH;
301 }
302 while (dst < dst_end);
303 }
244 } 304 }
245 305
246 lcd_scroll_info.lines = 0; 306 if (current_vp == &default_vp)
307 {
308 lcd_scroll_info.lines = 0;
309 }
310 else
311 {
312 lcd_scroll_stop(current_vp);
313 }
314}
315
316/* Clear the whole display */
317void lcd_clear_display(void)
318{
319 struct viewport* old_vp = current_vp;
320
321 current_vp = &default_vp;
322
323 lcd_clear_viewport();
324
325 current_vp = old_vp;
247} 326}
248 327
249/* Set a single pixel */ 328/* Set a single pixel */
250void lcd_drawpixel(int x, int y) 329void lcd_drawpixel(int x, int y)
251{ 330{
252 if (((unsigned)x < LCD_WIDTH) && ((unsigned)y < LCD_HEIGHT)) 331 if (((unsigned)x < (unsigned)current_vp->width) &&
253 lcd_fastpixelfuncs[drawmode](LCDADDR(x, y)); 332 ((unsigned)y < (unsigned)current_vp->height))
333 lcd_fastpixelfuncs[current_vp->drawmode](LCDADDR(current_vp->x+x, current_vp->y+y));
254} 334}
255 335
256/* Draw a line */ 336/* Draw a line */
@@ -262,7 +342,7 @@ void lcd_drawline(int x1, int y1, int x2, int y2)
262 int d, dinc1, dinc2; 342 int d, dinc1, dinc2;
263 int x, xinc1, xinc2; 343 int x, xinc1, xinc2;
264 int y, yinc1, yinc2; 344 int y, yinc1, yinc2;
265 lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[drawmode]; 345 lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[current_vp->drawmode];
266 346
267 deltax = abs(x2 - x1); 347 deltax = abs(x2 - x1);
268 deltay = abs(y2 - y1); 348 deltay = abs(y2 - y1);
@@ -306,8 +386,8 @@ void lcd_drawline(int x1, int y1, int x2, int y2)
306 386
307 for (i = 0; i < numpixels; i++) 387 for (i = 0; i < numpixels; i++)
308 { 388 {
309 if (((unsigned)x < LCD_WIDTH) && ((unsigned)y < LCD_HEIGHT)) 389 if (((unsigned)x < (unsigned)current_vp->width) && ((unsigned)y < (unsigned)current_vp->height))
310 pfunc(LCDADDR(x, y)); 390 pfunc(LCDADDR(x + current_vp->x, y + current_vp->y));
311 391
312 if (d < 0) 392 if (d < 0)
313 { 393 {
@@ -331,7 +411,7 @@ void lcd_hline(int x1, int x2, int y)
331 unsigned bits = 0; 411 unsigned bits = 0;
332 enum fill_opt fillopt = OPT_NONE; 412 enum fill_opt fillopt = OPT_NONE;
333 fb_data *dst, *dst_end; 413 fb_data *dst, *dst_end;
334 lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[drawmode]; 414 lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[current_vp->drawmode];
335 415
336 /* direction flip */ 416 /* direction flip */
337 if (x2 < x1) 417 if (x2 < x1)
@@ -342,23 +422,31 @@ void lcd_hline(int x1, int x2, int y)
342 } 422 }
343 423
344 /* nothing to draw? */ 424 /* nothing to draw? */
345 if (((unsigned)y >= LCD_HEIGHT) || (x1 >= LCD_WIDTH) || (x2 < 0)) 425 if (((unsigned)y >= (unsigned)current_vp->height) ||
426 (x1 >= current_vp->width) ||
427 (x2 < 0))
346 return; 428 return;
347 429
348 /* clipping */ 430 /* clipping */
349 if (x1 < 0) 431 if (x1 < 0)
350 x1 = 0; 432 x1 = 0;
351 if (x2 >= LCD_WIDTH) 433 if (x2 >= current_vp->width)
352 x2 = LCD_WIDTH-1; 434 x2 = current_vp->width-1;
435
436 width = x2 - x1 + 1;
353 437
354 if (drawmode & DRMODE_INVERSEVID) 438 /* Adjust x1 and y to viewport */
439 x1 += current_vp->x;
440 y += current_vp->y;
441
442 if (current_vp->drawmode & DRMODE_INVERSEVID)
355 { 443 {
356 if (drawmode & DRMODE_BG) 444 if (current_vp->drawmode & DRMODE_BG)
357 { 445 {
358 if (!lcd_backdrop) 446 if (!lcd_backdrop)
359 { 447 {
360 fillopt = OPT_SET; 448 fillopt = OPT_SET;
361 bits = bg_pattern; 449 bits = current_vp->bg_pattern;
362 } 450 }
363 else 451 else
364 fillopt = OPT_COPY; 452 fillopt = OPT_COPY;
@@ -366,14 +454,13 @@ void lcd_hline(int x1, int x2, int y)
366 } 454 }
367 else 455 else
368 { 456 {
369 if (drawmode & DRMODE_FG) 457 if (current_vp->drawmode & DRMODE_FG)
370 { 458 {
371 fillopt = OPT_SET; 459 fillopt = OPT_SET;
372 bits = fg_pattern; 460 bits = current_vp->fg_pattern;
373 } 461 }
374 } 462 }
375 dst = LCDADDR(x1, y); 463 dst = LCDADDR(x1, y);
376 width = x2 - x1 + 1;
377 464
378 switch (fillopt) 465 switch (fillopt)
379 { 466 {
@@ -400,7 +487,7 @@ void lcd_vline(int x, int y1, int y2)
400{ 487{
401 int y; 488 int y;
402 fb_data *dst, *dst_end; 489 fb_data *dst, *dst_end;
403 lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[drawmode]; 490 lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[current_vp->drawmode];
404 491
405 /* direction flip */ 492 /* direction flip */
406 if (y2 < y1) 493 if (y2 < y1)
@@ -411,16 +498,18 @@ void lcd_vline(int x, int y1, int y2)
411 } 498 }
412 499
413 /* nothing to draw? */ 500 /* nothing to draw? */
414 if (((unsigned)x >= LCD_WIDTH) || (y1 >= LCD_HEIGHT) || (y2 < 0)) 501 if ((x >= current_vp->width) ||
502 (y1 >= current_vp->height) ||
503 (y2 < 0))
415 return; 504 return;
416 505
417 /* clipping */ 506 /* clipping */
418 if (y1 < 0) 507 if (y1 < 0)
419 y1 = 0; 508 y1 = 0;
420 if (y2 >= LCD_HEIGHT) 509 if (y2 >= current_vp->height)
421 y2 = LCD_HEIGHT-1; 510 y2 = current_vp->height-1;
422 511
423 dst = LCDADDR(x, y1); 512 dst = LCDADDR(x + current_vp->x, y1 + current_vp->y);
424 dst_end = dst + (y2 - y1) * LCD_WIDTH; 513 dst_end = dst + (y2 - y1) * LCD_WIDTH;
425 514
426 do 515 do
@@ -452,11 +541,11 @@ void lcd_fillrect(int x, int y, int width, int height)
452 unsigned bits = 0; 541 unsigned bits = 0;
453 enum fill_opt fillopt = OPT_NONE; 542 enum fill_opt fillopt = OPT_NONE;
454 fb_data *dst, *dst_end; 543 fb_data *dst, *dst_end;
455 lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[drawmode]; 544 lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[current_vp->drawmode];
456 545
457 /* nothing to draw? */ 546 /* nothing to draw? */
458 if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT) 547 if ((width <= 0) || (height <= 0) || (x >= current_vp->width) ||
459 || (x + width <= 0) || (y + height <= 0)) 548 (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0))
460 return; 549 return;
461 550
462 /* clipping */ 551 /* clipping */
@@ -470,19 +559,19 @@ void lcd_fillrect(int x, int y, int width, int height)
470 height += y; 559 height += y;
471 y = 0; 560 y = 0;
472 } 561 }
473 if (x + width > LCD_WIDTH) 562 if (x + width > current_vp->width)
474 width = LCD_WIDTH - x; 563 width = current_vp->width - x;
475 if (y + height > LCD_HEIGHT) 564 if (y + height > current_vp->height)
476 height = LCD_HEIGHT - y; 565 height = current_vp->height - y;
477 566
478 if (drawmode & DRMODE_INVERSEVID) 567 if (current_vp->drawmode & DRMODE_INVERSEVID)
479 { 568 {
480 if (drawmode & DRMODE_BG) 569 if (current_vp->drawmode & DRMODE_BG)
481 { 570 {
482 if (!lcd_backdrop) 571 if (!lcd_backdrop)
483 { 572 {
484 fillopt = OPT_SET; 573 fillopt = OPT_SET;
485 bits = bg_pattern; 574 bits = current_vp->bg_pattern;
486 } 575 }
487 else 576 else
488 fillopt = OPT_COPY; 577 fillopt = OPT_COPY;
@@ -490,13 +579,13 @@ void lcd_fillrect(int x, int y, int width, int height)
490 } 579 }
491 else 580 else
492 { 581 {
493 if (drawmode & DRMODE_FG) 582 if (current_vp->drawmode & DRMODE_FG)
494 { 583 {
495 fillopt = OPT_SET; 584 fillopt = OPT_SET;
496 bits = fg_pattern; 585 bits = current_vp->fg_pattern;
497 } 586 }
498 } 587 }
499 dst = LCDADDR(x, y); 588 dst = LCDADDR(current_vp->x + x, current_vp->y + y);
500 dst_end = dst + height * LCD_WIDTH; 589 dst_end = dst + height * LCD_WIDTH;
501 590
502 do 591 do
@@ -530,24 +619,28 @@ void lcd_fillrect(int x, int y, int width, int height)
530/* Fill a rectangle with a gradient */ 619/* Fill a rectangle with a gradient */
531void lcd_gradient_rect(int x1, int x2, int y, int h) 620void lcd_gradient_rect(int x1, int x2, int y, int h)
532{ 621{
622 int old_pattern = current_vp->fg_pattern;
623
533 if (h == 0) return; 624 if (h == 0) return;
534 625
535 int h_r = RGB_UNPACK_RED(lss_pattern) << 16; 626 int h_r = RGB_UNPACK_RED(current_vp->lss_pattern) << 16;
536 int h_b = RGB_UNPACK_BLUE(lss_pattern) << 16; 627 int h_b = RGB_UNPACK_BLUE(current_vp->lss_pattern) << 16;
537 int h_g = RGB_UNPACK_GREEN(lss_pattern) << 16; 628 int h_g = RGB_UNPACK_GREEN(current_vp->lss_pattern) << 16;
538 int rstep = (h_r - ((signed)RGB_UNPACK_RED(lse_pattern) << 16)) / h; 629 int rstep = (h_r - ((signed)RGB_UNPACK_RED(current_vp->lse_pattern) << 16)) / h;
539 int gstep = (h_g - ((signed)RGB_UNPACK_GREEN(lse_pattern) << 16)) / h; 630 int gstep = (h_g - ((signed)RGB_UNPACK_GREEN(current_vp->lse_pattern) << 16)) / h;
540 int bstep = (h_b - ((signed)RGB_UNPACK_BLUE(lse_pattern) << 16)) / h; 631 int bstep = (h_b - ((signed)RGB_UNPACK_BLUE(current_vp->lse_pattern) << 16)) / h;
541 int count; 632 int count;
542 633
543 fg_pattern = lss_pattern; 634 current_vp->fg_pattern = current_vp->lss_pattern;
544 for(count = 0; count < h; count++) { 635 for(count = 0; count < h; count++) {
545 lcd_hline(x1, x2, y + count); 636 lcd_hline(x1, x2, y + count);
546 h_r -= rstep; 637 h_r -= rstep;
547 h_g -= gstep; 638 h_g -= gstep;
548 h_b -= bstep; 639 h_b -= bstep;
549 fg_pattern = LCD_RGBPACK(h_r >> 16, h_g >> 16, h_b >> 16); 640 current_vp->fg_pattern = LCD_RGBPACK(h_r >> 16, h_g >> 16, h_b >> 16);
550 } 641 }
642
643 current_vp->fg_pattern = old_pattern;
551} 644}
552 645
553#define H_COLOR(lss, lse, cur_line, max_line) \ 646#define H_COLOR(lss, lse, cur_line, max_line) \
@@ -562,14 +655,14 @@ void lcd_gradient_rect_scroll(int x1, int x2, int y, int h,
562{ 655{
563 if (h == 0 || num_lines == 0) return; 656 if (h == 0 || num_lines == 0) return;
564 657
565 unsigned tmp_lss = lss_pattern; 658 unsigned tmp_lss = current_vp->lss_pattern;
566 unsigned tmp_lse = lse_pattern; 659 unsigned tmp_lse = current_vp->lse_pattern;
567 int lss_r = (signed)RGB_UNPACK_RED(lss_pattern); 660 int lss_r = (signed)RGB_UNPACK_RED(current_vp->lss_pattern);
568 int lss_b = (signed)RGB_UNPACK_BLUE(lss_pattern); 661 int lss_b = (signed)RGB_UNPACK_BLUE(current_vp->lss_pattern);
569 int lss_g = (signed)RGB_UNPACK_GREEN(lss_pattern); 662 int lss_g = (signed)RGB_UNPACK_GREEN(current_vp->lss_pattern);
570 int lse_r = (signed)RGB_UNPACK_RED(lse_pattern); 663 int lse_r = (signed)RGB_UNPACK_RED(current_vp->lse_pattern);
571 int lse_b = (signed)RGB_UNPACK_BLUE(lse_pattern); 664 int lse_b = (signed)RGB_UNPACK_BLUE(current_vp->lse_pattern);
572 int lse_g = (signed)RGB_UNPACK_GREEN(lse_pattern); 665 int lse_g = (signed)RGB_UNPACK_GREEN(current_vp->lse_pattern);
573 666
574 int h_r = H_COLOR(lss_r, lse_r, cur_line, num_lines); 667 int h_r = H_COLOR(lss_r, lse_r, cur_line, num_lines);
575 int h_g = H_COLOR(lss_g, lse_g, cur_line, num_lines); 668 int h_g = H_COLOR(lss_g, lse_g, cur_line, num_lines);
@@ -583,8 +676,8 @@ void lcd_gradient_rect_scroll(int x1, int x2, int y, int h,
583 676
584 lcd_gradient_rect(x1, x2, y, h); 677 lcd_gradient_rect(x1, x2, y, h);
585 678
586 lcd_set_selector_start(tmp_lss); 679 current_vp->lss_pattern = tmp_lss;
587 lcd_set_selector_end(tmp_lse); 680 current_vp->lse_pattern = tmp_lse;
588} 681}
589 682
590/* About Rockbox' internal monochrome bitmap format: 683/* About Rockbox' internal monochrome bitmap format:
@@ -613,8 +706,8 @@ void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
613 lcd_fastpixelfunc_type *fgfunc, *bgfunc; 706 lcd_fastpixelfunc_type *fgfunc, *bgfunc;
614 707
615 /* nothing to draw? */ 708 /* nothing to draw? */
616 if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT) 709 if ((width <= 0) || (height <= 0) || (x >= current_vp->width) ||
617 || (x + width <= 0) || (y + height <= 0)) 710 (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0))
618 return; 711 return;
619 712
620 /* clipping */ 713 /* clipping */
@@ -630,20 +723,20 @@ void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
630 src_y -= y; 723 src_y -= y;
631 y = 0; 724 y = 0;
632 } 725 }
633 if (x + width > LCD_WIDTH) 726 if (x + width > current_vp->width)
634 width = LCD_WIDTH - x; 727 width = current_vp->width - x;
635 if (y + height > LCD_HEIGHT) 728 if (y + height > current_vp->height)
636 height = LCD_HEIGHT - y; 729 height = current_vp->height - y;
637 730
638 src += stride * (src_y >> 3) + src_x; /* move starting point */ 731 src += stride * (src_y >> 3) + src_x; /* move starting point */
639 src_y &= 7; 732 src_y &= 7;
640 src_end = src + width; 733 src_end = src + width;
641 734
642 dst = LCDADDR(x, y); 735 dst = LCDADDR(current_vp->x + x, current_vp->y + y);
643 has_backdrop = (lcd_backdrop != NULL); 736 has_backdrop = (lcd_backdrop != NULL);
644 backdrop = lcd_backdrop + y * LCD_WIDTH + x; 737 backdrop = lcd_backdrop + (current_vp->y + y) * LCD_WIDTH + current_vp->x + x;
645 fgfunc = lcd_fastpixelfuncs[drawmode]; 738 fgfunc = lcd_fastpixelfuncs[current_vp->drawmode];
646 bgfunc = lcd_fastpixelfuncs[drawmode ^ DRMODE_INVERSEVID]; 739 bgfunc = lcd_fastpixelfuncs[current_vp->drawmode ^ DRMODE_INVERSEVID];
647 do 740 do
648 { 741 {
649 const unsigned char *src_col = src++; 742 const unsigned char *src_col = src++;
@@ -654,23 +747,23 @@ void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
654 dst_end = dst_col + height * LCD_WIDTH; 747 dst_end = dst_col + height * LCD_WIDTH;
655 do 748 do
656 { 749 {
657 switch (drawmode) 750 switch (current_vp->drawmode)
658 { 751 {
659 case DRMODE_SOLID: 752 case DRMODE_SOLID:
660 if (data & 0x01) 753 if (data & 0x01)
661 *dst_col = fg_pattern; 754 *dst_col = current_vp->fg_pattern;
662 else 755 else
663 *dst_col = has_backdrop ? *backdrop_col : bg_pattern; 756 *dst_col = has_backdrop ? *backdrop_col : current_vp->bg_pattern;
664 break; 757 break;
665 case DRMODE_FG: 758 case DRMODE_FG:
666 if (data & 0x01) 759 if (data & 0x01)
667 *dst_col = fg_pattern; 760 *dst_col = current_vp->fg_pattern;
668 break; 761 break;
669 case (DRMODE_SOLID|DRMODE_INVERSEVID): 762 case (DRMODE_SOLID|DRMODE_INVERSEVID):
670 if (data & 0x01) 763 if (data & 0x01)
671 *dst_col = has_backdrop ? *backdrop_col : bg_pattern; 764 *dst_col = has_backdrop ? *backdrop_col : current_vp->bg_pattern;
672 else 765 else
673 *dst_col = fg_pattern; 766 *dst_col = current_vp->fg_pattern;
674 break; 767 break;
675 default: 768 default:
676 if (data & 0x01) 769 if (data & 0x01)
@@ -709,8 +802,8 @@ void lcd_bitmap_part(const fb_data *src, int src_x, int src_y,
709 fb_data *dst, *dst_end; 802 fb_data *dst, *dst_end;
710 803
711 /* nothing to draw? */ 804 /* nothing to draw? */
712 if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT) 805 if ((width <= 0) || (height <= 0) || (x >= current_vp->width) ||
713 || (x + width <= 0) || (y + height <= 0)) 806 (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0))
714 return; 807 return;
715 808
716 /* clipping */ 809 /* clipping */
@@ -726,13 +819,13 @@ void lcd_bitmap_part(const fb_data *src, int src_x, int src_y,
726 src_y -= y; 819 src_y -= y;
727 y = 0; 820 y = 0;
728 } 821 }
729 if (x + width > LCD_WIDTH) 822 if (x + width > current_vp->width)
730 width = LCD_WIDTH - x; 823 width = current_vp->width - x;
731 if (y + height > LCD_HEIGHT) 824 if (y + height > current_vp->height)
732 height = LCD_HEIGHT - y; 825 height = current_vp->height - y;
733 826
734 src += stride * src_y + src_x; /* move starting point */ 827 src += stride * src_y + src_x; /* move starting point */
735 dst = LCDADDR(x, y); 828 dst = LCDADDR(current_vp->x + x, current_vp->y + y);
736 dst_end = dst + height * LCD_WIDTH; 829 dst_end = dst + height * LCD_WIDTH;
737 830
738 do 831 do
@@ -763,8 +856,8 @@ void lcd_bitmap_transparent_part(const fb_data *src, int src_x, int src_y,
763 fb_data *dst, *dst_end; 856 fb_data *dst, *dst_end;
764 857
765 /* nothing to draw? */ 858 /* nothing to draw? */
766 if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT) 859 if ((width <= 0) || (height <= 0) || (x >= current_vp->width) ||
767 || (x + width <= 0) || (y + height <= 0)) 860 (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0))
768 return; 861 return;
769 862
770 /* clipping */ 863 /* clipping */
@@ -780,13 +873,13 @@ void lcd_bitmap_transparent_part(const fb_data *src, int src_x, int src_y,
780 src_y -= y; 873 src_y -= y;
781 y = 0; 874 y = 0;
782 } 875 }
783 if (x + width > LCD_WIDTH) 876 if (x + width > current_vp->width)
784 width = LCD_WIDTH - x; 877 width = current_vp->width - x;
785 if (y + height > LCD_HEIGHT) 878 if (y + height > current_vp->height)
786 height = LCD_HEIGHT - y; 879 height = current_vp->height - y;
787 880
788 src += stride * src_y + src_x; /* move starting point */ 881 src += stride * src_y + src_x; /* move starting point */
789 dst = LCDADDR(x, y); 882 dst = LCDADDR(current_vp->x + x, current_vp->y + y);
790 dst_end = dst + height * LCD_WIDTH; 883 dst_end = dst + height * LCD_WIDTH;
791 884
792 do 885 do
@@ -795,7 +888,7 @@ void lcd_bitmap_transparent_part(const fb_data *src, int src_x, int src_y,
795 for(i = 0;i < width;i++) 888 for(i = 0;i < width;i++)
796 { 889 {
797 if (src[i] == REPLACEWITHFG_COLOR) 890 if (src[i] == REPLACEWITHFG_COLOR)
798 dst[i] = fg_pattern; 891 dst[i] = current_vp->fg_pattern;
799 else if(src[i] != TRANSPARENT_COLOR) 892 else if(src[i] != TRANSPARENT_COLOR)
800 dst[i] = src[i]; 893 dst[i] = src[i];
801 } 894 }
@@ -818,11 +911,11 @@ static void lcd_putsxyofs(int x, int y, int ofs, const unsigned char *str)
818{ 911{
819 unsigned short ch; 912 unsigned short ch;
820 unsigned short *ucs; 913 unsigned short *ucs;
821 struct font* pf = font_get(curfont); 914 struct font* pf = font_get(current_vp->font);
822 915
823 ucs = bidi_l2v(str, 1); 916 ucs = bidi_l2v(str, 1);
824 917
825 while ((ch = *ucs++) != 0 && x < LCD_WIDTH) 918 while ((ch = *ucs++) != 0 && x < current_vp->width)
826 { 919 {
827 int width; 920 int width;
828 const unsigned char *bits; 921 const unsigned char *bits;
@@ -875,51 +968,51 @@ void lcd_puts_style_offset(int x, int y, const unsigned char *str, int style,
875 int offset) 968 int offset)
876{ 969{
877 int xpos,ypos,w,h,xrect; 970 int xpos,ypos,w,h,xrect;
878 int lastmode = drawmode; 971 int lastmode = current_vp->drawmode;
879 int oldfgcolor = fg_pattern; 972 int oldfgcolor = current_vp->fg_pattern;
880 int oldbgcolor = bg_pattern; 973 int oldbgcolor = current_vp->bg_pattern;
881 974
882 /* make sure scrolling is turned off on the line we are updating */ 975 /* make sure scrolling is turned off on the line we are updating */
883 lcd_scroll_info.lines &= ~(1 << y); 976 lcd_scroll_stop_line(current_vp, y);
884 977
885 if(!str || !str[0]) 978 if(!str || !str[0])
886 return; 979 return;
887 980
888 lcd_getstringsize(str, &w, &h); 981 lcd_getstringsize(str, &w, &h);
889 xpos = xmargin + x*w / utf8length(str); 982 xpos = current_vp->xmargin + x*w / utf8length(str);
890 ypos = ymargin + y*h; 983 ypos = current_vp->ymargin + y*h;
891 drawmode = (style & STYLE_INVERT) ? 984 current_vp->drawmode = (style & STYLE_INVERT) ?
892 (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; 985 (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID;
893 if (style & STYLE_COLORED) { 986 if (style & STYLE_COLORED) {
894 if (drawmode == DRMODE_SOLID) 987 if (current_vp->drawmode == DRMODE_SOLID)
895 fg_pattern = style & STYLE_COLOR_MASK; 988 current_vp->fg_pattern = style & STYLE_COLOR_MASK;
896 else 989 else
897 bg_pattern = style & STYLE_COLOR_MASK; 990 current_vp->bg_pattern = style & STYLE_COLOR_MASK;
898 } 991 }
899 drawmode ^= DRMODE_INVERSEVID; 992 current_vp->drawmode ^= DRMODE_INVERSEVID;
900 xrect = xpos + MAX(w - offset, 0); 993 xrect = xpos + MAX(w - offset, 0);
901 994
902 if (style & STYLE_GRADIENT) { 995 if (style & STYLE_GRADIENT) {
903 drawmode = DRMODE_FG; 996 current_vp->drawmode = DRMODE_FG;
904 if (CURLN_UNPACK(style) == 0) 997 if (CURLN_UNPACK(style) == 0)
905 lcd_gradient_rect(xpos, LCD_WIDTH, ypos, h*NUMLN_UNPACK(style)); 998 lcd_gradient_rect(xpos, current_vp->width, ypos, h*NUMLN_UNPACK(style));
906 fg_pattern = lst_pattern; 999 current_vp->fg_pattern = current_vp->lst_pattern;
907 } 1000 }
908 else if (style & STYLE_COLORBAR) { 1001 else if (style & STYLE_COLORBAR) {
909 drawmode = DRMODE_FG; 1002 current_vp->drawmode = DRMODE_FG;
910 fg_pattern = lss_pattern; 1003 current_vp->fg_pattern = current_vp->lss_pattern;
911 lcd_fillrect(xpos, ypos, LCD_WIDTH - xpos, h); 1004 lcd_fillrect(xpos, ypos, current_vp->width - xpos, h);
912 fg_pattern = lst_pattern; 1005 current_vp->fg_pattern = current_vp->lst_pattern;
913 } 1006 }
914 else { 1007 else {
915 lcd_fillrect(xrect, ypos, LCD_WIDTH - xrect, h); 1008 lcd_fillrect(xrect, ypos, current_vp->width - xrect, h);
916 drawmode = (style & STYLE_INVERT) ? 1009 current_vp->drawmode = (style & STYLE_INVERT) ?
917 (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID; 1010 (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID;
918 } 1011 }
919 lcd_putsxyofs(xpos, ypos, offset, str); 1012 lcd_putsxyofs(xpos, ypos, offset, str);
920 drawmode = lastmode; 1013 current_vp->drawmode = lastmode;
921 fg_pattern = oldfgcolor; 1014 current_vp->fg_pattern = oldfgcolor;
922 bg_pattern = oldbgcolor; 1015 current_vp->bg_pattern = oldbgcolor;
923} 1016}
924 1017
925/*** scrolling ***/ 1018/*** scrolling ***/
@@ -938,15 +1031,23 @@ void lcd_puts_scroll_offset(int x, int y, const unsigned char *string, int offse
938 lcd_puts_scroll_style_offset(x, y, string, STYLE_DEFAULT, offset); 1031 lcd_puts_scroll_style_offset(x, y, string, STYLE_DEFAULT, offset);
939} 1032}
940 1033
1034/* Initialise a scrolling line at (x,y) in current viewport */
1035
941void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string, 1036void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string,
942 int style, int offset) 1037 int style, int offset)
943{ 1038{
944 struct scrollinfo* s; 1039 struct scrollinfo* s;
945 int w, h; 1040 int w, h;
946 1041
947 if(y>=LCD_SCROLLABLE_LINES) return; 1042 if ((unsigned)y >= (unsigned)current_vp->height)
1043 return;
1044
1045 /* remove any previously scrolling line at the same location */
1046 lcd_scroll_stop_line(current_vp, y);
1047
1048 if (lcd_scroll_info.lines >= LCD_SCROLLABLE_LINES) return;
948 1049
949 s = &lcd_scroll_info.scroll[y]; 1050 s = &lcd_scroll_info.scroll[lcd_scroll_info.lines];
950 1051
951 s->start_tick = current_tick + lcd_scroll_info.delay; 1052 s->start_tick = current_tick + lcd_scroll_info.delay;
952 s->style = style; 1053 s->style = style;
@@ -954,7 +1055,7 @@ void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string,
954 1055
955 lcd_getstringsize(string, &w, &h); 1056 lcd_getstringsize(string, &w, &h);
956 1057
957 if (LCD_WIDTH - x * 8 - xmargin < w) { 1058 if (current_vp->width - x * 8 - current_vp->xmargin < w) {
958 /* prepare scroll line */ 1059 /* prepare scroll line */
959 char *end; 1060 char *end;
960 1061
@@ -967,7 +1068,7 @@ void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string,
967 /* scroll bidirectional or forward only depending on the string 1068 /* scroll bidirectional or forward only depending on the string
968 width */ 1069 width */
969 if ( lcd_scroll_info.bidir_limit ) { 1070 if ( lcd_scroll_info.bidir_limit ) {
970 s->bidir = s->width < (LCD_WIDTH - xmargin) * 1071 s->bidir = s->width < (current_vp->width - current_vp->xmargin) *
971 (100 + lcd_scroll_info.bidir_limit) / 100; 1072 (100 + lcd_scroll_info.bidir_limit) / 100;
972 } 1073 }
973 else 1074 else
@@ -980,17 +1081,16 @@ void lcd_puts_scroll_style_offset(int x, int y, const unsigned char *string,
980 } 1081 }
981 1082
982 end = strchr(s->line, '\0'); 1083 end = strchr(s->line, '\0');
983 strncpy(end, string, LCD_WIDTH/2); 1084 strncpy(end, string, current_vp->width/2);
984 1085
1086 s->vp = current_vp;
1087 s->y = y;
985 s->len = utf8length(string); 1088 s->len = utf8length(string);
986 s->offset = offset; 1089 s->offset = offset;
987 s->startx = xmargin + x * s->width / s->len; 1090 s->startx = current_vp->xmargin + x * s->width / s->len;
988 s->backward = false; 1091 s->backward = false;
989 lcd_scroll_info.lines |= (1<<y); 1092 lcd_scroll_info.lines++;
990 } 1093 }
991 else
992 /* force a bit switch-off since it doesn't scroll */
993 lcd_scroll_info.lines &= ~(1<<y);
994} 1094}
995 1095
996void lcd_scroll_fn(void) 1096void lcd_scroll_fn(void)
@@ -1000,28 +1100,29 @@ void lcd_scroll_fn(void)
1000 int index; 1100 int index;
1001 int xpos, ypos; 1101 int xpos, ypos;
1002 int lastmode; 1102 int lastmode;
1003 unsigned old_fgcolor = fg_pattern; 1103 unsigned old_fgcolor;
1004 unsigned old_bgcolor = bg_pattern; 1104 unsigned old_bgcolor;
1005 1105 struct viewport* old_vp = current_vp;
1006 for ( index = 0; index < LCD_SCROLLABLE_LINES; index++ ) {
1007 /* really scroll? */
1008 if ((lcd_scroll_info.lines & (1 << index)) == 0)
1009 continue;
1010 1106
1107 for ( index = 0; index < lcd_scroll_info.lines; index++ ) {
1011 s = &lcd_scroll_info.scroll[index]; 1108 s = &lcd_scroll_info.scroll[index];
1012 1109
1013 /* check pause */ 1110 /* check pause */
1014 if (TIME_BEFORE(current_tick, s->start_tick)) 1111 if (TIME_BEFORE(current_tick, s->start_tick))
1015 continue; 1112 continue;
1016 1113
1114 lcd_set_viewport(s->vp);
1115 old_fgcolor = current_vp->fg_pattern;
1116 old_bgcolor = current_vp->bg_pattern;
1117
1017 if (s->style&STYLE_COLORED) { 1118 if (s->style&STYLE_COLORED) {
1018 if (s->style&STYLE_MODE_MASK) { 1119 if (s->style&STYLE_MODE_MASK) {
1019 fg_pattern = old_fgcolor; 1120 current_vp->fg_pattern = old_fgcolor;
1020 bg_pattern = s->style&STYLE_COLOR_MASK; 1121 current_vp->bg_pattern = s->style&STYLE_COLOR_MASK;
1021 } 1122 }
1022 else { 1123 else {
1023 fg_pattern = s->style&STYLE_COLOR_MASK; 1124 current_vp->fg_pattern = s->style&STYLE_COLOR_MASK;
1024 bg_pattern = old_bgcolor; 1125 current_vp->bg_pattern = old_bgcolor;
1025 } 1126 }
1026 } 1127 }
1027 1128
@@ -1030,9 +1131,9 @@ void lcd_scroll_fn(void)
1030 else 1131 else
1031 s->offset += lcd_scroll_info.step; 1132 s->offset += lcd_scroll_info.step;
1032 1133
1033 pf = font_get(curfont); 1134 pf = font_get(current_vp->font);
1034 xpos = s->startx; 1135 xpos = s->startx;
1035 ypos = ymargin + index * pf->height; 1136 ypos = current_vp->ymargin + s->y * pf->height;
1036 1137
1037 if (s->bidir) { /* scroll bidirectional */ 1138 if (s->bidir) { /* scroll bidirectional */
1038 if (s->offset <= 0) { 1139 if (s->offset <= 0) {
@@ -1041,9 +1142,9 @@ void lcd_scroll_fn(void)
1041 s->backward = false; 1142 s->backward = false;
1042 s->start_tick = current_tick + lcd_scroll_info.delay * 2; 1143 s->start_tick = current_tick + lcd_scroll_info.delay * 2;
1043 } 1144 }
1044 if (s->offset >= s->width - (LCD_WIDTH - xpos)) { 1145 if (s->offset >= s->width - (current_vp->width - xpos)) {
1045 /* at end of line */ 1146 /* at end of line */
1046 s->offset = s->width - (LCD_WIDTH - xpos); 1147 s->offset = s->width - (current_vp->width - xpos);
1047 s->backward = true; 1148 s->backward = true;
1048 s->start_tick = current_tick + lcd_scroll_info.delay * 2; 1149 s->start_tick = current_tick + lcd_scroll_info.delay * 2;
1049 } 1150 }
@@ -1054,35 +1155,36 @@ void lcd_scroll_fn(void)
1054 s->offset %= s->width; 1155 s->offset %= s->width;
1055 } 1156 }
1056 1157
1057 lastmode = drawmode; 1158 lastmode = current_vp->drawmode;
1058 switch (s->style&STYLE_MODE_MASK) { 1159 switch (s->style&STYLE_MODE_MASK) {
1059 case STYLE_INVERT: 1160 case STYLE_INVERT:
1060 drawmode = DRMODE_SOLID|DRMODE_INVERSEVID; 1161 current_vp->drawmode = DRMODE_SOLID|DRMODE_INVERSEVID;
1061 break; 1162 break;
1062 case STYLE_COLORBAR: 1163 case STYLE_COLORBAR:
1063 /* Solid colour line selector */ 1164 /* Solid colour line selector */
1064 drawmode = DRMODE_FG; 1165 current_vp->drawmode = DRMODE_FG;
1065 fg_pattern = lss_pattern; 1166 current_vp->fg_pattern = current_vp->lss_pattern;
1066 lcd_fillrect(xpos, ypos, LCD_WIDTH - xpos, pf->height); 1167 lcd_fillrect(xpos, ypos, current_vp->width - xpos, pf->height);
1067 fg_pattern = lst_pattern; 1168 current_vp->fg_pattern = current_vp->lst_pattern;
1068 break; 1169 break;
1069 case STYLE_GRADIENT: 1170 case STYLE_GRADIENT:
1070 /* Gradient line selector */ 1171 /* Gradient line selector */
1071 drawmode = DRMODE_FG; 1172 current_vp->drawmode = DRMODE_FG;
1072 lcd_gradient_rect_scroll(xpos, LCD_WIDTH, ypos, (signed)pf->height, 1173 lcd_gradient_rect_scroll(xpos, current_vp->width, ypos, (signed)pf->height,
1073 NUMLN_UNPACK(s->style), 1174 NUMLN_UNPACK(s->style),
1074 CURLN_UNPACK(s->style)); 1175 CURLN_UNPACK(s->style));
1075 fg_pattern = lst_pattern; 1176 current_vp->fg_pattern = current_vp->lst_pattern;
1076 break; 1177 break;
1077 default: 1178 default:
1078 drawmode = DRMODE_SOLID; 1179 current_vp->drawmode = DRMODE_SOLID;
1079 break; 1180 break;
1080 } 1181 }
1081 lcd_putsxyofs(xpos, ypos, s->offset, s->line); 1182 lcd_putsxyofs(xpos, ypos, s->offset, s->line);
1082 drawmode = lastmode; 1183 current_vp->drawmode = lastmode;
1083 lcd_update_rect(xpos, ypos, LCD_WIDTH - xpos, pf->height); 1184 current_vp->fg_pattern = old_fgcolor;
1185 current_vp->bg_pattern = old_bgcolor;
1186 lcd_update_viewport_rect(xpos, ypos, current_vp->width - xpos, pf->height);
1084 } 1187 }
1085 1188
1086 fg_pattern = old_fgcolor; 1189 lcd_set_viewport(old_vp);
1087 bg_pattern = old_bgcolor;
1088} 1190}