diff options
Diffstat (limited to 'firmware/drivers/lcd.c')
-rw-r--r-- | firmware/drivers/lcd.c | 106 |
1 files changed, 95 insertions, 11 deletions
diff --git a/firmware/drivers/lcd.c b/firmware/drivers/lcd.c index f43f925375..5b8303114c 100644 --- a/firmware/drivers/lcd.c +++ b/firmware/drivers/lcd.c | |||
@@ -19,6 +19,7 @@ | |||
19 | 19 | ||
20 | #include "config.h" | 20 | #include "config.h" |
21 | #include "lcd.h" | 21 | #include "lcd.h" |
22 | #include "kernel.h" | ||
22 | #include <string.h> | 23 | #include <string.h> |
23 | #include <stdlib.h> | 24 | #include <stdlib.h> |
24 | 25 | ||
@@ -396,7 +397,13 @@ static unsigned char ones[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
396 | static char fonts[] = { 6,8,12 }; | 397 | static char fonts[] = { 6,8,12 }; |
397 | static char fontheight[] = { 8,12,16 }; | 398 | static char fontheight[] = { 8,12,16 }; |
398 | 399 | ||
399 | #ifndef SIMULATOR | 400 | #ifdef SIMULATOR |
401 | |||
402 | void lcd_init (void) | ||
403 | { | ||
404 | create_thread(scroll_thread, scroll_stack, sizeof(scroll_stack)); | ||
405 | } | ||
406 | #else | ||
400 | 407 | ||
401 | /* | 408 | /* |
402 | * Initialize LCD | 409 | * Initialize LCD |
@@ -418,6 +425,7 @@ void lcd_init (void) | |||
418 | 425 | ||
419 | lcd_clear_display(); | 426 | lcd_clear_display(); |
420 | lcd_update(); | 427 | lcd_update(); |
428 | create_thread(scroll_thread, scroll_stack, sizeof(scroll_stack)); | ||
421 | } | 429 | } |
422 | 430 | ||
423 | /* | 431 | /* |
@@ -476,8 +484,8 @@ void lcd_puts(int x, int y, char *str) | |||
476 | as otherwise it'll wrap. The real target doesn't wrap. */ | 484 | as otherwise it'll wrap. The real target doesn't wrap. */ |
477 | 485 | ||
478 | char buffer[12]; | 486 | char buffer[12]; |
479 | if((x < 11) && (strlen(str) > (11-x)) ) { | 487 | if(strlen(str)+x > 11 ) { |
480 | memcpy(str, buffer, 11-x); | 488 | strncpy(buffer, str, sizeof buffer); |
481 | buffer[11-x]=0; | 489 | buffer[11-x]=0; |
482 | str = buffer; | 490 | str = buffer; |
483 | } | 491 | } |
@@ -506,15 +514,8 @@ void lcd_putsxy(int x, int y, char *str, int thisfont) | |||
506 | int lcd_x = x; | 514 | int lcd_x = x; |
507 | int lcd_y = y; | 515 | int lcd_y = y; |
508 | 516 | ||
509 | while ((ch = *str++) != '\0') | 517 | while (((ch = *str++) != '\0') && (lcd_x + nx < LCD_WIDTH)) |
510 | { | 518 | { |
511 | if (ch == '\n' || lcd_x + nx > LCD_WIDTH) | ||
512 | { | ||
513 | /* Wrap to next line */ | ||
514 | lcd_x = x; | ||
515 | lcd_y += ny; | ||
516 | } | ||
517 | |||
518 | if (lcd_y + ny > LCD_HEIGHT) | 519 | if (lcd_y + ny > LCD_HEIGHT) |
519 | return; | 520 | return; |
520 | 521 | ||
@@ -745,6 +746,89 @@ void lcd_getfontsize(unsigned int font, int *width, int *height) | |||
745 | /* no LCD defined, no code to use */ | 746 | /* no LCD defined, no code to use */ |
746 | #endif | 747 | #endif |
747 | 748 | ||
749 | |||
750 | struct scrollinfo { | ||
751 | char text[128]; | ||
752 | int textlen; | ||
753 | char offset; | ||
754 | char xpos; | ||
755 | char startx; | ||
756 | char starty; | ||
757 | char space; | ||
758 | }; | ||
759 | |||
760 | static void scroll_thread(void); | ||
761 | static char scroll_stack[0x100]; | ||
762 | static char scroll_speed = 10; /* updates per second */ | ||
763 | |||
764 | static struct scrollinfo scroll; /* only one scroll line at the moment */ | ||
765 | static bool run_scroll = false; | ||
766 | |||
767 | void lcd_puts_scroll(int x, int y, char* string ) | ||
768 | { | ||
769 | struct scrollinfo* s = &scroll; | ||
770 | #ifdef HAVE_LCD_CHARCELLS | ||
771 | s->space = 11 - x; | ||
772 | #else | ||
773 | int width, height; | ||
774 | lcd_getfontsize(font, &width, &height); | ||
775 | s->space = (LCD_WIDTH - xmargin - x) / width; | ||
776 | #endif | ||
777 | s->offset=0; | ||
778 | s->xpos=x; | ||
779 | s->startx=x; | ||
780 | s->starty=y; | ||
781 | s->textlen = strlen(string); | ||
782 | strncpy(s->text,string,sizeof s->text); | ||
783 | s->text[sizeof s->text - 1] = 0; | ||
784 | |||
785 | run_scroll = true; | ||
786 | lcd_puts(s->xpos,y,s->text + s->offset); | ||
787 | lcd_update(); | ||
788 | } | ||
789 | |||
790 | void lcd_stop_scroll(void) | ||
791 | { | ||
792 | struct scrollinfo* s = &scroll; | ||
793 | run_scroll = false; | ||
794 | |||
795 | /* restore scrolled row */ | ||
796 | lcd_puts(s->startx,s->starty,s->text); | ||
797 | lcd_update(); | ||
798 | } | ||
799 | |||
800 | void lcd_scroll_speed(int speed) | ||
801 | { | ||
802 | scroll_speed = speed; | ||
803 | } | ||
804 | |||
805 | static void scroll_thread(void) | ||
806 | { | ||
807 | struct scrollinfo* s = &scroll; | ||
808 | while ( 1 ) { | ||
809 | if ( !run_scroll ) { | ||
810 | yield(); | ||
811 | continue; | ||
812 | } | ||
813 | lcd_puts(s->xpos,s->starty,s->text + s->offset); | ||
814 | if ( s->textlen - s->offset < s->space ) | ||
815 | lcd_puts(s->startx + s->textlen - s->offset, s->starty," "); | ||
816 | lcd_update(); | ||
817 | |||
818 | if ( s->xpos > s->startx ) | ||
819 | s->xpos--; | ||
820 | else | ||
821 | s->offset++; | ||
822 | |||
823 | if (s->offset > s->textlen) { | ||
824 | s->offset=0; | ||
825 | s->xpos = s->space-1; | ||
826 | } | ||
827 | sleep(HZ/scroll_speed); | ||
828 | } | ||
829 | } | ||
830 | |||
831 | |||
748 | /* ----------------------------------------------------------------- | 832 | /* ----------------------------------------------------------------- |
749 | * local variables: | 833 | * local variables: |
750 | * eval: (load-file "../rockbox-mode.el") | 834 | * eval: (load-file "../rockbox-mode.el") |