summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTeruaki Kawashima <teru@rockbox.org>2009-10-03 13:53:49 +0000
committerTeruaki Kawashima <teru@rockbox.org>2009-10-03 13:53:49 +0000
commitccf2078150e9ccd9edafeccd209f93ca60a7ada5 (patch)
treed8d1a86218379ac93cce6b318d2216a6335efadf
parentc78e9de35abeed6bec34979ab623c0b6a0de6863 (diff)
downloadrockbox-ccf2078150e9ccd9edafeccd209f93ca60a7ada5.tar.gz
rockbox-ccf2078150e9ccd9edafeccd209f93ca60a7ada5.zip
Fix FS#10597: Loadable keyboard layout rendered incorrectly.
Also fix out of bounds access to kbd_buf. Reset cursor position in keyboard when loading new virtual keyboard for the case size is different from previous one. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@22892 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/recorder/keyboard.c82
1 files changed, 43 insertions, 39 deletions
diff --git a/apps/recorder/keyboard.c b/apps/recorder/keyboard.c
index 2911f94931..ddfbcf4585 100644
--- a/apps/recorder/keyboard.c
+++ b/apps/recorder/keyboard.c
@@ -98,6 +98,7 @@ struct keyboard_parameters
98 int nchars; 98 int nchars;
99 int font_w; 99 int font_w;
100 int font_h; 100 int font_h;
101 int text_w;
101 struct font* font; 102 struct font* font;
102 int curfont; 103 int curfont;
103 int main_x; 104 int main_x;
@@ -144,6 +145,12 @@ int load_kbd(unsigned char* filename)
144 int i = 0; 145 int i = 0;
145 unsigned char buf[4]; 146 unsigned char buf[4];
146 147
148 FOR_NB_SCREENS(l)
149 {
150 struct keyboard_parameters *pm = &kbd_param[l];
151 pm->x = pm->y = pm->page = 0;
152 }
153
147 if (filename == NULL) 154 if (filename == NULL)
148 { 155 {
149 kbd_loaded = false; 156 kbd_loaded = false;
@@ -159,6 +166,7 @@ int load_kbd(unsigned char* filename)
159 /* check how many bytes to read for this character */ 166 /* check how many bytes to read for this character */
160 static const unsigned char sizes[4] = { 0x80, 0xe0, 0xf0, 0xf5 }; 167 static const unsigned char sizes[4] = { 0x80, 0xe0, 0xf0, 0xf5 };
161 size_t count; 168 size_t count;
169 unsigned short ch;
162 170
163 for (count = 0; count < ARRAYLEN(sizes); count++) 171 for (count = 0; count < ARRAYLEN(sizes); count++)
164 { 172 {
@@ -176,11 +184,11 @@ int load_kbd(unsigned char* filename)
176 return 1; 184 return 1;
177 } 185 }
178 186
187 utf8decode(buf, &ch);
179 FOR_NB_SCREENS(l) 188 FOR_NB_SCREENS(l)
180 utf8decode(buf, &kbd_param[l].kbd_buf[i]); 189 kbd_param[l].kbd_buf[i] = ch;
181 190
182 if (kbd_param[0].kbd_buf[i] != 0xFEFF && 191 if (ch != 0xFEFF && ch != '\r') /*skip BOM & carriage returns */
183 kbd_param[0].kbd_buf[i] != '\r') /*skip BOM & carriage returns */
184 { 192 {
185 i++; 193 i++;
186 } 194 }
@@ -276,9 +284,10 @@ static void kbd_delchar(unsigned char* text, int* editpos)
276} 284}
277 285
278/* Lookup k value based on state of param (pm) */ 286/* Lookup k value based on state of param (pm) */
279static int get_param_k(const struct keyboard_parameters *pm) 287static unsigned short get_kbd_ch(const struct keyboard_parameters *pm)
280{ 288{
281 return (pm->page*pm->lines + pm->y)*pm->max_chars + pm->x; 289 int k = (pm->page*pm->lines + pm->y)*pm->max_chars + pm->x;
290 return (k < pm->nchars)? pm->kbd_buf[k]: ' ';
282} 291}
283 292
284int kbd_input(char* text, int buflen) 293int kbd_input(char* text, int buflen)
@@ -291,7 +300,6 @@ int kbd_input(char* text, int buflen)
291 struct keyboard_parameters * const param = kbd_param; 300 struct keyboard_parameters * const param = kbd_param;
292#endif 301#endif
293 int l; /* screen loop variable */ 302 int l; /* screen loop variable */
294 int text_w = 0;
295 int editpos; /* Edit position on all screens */ 303 int editpos; /* Edit position on all screens */
296 const int statusbar_size = 0; 304 const int statusbar_size = 0;
297 unsigned short ch; 305 unsigned short ch;
@@ -406,9 +414,12 @@ int kbd_input(char* text, int buflen)
406 /* find max width of keyboard glyphs */ 414 /* find max width of keyboard glyphs */
407 for (i = 0; i < pm->nchars; i++) 415 for (i = 0; i < pm->nchars; i++)
408 { 416 {
409 w = font_get_width(pm->font, pm->kbd_buf[i]); 417 if (pm->kbd_buf[i] != '\n')
410 if ( w > pm->font_w ) 418 {
411 pm->font_w = w; 419 w = font_get_width(pm->font, pm->kbd_buf[i]);
420 if ( w > pm->font_w )
421 pm->font_w = w;
422 }
412 } 423 }
413 424
414 /* Since we're going to be adding spaces, make sure that we check 425 /* Since we're going to be adding spaces, make sure that we check
@@ -424,16 +435,17 @@ int kbd_input(char* text, int buflen)
424 struct screen *sc = &screens[l]; 435 struct screen *sc = &screens[l];
425 int i = 0; 436 int i = 0;
426 437
438 pm->max_chars = sc->getwidth() / pm->font_w;
439
427 /* Pad lines with spaces */ 440 /* Pad lines with spaces */
428 while (i < pm->nchars) 441 while (i < pm->nchars)
429 { 442 {
430 if (pm->kbd_buf[i] == '\n') 443 if (pm->kbd_buf[i] == '\n')
431 { 444 {
432 int k = sc->getwidth() / pm->font_w 445 int k = pm->max_chars - i % ( pm->max_chars ) - 1;
433 - i % ( sc->getwidth() / pm->font_w ) - 1;
434 int j; 446 int j;
435 447
436 if (k == sc->getwidth() / pm->font_w - 1) 448 if (k == pm->max_chars - 1)
437 { 449 {
438 pm->nchars--; 450 pm->nchars--;
439 451
@@ -471,27 +483,24 @@ int kbd_input(char* text, int buflen)
471 } 483 }
472 484
473 /* Find max width for text string */ 485 /* Find max width for text string */
474 utf8 = text;
475 FOR_NB_SCREENS(l) 486 FOR_NB_SCREENS(l)
476 { 487 {
477 struct keyboard_parameters *pm = &param[l]; 488 struct keyboard_parameters *pm = &param[l];
478 struct screen *sc = &screens[l]; 489 struct screen *sc = &screens[l];
479 490
480 text_w = pm->font_w; 491 pm->text_w = pm->font_w;
481 492
493 utf8 = text;
482 while (*utf8) 494 while (*utf8)
483 { 495 {
484 int w = font_get_width(pm->font, ch); 496 int w;
485 utf8 = (unsigned char*)utf8decode(utf8, &ch); 497 utf8 = (unsigned char*)utf8decode(utf8, &ch);
486 498 w = font_get_width(pm->font, ch);
487 if (w > text_w) 499 if (w > pm->text_w)
488 text_w = w; 500 pm->text_w = w;
489 } 501 }
490 502
491 pm->max_chars_text = sc->getwidth() / text_w - 2; 503 pm->max_chars_text = sc->getwidth() / pm->text_w - 2;
492
493 /* Calculate keyboard grid size */
494 pm->max_chars = sc->getwidth() / pm->font_w;
495 504
496 if (!kbd_loaded) 505 if (!kbd_loaded)
497 { 506 {
@@ -644,6 +653,7 @@ int kbd_input(char* text, int buflen)
644 struct keyboard_parameters *pm = &param[l]; 653 struct keyboard_parameters *pm = &param[l];
645 struct screen *sc = &screens[l]; 654 struct screen *sc = &screens[l];
646 int i = 0, j = 0; 655 int i = 0, j = 0;
656 int text_w = pm->text_w;
647 657
648 /* Clear text area one pixel above separator line so any overdraw 658 /* Clear text area one pixel above separator line so any overdraw
649 doesn't collide */ 659 doesn't collide */
@@ -662,8 +672,6 @@ int kbd_input(char* text, int buflen)
662 pm->leftpos = editpos - pm->curpos; 672 pm->leftpos = editpos - pm->curpos;
663 utf8 = text + utf8seek(text, pm->leftpos); 673 utf8 = text + utf8seek(text, pm->leftpos);
664 674
665 text_w = pm->font_w;
666
667 while (*utf8 && i < pm->max_chars_text) 675 while (*utf8 && i < pm->max_chars_text)
668 { 676 {
669 outline[j++] = *utf8++; 677 outline[j++] = *utf8++;
@@ -780,7 +788,6 @@ int kbd_input(char* text, int buflen)
780 788
781 case ACTION_KBD_PAGE_FLIP: 789 case ACTION_KBD_PAGE_FLIP:
782 { 790 {
783 int k;
784#ifdef KBD_MORSE_INPUT 791#ifdef KBD_MORSE_INPUT
785 if (morse_mode) 792 if (morse_mode)
786 break; 793 break;
@@ -788,8 +795,8 @@ int kbd_input(char* text, int buflen)
788 if (++pm->page >= pm->pages) 795 if (++pm->page >= pm->pages)
789 pm->page = 0; 796 pm->page = 0;
790 797
791 k = get_param_k(pm); 798 ch = get_kbd_ch(pm);
792 kbd_spellchar(pm->kbd_buf[k]); 799 kbd_spellchar(ch);
793 break; 800 break;
794 } 801 }
795 802
@@ -843,7 +850,6 @@ int kbd_input(char* text, int buflen)
843 else 850 else
844#endif /* KBD_MODES */ 851#endif /* KBD_MODES */
845 { 852 {
846 int k;
847#ifdef KBD_MORSE_INPUT 853#ifdef KBD_MORSE_INPUT
848 if (morse_mode) 854 if (morse_mode)
849 break; 855 break;
@@ -858,8 +864,8 @@ int kbd_input(char* text, int buflen)
858 pm->x = 0; 864 pm->x = 0;
859 } 865 }
860 866
861 k = get_param_k(pm); 867 ch = get_kbd_ch(pm);
862 kbd_spellchar(pm->kbd_buf[k]); 868 kbd_spellchar(ch);
863 } 869 }
864 break; 870 break;
865 871
@@ -888,7 +894,6 @@ int kbd_input(char* text, int buflen)
888 else 894 else
889#endif /* KBD_MODES */ 895#endif /* KBD_MODES */
890 { 896 {
891 int k;
892#ifdef KBD_MORSE_INPUT 897#ifdef KBD_MORSE_INPUT
893 if (morse_mode) 898 if (morse_mode)
894 break; 899 break;
@@ -903,8 +908,8 @@ int kbd_input(char* text, int buflen)
903 pm->x = pm->max_chars - 1; 908 pm->x = pm->max_chars - 1;
904 } 909 }
905 910
906 k = get_param_k(pm); 911 ch = get_kbd_ch(pm);
907 kbd_spellchar(pm->kbd_buf[k]); 912 kbd_spellchar(ch);
908 } 913 }
909 break; 914 break;
910 915
@@ -946,8 +951,8 @@ int kbd_input(char* text, int buflen)
946 if (!pm->line_edit) 951 if (!pm->line_edit)
947#endif 952#endif
948 { 953 {
949 int k = get_param_k(pm); 954 ch = get_kbd_ch(pm);
950 kbd_spellchar(pm->kbd_buf[k]); 955 kbd_spellchar(ch);
951 } 956 }
952 break; 957 break;
953 958
@@ -989,8 +994,8 @@ int kbd_input(char* text, int buflen)
989 if (!pm->line_edit) 994 if (!pm->line_edit)
990#endif 995#endif
991 { 996 {
992 int k = get_param_k(pm); 997 ch = get_kbd_ch(pm);
993 kbd_spellchar(pm->kbd_buf[k]); 998 kbd_spellchar(ch);
994 } 999 }
995 break; 1000 break;
996 1001
@@ -1061,8 +1066,7 @@ int kbd_input(char* text, int buflen)
1061#endif /* KBD_MODES */ 1066#endif /* KBD_MODES */
1062 { 1067 {
1063 /* find input char */ 1068 /* find input char */
1064 int k = get_param_k(pm); 1069 ch = get_kbd_ch(pm);
1065 ch = (k < pm->nchars) ? pm->kbd_buf[k] : ' ';
1066 1070
1067 /* check for hangul input */ 1071 /* check for hangul input */
1068 if (ch >= 0x3131 && ch <= 0x3163) 1072 if (ch >= 0x3131 && ch <= 0x3163)