summaryrefslogtreecommitdiff
path: root/firmware/drivers/lcd-charcell.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-charcell.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-charcell.c')
-rw-r--r--firmware/drivers/lcd-charcell.c159
1 files changed, 119 insertions, 40 deletions
diff --git a/firmware/drivers/lcd-charcell.c b/firmware/drivers/lcd-charcell.c
index 0fd41481c5..1bc634cd2f 100644
--- a/firmware/drivers/lcd-charcell.c
+++ b/firmware/drivers/lcd-charcell.c
@@ -52,8 +52,17 @@ static unsigned char xfont_variable[VARIABLE_XCHARS][HW_PATTERN_SIZE];
52static bool xfont_variable_locked[VARIABLE_XCHARS]; 52static bool xfont_variable_locked[VARIABLE_XCHARS];
53static int xspace; /* stores xhcar id of ' ' - often needed */ 53static int xspace; /* stores xhcar id of ' ' - often needed */
54 54
55static int xmargin = 0; 55static struct viewport default_vp =
56static int ymargin = 0; 56 {
57 .x = 0,
58 .y = 0,
59 .width = LCD_WIDTH,
60 .height = LCD_HEIGHT,
61 .xmargin = 0,
62 .ymargin = 0,
63 };
64
65static struct viewport* current_vp = &default_vp;
57 66
58/* LCD init */ 67/* LCD init */
59void lcd_init (void) 68void lcd_init (void)
@@ -66,22 +75,47 @@ void lcd_init (void)
66 scroll_init(); 75 scroll_init();
67} 76}
68 77
78/* Viewports */
79
80void lcd_set_viewport(struct viewport* vp)
81{
82 if (vp == NULL)
83 current_vp = &default_vp;
84 else
85 current_vp = vp;
86}
87
88void lcd_update_viewport(void)
89{
90 lcd_update();
91}
92
69/** parameter handling **/ 93/** parameter handling **/
70 94
71void lcd_setmargins(int x, int y) 95void lcd_setmargins(int x, int y)
72{ 96{
73 xmargin = x; 97 current_vp->xmargin = x;
74 ymargin = y; 98 current_vp->ymargin = y;
75} 99}
76 100
77int lcd_getxmargin(void) 101int lcd_getxmargin(void)
78{ 102{
79 return xmargin; 103 return current_vp->xmargin;
80} 104}
81 105
82int lcd_getymargin(void) 106int lcd_getymargin(void)
83{ 107{
84 return ymargin; 108 return current_vp->ymargin;
109}
110
111int lcd_getwidth(void)
112{
113 return current_vp->width;
114}
115
116int lcd_getheight(void)
117{
118 return current_vp->height;
85} 119}
86 120
87int lcd_getstringsize(const unsigned char *str, int *w, int *h) 121int lcd_getstringsize(const unsigned char *str, int *w, int *h)
@@ -225,7 +259,13 @@ static int map_xchar(int xchar, unsigned char *substitute)
225 259
226static void lcd_putxchar(int x, int y, int xchar) 260static void lcd_putxchar(int x, int y, int xchar)
227{ 261{
228 int lcd_char = lcd_charbuffer[y][x]; 262 int lcd_char;
263
264 /* Adjust for viewport */
265 x += current_vp->x;
266 y += current_vp->y;
267
268 lcd_char = lcd_charbuffer[y][x];
229 269
230 if (lcd_char < lcd_pattern_count) /* old char was soft */ 270 if (lcd_char < lcd_pattern_count) /* old char was soft */
231 lcd_patterns[lcd_char].count--; /* decrease old reference count */ 271 lcd_patterns[lcd_char].count--; /* decrease old reference count */
@@ -283,19 +323,55 @@ void lcd_define_pattern(unsigned long ucs, const char *pattern)
283void lcd_clear_display(void) 323void lcd_clear_display(void)
284{ 324{
285 int x, y; 325 int x, y;
326 struct viewport* old_vp = current_vp;
286 327
287 lcd_stop_scroll(); 328 lcd_scroll_info.lines = 0;
288 lcd_remove_cursor(); 329 lcd_remove_cursor();
289 330
331 /* Set the default viewport - required for lcd_putxchar */
332 current_vp = &default_vp;
333
290 for (x = 0; x < LCD_WIDTH; x++) 334 for (x = 0; x < LCD_WIDTH; x++)
291 for (y = 0; y < LCD_HEIGHT; y++) 335 for (y = 0; y < LCD_HEIGHT; y++)
292 lcd_putxchar(x, y, xspace); 336 lcd_putxchar(x, y, xspace);
337
338 current_vp = old_vp;
339}
340
341/* Clear the current viewport */
342void lcd_clear_viewport(void)
343{
344 int x, y;
345
346 if (current_vp == &default_vp)
347 {
348 lcd_clear_display();
349 }
350 else
351 {
352 /* Remove the cursor if it is within the current viewport */
353 if (lcd_cursor.enabled &&
354 (lcd_cursor.x >= current_vp->x) &&
355 (lcd_cursor.x <= current_vp->x + current_vp->width) &&
356 (lcd_cursor.y >= current_vp->y) &&
357 (lcd_cursor.y <= current_vp->y + current_vp->height))
358 {
359 lcd_remove_cursor();
360 }
361
362 for (x = 0; x < current_vp->width; x++)
363 for (y = 0; y < current_vp->height; y++)
364 lcd_putxchar(x, y, xspace);
365
366 lcd_scroll_stop(current_vp);
367 }
293} 368}
294 369
295/* Put an unicode character at the given position */ 370/* Put an unicode character at the given position */
296void lcd_putc(int x, int y, unsigned long ucs) 371void lcd_putc(int x, int y, unsigned long ucs)
297{ 372{
298 if ((unsigned)x >= LCD_WIDTH || (unsigned)y >= LCD_HEIGHT) 373 if ((unsigned)x >= (unsigned)current_vp->width ||
374 (unsigned)y >= (unsigned)current_vp->height)
299 return; 375 return;
300 376
301 lcd_putxchar(x, y, find_xchar(ucs)); 377 lcd_putxchar(x, y, find_xchar(ucs));
@@ -304,15 +380,16 @@ void lcd_putc(int x, int y, unsigned long ucs)
304/* Show cursor (alternating with existing character) at the given position */ 380/* Show cursor (alternating with existing character) at the given position */
305void lcd_put_cursor(int x, int y, unsigned long cursor_ucs) 381void lcd_put_cursor(int x, int y, unsigned long cursor_ucs)
306{ 382{
307 if ((unsigned)x >= LCD_WIDTH || (unsigned)y >= LCD_HEIGHT 383 if ((unsigned)x >= (unsigned)current_vp->width ||
308 || lcd_cursor.enabled) 384 (unsigned)y >= (unsigned)current_vp->height ||
385 lcd_cursor.enabled)
309 return; 386 return;
310 387
311 lcd_cursor.enabled = true; 388 lcd_cursor.enabled = true;
312 lcd_cursor.visible = false; 389 lcd_cursor.visible = false;
313 lcd_cursor.hw_char = map_xchar(find_xchar(cursor_ucs), &lcd_cursor.subst_char); 390 lcd_cursor.hw_char = map_xchar(find_xchar(cursor_ucs), &lcd_cursor.subst_char);
314 lcd_cursor.x = x; 391 lcd_cursor.x = current_vp->x + x;
315 lcd_cursor.y = y; 392 lcd_cursor.y = current_vp->y + y;
316 lcd_cursor.downcount = 0; 393 lcd_cursor.downcount = 0;
317 lcd_cursor.divider = MAX((HZ/2) / lcd_scroll_info.ticks, 1); 394 lcd_cursor.divider = MAX((HZ/2) / lcd_scroll_info.ticks, 1);
318} 395}
@@ -335,7 +412,7 @@ static int lcd_putsxyofs(int x, int y, int ofs, const unsigned char *str)
335 unsigned short ucs; 412 unsigned short ucs;
336 const unsigned char *utf8 = str; 413 const unsigned char *utf8 = str;
337 414
338 while (*utf8 && x < LCD_WIDTH) 415 while (*utf8 && x < current_vp->width)
339 { 416 {
340 utf8 = utf8decode(utf8, &ucs); 417 utf8 = utf8decode(utf8, &ucs);
341 418
@@ -352,7 +429,7 @@ static int lcd_putsxyofs(int x, int y, int ofs, const unsigned char *str)
352/* Put a string at a given position */ 429/* Put a string at a given position */
353void lcd_putsxy(int x, int y, const unsigned char *str) 430void lcd_putsxy(int x, int y, const unsigned char *str)
354{ 431{
355 if ((unsigned)y >= LCD_HEIGHT) 432 if ((unsigned)y >= (unsigned)current_vp->height)
356 return; 433 return;
357 434
358 lcd_putsxyofs(x, y, 0, str); 435 lcd_putsxyofs(x, y, 0, str);
@@ -369,17 +446,14 @@ void lcd_puts(int x, int y, const unsigned char *str)
369/* Put a string at a given char position, skipping first offset chars */ 446/* Put a string at a given char position, skipping first offset chars */
370void lcd_puts_offset(int x, int y, const unsigned char *str, int offset) 447void lcd_puts_offset(int x, int y, const unsigned char *str, int offset)
371{ 448{
372 x += xmargin; 449 if ((unsigned)y >= (unsigned)current_vp->height)
373 y += ymargin;
374
375 if ((unsigned)y >= LCD_HEIGHT)
376 return; 450 return;
377 451
378 /* make sure scrolling is turned off on the line we are updating */ 452 /* make sure scrolling is turned off on the line we are updating */
379 lcd_scroll_info.lines &= ~(1 << y); 453 lcd_scroll_stop_line(current_vp, y);
380 454
381 x = lcd_putsxyofs(x, y, offset, str); 455 x = lcd_putsxyofs(x, y, offset, str);
382 while (x < LCD_WIDTH) 456 while (x < current_vp->width)
383 lcd_putxchar(x++, y, xspace); 457 lcd_putxchar(x++, y, xspace);
384} 458}
385 459
@@ -395,16 +469,22 @@ void lcd_puts_scroll_offset(int x, int y, const unsigned char *string,
395 struct scrollinfo* s; 469 struct scrollinfo* s;
396 int len; 470 int len;
397 471
398 if(y>=LCD_SCROLLABLE_LINES) return; 472 if ((unsigned)y >= (unsigned)current_vp->height)
473 return;
474
475 /* remove any previously scrolling line at the same location */
476 lcd_scroll_stop_line(current_vp, y);
399 477
400 s = &lcd_scroll_info.scroll[y]; 478 if (lcd_scroll_info.lines >= LCD_SCROLLABLE_LINES) return;
479
480 s = &lcd_scroll_info.scroll[lcd_scroll_info.lines];
401 481
402 s->start_tick = current_tick + lcd_scroll_info.delay; 482 s->start_tick = current_tick + lcd_scroll_info.delay;
403 483
404 lcd_puts_offset(x, y, string, offset); 484 lcd_puts_offset(x, y, string, offset);
405 len = utf8length(string); 485 len = utf8length(string);
406 486
407 if (LCD_WIDTH - x - xmargin < len) 487 if (current_vp->width - x - current_vp->xmargin < len)
408 { 488 {
409 /* prepare scroll line */ 489 /* prepare scroll line */
410 char *end; 490 char *end;
@@ -418,7 +498,7 @@ void lcd_puts_scroll_offset(int x, int y, const unsigned char *string,
418 /* scroll bidirectional or forward only depending on the string width */ 498 /* scroll bidirectional or forward only depending on the string width */
419 if (lcd_scroll_info.bidir_limit) 499 if (lcd_scroll_info.bidir_limit)
420 { 500 {
421 s->bidir = s->len < (LCD_WIDTH - xmargin) * 501 s->bidir = s->len < (current_vp->width - current_vp->xmargin) *
422 (100 + lcd_scroll_info.bidir_limit) / 100; 502 (100 + lcd_scroll_info.bidir_limit) / 100;
423 } 503 }
424 else 504 else
@@ -432,16 +512,15 @@ void lcd_puts_scroll_offset(int x, int y, const unsigned char *string,
432 } 512 }
433 513
434 end = strchr(s->line, '\0'); 514 end = strchr(s->line, '\0');
435 strncpy(end, string, utf8seek(s->line, LCD_WIDTH)); 515 strncpy(end, string, utf8seek(s->line, current_vp->width));
436 516
517 s->vp = current_vp;
518 s->y = y;
437 s->offset = offset; 519 s->offset = offset;
438 s->startx = xmargin + x; 520 s->startx = current_vp->xmargin + x;
439 s->backward = false; 521 s->backward = false;
440 lcd_scroll_info.lines |= (1<<y); 522 lcd_scroll_info.lines++;
441 } 523 }
442 else
443 /* force a bit switch-off since it doesn't scroll */
444 lcd_scroll_info.lines &= ~(1<<y);
445} 524}
446 525
447void lcd_scroll_fn(void) 526void lcd_scroll_fn(void)
@@ -450,27 +529,25 @@ void lcd_scroll_fn(void)
450 int index; 529 int index;
451 int xpos, ypos; 530 int xpos, ypos;
452 bool update; 531 bool update;
532 struct viewport* old_vp = current_vp;
453 533
454 update = false; 534 update = false;
455 for (index = 0; index < LCD_SCROLLABLE_LINES; index++) 535 for ( index = 0; index < lcd_scroll_info.lines; index++ ) {
456 {
457 /* really scroll? */
458 if ((lcd_scroll_info.lines & (1 << index)) == 0)
459 continue;
460
461 s = &lcd_scroll_info.scroll[index]; 536 s = &lcd_scroll_info.scroll[index];
462 537
463 /* check pause */ 538 /* check pause */
464 if (TIME_BEFORE(current_tick, s->start_tick)) 539 if (TIME_BEFORE(current_tick, s->start_tick))
465 continue; 540 continue;
466 541
542 lcd_set_viewport(s->vp);
543
467 if (s->backward) 544 if (s->backward)
468 s->offset--; 545 s->offset--;
469 else 546 else
470 s->offset++; 547 s->offset++;
471 548
472 xpos = s->startx; 549 xpos = s->startx;
473 ypos = ymargin + index; 550 ypos = current_vp->ymargin + s->y;
474 551
475 if (s->bidir) /* scroll bidirectional */ 552 if (s->bidir) /* scroll bidirectional */
476 { 553 {
@@ -480,9 +557,9 @@ void lcd_scroll_fn(void)
480 s->backward = false; 557 s->backward = false;
481 s->start_tick = current_tick + lcd_scroll_info.delay * 2; 558 s->start_tick = current_tick + lcd_scroll_info.delay * 2;
482 } 559 }
483 if (s->offset >= s->len - (LCD_WIDTH - xpos)) { 560 if (s->offset >= s->len - (current_vp->width - xpos)) {
484 /* at end of line */ 561 /* at end of line */
485 s->offset = s->len - (LCD_WIDTH - xpos); 562 s->offset = s->len - (current_vp->width - xpos);
486 s->backward = true; 563 s->backward = true;
487 s->start_tick = current_tick + lcd_scroll_info.delay * 2; 564 s->start_tick = current_tick + lcd_scroll_info.delay * 2;
488 } 565 }
@@ -497,6 +574,8 @@ void lcd_scroll_fn(void)
497 update = true; 574 update = true;
498 } 575 }
499 576
577 lcd_set_viewport(old_vp);
578
500 if (lcd_cursor.enabled) 579 if (lcd_cursor.enabled)
501 { 580 {
502 if (--lcd_cursor.downcount <= 0) 581 if (--lcd_cursor.downcount <= 0)