summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTeruaki Kawashima <teru@rockbox.org>2010-02-25 06:40:36 +0000
committerTeruaki Kawashima <teru@rockbox.org>2010-02-25 06:40:36 +0000
commit62e6a2f9d8f11a4b46c0aa37679c77ff0849dec2 (patch)
tree7e0243a62ce4213a9f378ccf5a2b912cff6efc34
parent51bc09e88ecb88049274006e2d5b7d8df771761c (diff)
downloadrockbox-62e6a2f9d8f11a4b46c0aa37679c77ff0849dec2.tar.gz
rockbox-62e6a2f9d8f11a4b46c0aa37679c77ff0849dec2.zip
keyboard: accept FS#11047 partially with some modifications. make some parts in switch() in kbd_input() to separate functions.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@24902 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/recorder/keyboard.c453
1 files changed, 225 insertions, 228 deletions
diff --git a/apps/recorder/keyboard.c b/apps/recorder/keyboard.c
index 060393c269..3df3142897 100644
--- a/apps/recorder/keyboard.c
+++ b/apps/recorder/keyboard.c
@@ -92,6 +92,10 @@
92#define KBD_TOGGLE_INPUT 92#define KBD_TOGGLE_INPUT
93#endif 93#endif
94 94
95#define CHANGED_PICKER 1
96#define CHANGED_CURSOR 2
97#define CHANGED_TEXT 3
98
95struct keyboard_parameters 99struct keyboard_parameters
96{ 100{
97 unsigned short kbd_buf[KBD_BUF_SIZE]; 101 unsigned short kbd_buf[KBD_BUF_SIZE];
@@ -136,6 +140,7 @@ struct edit_state
136 unsigned char morse_code; 140 unsigned char morse_code;
137 int morse_tick; 141 int morse_tick;
138#endif 142#endif
143 int changed;
139}; 144};
140 145
141static struct keyboard_parameters kbd_param[NB_SCREENS]; 146static struct keyboard_parameters kbd_param[NB_SCREENS];
@@ -232,30 +237,19 @@ int load_kbd(unsigned char* filename)
232 return 0; 237 return 0;
233} 238}
234 239
235/* helper function to spell a char if voice UI is enabled */ 240/* helper function to spell a char */
236static void kbd_spellchar(unsigned short c) 241static void kbd_spellchar(unsigned short c)
237{ 242{
238 if (global_settings.talk_menu) /* voice UI? */ 243 unsigned char tmp[5];
239 { 244 /* store char to pass to talk_spell */
240 unsigned char tmp[5]; 245 unsigned char* utf8 = utf8encode(c, tmp);
241 /* store char to pass to talk_spell */ 246 *utf8 = 0;
242 unsigned char* utf8 = utf8encode(c, tmp);
243 *utf8 = 0;
244 247
245 if (c == ' ') 248 if (c == ' ')
246 talk_id(VOICE_BLANK, false); 249 talk_id(VOICE_BLANK, false);
247 else 250 else
248 talk_spell(tmp, false); 251 talk_spell(tmp, false);
249 }
250}
251
252#ifdef KBD_MODES
253static void say_edit(void)
254{
255 if (global_settings.talk_menu)
256 talk_id(VOICE_EDIT, false);
257} 252}
258#endif
259 253
260static void kbd_inschar(struct edit_state *state, unsigned short ch) 254static void kbd_inschar(struct edit_state *state, unsigned short ch)
261{ 255{
@@ -274,6 +268,7 @@ static void kbd_inschar(struct edit_state *state, unsigned short ch)
274 memmove(utf8 + j, utf8, len - i + 1); 268 memmove(utf8 + j, utf8, len - i + 1);
275 memcpy(utf8, tmp, j); 269 memcpy(utf8, tmp, j);
276 state->editpos++; 270 state->editpos++;
271 state->changed = CHANGED_TEXT;
277 } 272 }
278} 273}
279 274
@@ -290,6 +285,7 @@ static void kbd_delchar(struct edit_state *state)
290 utf8 = state->text + i; 285 utf8 = state->text + i;
291 j = utf8seek(utf8, 1); 286 j = utf8seek(utf8, 1);
292 memmove(utf8, utf8 + j, len - i - j + 1); 287 memmove(utf8, utf8 + j, len - i - j + 1);
288 state->changed = CHANGED_TEXT;
293 } 289 }
294} 290}
295 291
@@ -306,6 +302,12 @@ static void kbd_draw_picker(struct keyboard_parameters *pm,
306 struct screen *sc, struct edit_state *state); 302 struct screen *sc, struct edit_state *state);
307static void kbd_draw_edit_line(struct keyboard_parameters *pm, 303static void kbd_draw_edit_line(struct keyboard_parameters *pm,
308 struct screen *sc, struct edit_state *state); 304 struct screen *sc, struct edit_state *state);
305static void kbd_insert_selected(struct keyboard_parameters *pm,
306 struct edit_state *state);
307static void kbd_backspace(struct edit_state *state);
308static void kbd_move_cursor(struct edit_state *state, int dir);
309static void kbd_move_picker_vertical(struct keyboard_parameters *pm,
310 struct edit_state *state, int dir);
309 311
310int kbd_input(char* text, int buflen) 312int kbd_input(char* text, int buflen)
311{ 313{
@@ -345,6 +347,7 @@ int kbd_input(char* text, int buflen)
345 state.morse_reading = false; 347 state.morse_reading = false;
346#endif 348#endif
347 state.hangul = false; 349 state.hangul = false;
350 state.changed = 0;
348 351
349 if (!kbd_loaded) 352 if (!kbd_loaded)
350 { 353 {
@@ -441,8 +444,6 @@ int kbd_input(char* text, int buflen)
441 kbd_draw_edit_line(pm, sc, &state); 444 kbd_draw_edit_line(pm, sc, &state);
442 } 445 }
443 446
444 state.cur_blink = !state.cur_blink;
445
446#ifdef HAVE_BUTTONBAR 447#ifdef HAVE_BUTTONBAR
447 /* draw the button bar */ 448 /* draw the button bar */
448 gui_buttonbar_set(&buttonbar, "Shift", "OK", "Del"); 449 gui_buttonbar_set(&buttonbar, "Shift", "OK", "Del");
@@ -452,6 +453,8 @@ int kbd_input(char* text, int buflen)
452 FOR_NB_SCREENS(l) 453 FOR_NB_SCREENS(l)
453 screens[l].update(); 454 screens[l].update();
454 455
456 state.cur_blink = !state.cur_blink;
457
455 button = get_action( 458 button = get_action(
456#ifdef HAVE_MORSE_INPUT 459#ifdef HAVE_MORSE_INPUT
457 state.morse_mode? CONTEXT_MORSE_INPUT: 460 state.morse_mode? CONTEXT_MORSE_INPUT:
@@ -507,25 +510,9 @@ int kbd_input(char* text, int buflen)
507 if (++pm->page >= pm->pages) 510 if (++pm->page >= pm->pages)
508 pm->page = 0; 511 pm->page = 0;
509 512
510 ch = get_kbd_ch(pm); 513 state.changed = CHANGED_PICKER;
511 kbd_spellchar(ch);
512 break; 514 break;
513 515
514#if defined(HAVE_MORSE_INPUT) && defined(KBD_TOGGLE_INPUT)
515 case ACTION_KBD_MORSE_INPUT:
516 state.morse_mode = !state.morse_mode;
517
518 FOR_NB_SCREENS(l)
519 {
520 struct keyboard_parameters *pm = &param[l];
521 int y = pm->main_y;
522 pm->main_y = pm->old_main_y;
523 pm->old_main_y = y;
524 }
525 /* FIXME: We should talk something like Morse mode.. */
526 break;
527#endif /* HAVE_MORSE_INPUT && KBD_TOGGLE_INPUT */
528
529 case ACTION_KBD_RIGHT: 516 case ACTION_KBD_RIGHT:
530 if (++pm->x >= pm->max_chars) 517 if (++pm->x >= pm->max_chars)
531 { 518 {
@@ -537,8 +524,7 @@ int kbd_input(char* text, int buflen)
537 pm->x = 0; 524 pm->x = 0;
538 } 525 }
539 526
540 ch = get_kbd_ch(pm); 527 state.changed = CHANGED_PICKER;
541 kbd_spellchar(ch);
542 break; 528 break;
543 529
544 case ACTION_KBD_LEFT: 530 case ACTION_KBD_LEFT:
@@ -552,83 +538,33 @@ int kbd_input(char* text, int buflen)
552 pm->x = pm->max_chars - 1; 538 pm->x = pm->max_chars - 1;
553 } 539 }
554 540
555 ch = get_kbd_ch(pm); 541 state.changed = CHANGED_PICKER;
556 kbd_spellchar(ch);
557 break; 542 break;
558 543
559 case ACTION_KBD_DOWN: 544 case ACTION_KBD_DOWN:
560#ifdef HAVE_MORSE_INPUT 545 kbd_move_picker_vertical(pm, &state, 1);
561 if (state.morse_mode)
562 {
563#ifdef KBD_MODES
564 pm->line_edit = !pm->line_edit;
565 if (pm->line_edit)
566 say_edit();
567#endif
568 break;
569 }
570#endif /* HAVE_MORSE_INPUT */
571#ifdef KBD_MODES
572 if (pm->line_edit)
573 {
574 pm->y = 0;
575 pm->line_edit = false;
576 }
577 else if (++pm->y >= pm->lines)
578 {
579 pm->line_edit = true;
580 say_edit();
581 }
582#else
583 if (++pm->y >= pm->lines)
584 pm->y = 0;
585#endif
586#ifdef KBD_MODES
587 if (!pm->line_edit)
588#endif
589 {
590 ch = get_kbd_ch(pm);
591 kbd_spellchar(ch);
592 }
593 break; 546 break;
594 547
595 case ACTION_KBD_UP: 548 case ACTION_KBD_UP:
549 kbd_move_picker_vertical(pm, &state, -1);
550 break;
551
596#ifdef HAVE_MORSE_INPUT 552#ifdef HAVE_MORSE_INPUT
597 if (state.morse_mode) 553#ifdef KBD_TOGGLE_INPUT
598 { 554 case ACTION_KBD_MORSE_INPUT:
599#ifdef KBD_MODES 555 state.morse_mode = !state.morse_mode;
600 pm->line_edit = !pm->line_edit; 556
601 if (pm->line_edit) 557 FOR_NB_SCREENS(l)
602 say_edit();
603#endif
604 break;
605 }
606#endif /* HAVE_MORSE_INPUT */
607#ifdef KBD_MODES
608 if (pm->line_edit)
609 {
610 pm->y = pm->lines - 1;
611 pm->line_edit = false;
612 }
613 else if (--pm->y < 0)
614 {
615 pm->line_edit = true;
616 say_edit();
617 }
618#else
619 if (--pm->y < 0)
620 pm->y = pm->lines - 1;
621#endif
622#ifdef KBD_MODES
623 if (!pm->line_edit)
624#endif
625 { 558 {
626 ch = get_kbd_ch(pm); 559 struct keyboard_parameters *pm = &param[l];
627 kbd_spellchar(ch); 560 int y = pm->main_y;
561 pm->main_y = pm->old_main_y;
562 pm->old_main_y = y;
628 } 563 }
564 /* FIXME: We should talk something like Morse mode.. */
629 break; 565 break;
566#endif /* KBD_TOGGLE_INPUT */
630 567
631#ifdef HAVE_MORSE_INPUT
632 case ACTION_KBD_MORSE_SELECT: 568 case ACTION_KBD_MORSE_SELECT:
633 if (state.morse_mode && state.morse_reading) 569 if (state.morse_mode && state.morse_reading)
634 { 570 {
@@ -653,133 +589,19 @@ int kbd_input(char* text, int buflen)
653 } 589 }
654 else 590 else
655#endif /* HAVE_MORSE_INPUT */ 591#endif /* HAVE_MORSE_INPUT */
656 { 592 kbd_insert_selected(pm, &state);
657 /* inserts the selected char */
658 /* find input char */
659 ch = get_kbd_ch(pm);
660
661 /* check for hangul input */
662 if (ch >= 0x3131 && ch <= 0x3163)
663 {
664 unsigned short tmp;
665
666 if (!state.hangul)
667 {
668 state.hlead = state.hvowel = state.htail = 0;
669 state.hangul = true;
670 }
671
672 if (!state.hvowel)
673 {
674 state.hvowel = ch;
675 }
676 else if (!state.htail)
677 {
678 state.htail = ch;
679 }
680 else
681 {
682 /* previous hangul complete */
683 /* check whether tail is actually lead of next char */
684 tmp = hangul_join(state.htail, ch, 0);
685
686 if (tmp != 0xfffd)
687 {
688 tmp = hangul_join(state.hlead, state.hvowel, 0);
689 kbd_delchar(&state);
690 kbd_inschar(&state, tmp);
691 /* insert dummy char */
692 kbd_inschar(&state, ' ');
693 state.hlead = state.htail;
694 state.hvowel = ch;
695 state.htail = 0;
696 }
697 else
698 {
699 state.hvowel = state.htail = 0;
700 state.hlead = ch;
701 }
702 }
703
704 /* combine into hangul */
705 tmp = hangul_join(state.hlead, state.hvowel, state.htail);
706
707 if (tmp != 0xfffd)
708 {
709 kbd_delchar(&state);
710 ch = tmp;
711 }
712 else
713 {
714 state.hvowel = state.htail = 0;
715 state.hlead = ch;
716 }
717 }
718 else
719 {
720 state.hangul = false;
721 }
722
723 /* insert char */
724 kbd_inschar(&state, ch);
725
726 if (global_settings.talk_menu) /* voice UI? */
727 talk_spell(state.text, false); /* speak revised text */
728 }
729 break; 593 break;
730 594
731 case ACTION_KBD_BACKSPACE: 595 case ACTION_KBD_BACKSPACE:
732 if (state.hangul) 596 kbd_backspace(&state);
733 {
734 if (state.htail)
735 state.htail = 0;
736 else if (state.hvowel)
737 state.hvowel = 0;
738 else
739 state.hangul = false;
740 }
741
742 kbd_delchar(&state);
743
744 if (state.hangul)
745 {
746 if (state.hvowel)
747 ch = hangul_join(state.hlead, state.hvowel, state.htail);
748 else
749 ch = state.hlead;
750 kbd_inschar(&state, ch);
751 }
752
753 if (global_settings.talk_menu) /* voice UI? */
754 talk_spell(state.text, false); /* speak revised text */
755 break; 597 break;
756 598
757 case ACTION_KBD_CURSOR_RIGHT: 599 case ACTION_KBD_CURSOR_RIGHT:
758 state.hangul = false; 600 kbd_move_cursor(&state, 1);
759
760 if (state.editpos < state.len_utf8)
761 {
762 int c = utf8seek(state.text, ++state.editpos);
763 kbd_spellchar(state.text[c]);
764 }
765#if CONFIG_CODEC == SWCODEC
766 else if (global_settings.talk_menu)
767 pcmbuf_beep(1000, 150, 1500);
768#endif
769 break; 601 break;
770 602
771 case ACTION_KBD_CURSOR_LEFT: 603 case ACTION_KBD_CURSOR_LEFT:
772 state.hangul = false; 604 kbd_move_cursor(&state, -1);
773
774 if (state.editpos > 0)
775 {
776 int c = utf8seek(state.text, --state.editpos);
777 kbd_spellchar(state.text[c]);
778 }
779#if CONFIG_CODEC == SWCODEC
780 else if (global_settings.talk_menu)
781 pcmbuf_beep(1000, 150, 1500);
782#endif
783 break; 605 break;
784 606
785 case ACTION_NONE: 607 case ACTION_NONE:
@@ -805,9 +627,6 @@ int kbd_input(char* text, int buflen)
805 /* turn off hangul input */ 627 /* turn off hangul input */
806 state.hangul = false; 628 state.hangul = false;
807 kbd_inschar(&state, morse_alphabets[j]); 629 kbd_inschar(&state, morse_alphabets[j]);
808
809 if (global_settings.talk_menu) /* voice UI? */
810 talk_spell(state.text, false); /* speak revised text */
811 } 630 }
812#endif /* HAVE_MORSE_INPUT */ 631#endif /* HAVE_MORSE_INPUT */
813 break; 632 break;
@@ -826,6 +645,34 @@ int kbd_input(char* text, int buflen)
826 { 645 {
827 state.cur_blink = true; 646 state.cur_blink = true;
828 } 647 }
648 if (global_settings.talk_menu) /* voice UI? */
649 {
650 if (state.changed == CHANGED_PICKER)
651 {
652#ifdef KBD_MODES
653 if (pm->line_edit)
654 {
655 talk_id(VOICE_EDIT, false);
656 }
657 else
658#endif
659#ifdef HAVE_MORSE_INPUT
660 if (!state.morse_mode)
661#endif
662 {
663 ch = get_kbd_ch(pm);
664 kbd_spellchar(ch);
665 }
666 }
667 else if (state.changed == CHANGED_CURSOR)
668 {
669 int c = utf8seek(state.text, state.editpos);
670 kbd_spellchar(state.text[c]);
671 }
672 else if (state.changed == CHANGED_TEXT)
673 talk_spell(state.text, false); /* speak revised text */
674 }
675 state.changed = 0;
829 } 676 }
830 677
831#ifdef HAVE_BUTTONBAR 678#ifdef HAVE_BUTTONBAR
@@ -1171,3 +1018,153 @@ static void kbd_draw_edit_line(struct keyboard_parameters *pm,
1171 } 1018 }
1172#endif 1019#endif
1173} 1020}
1021
1022/* inserts the selected char */
1023static void kbd_insert_selected(struct keyboard_parameters *pm,
1024 struct edit_state *state)
1025{
1026 /* find input char */
1027 unsigned short ch = get_kbd_ch(pm);
1028
1029 /* check for hangul input */
1030 if (ch >= 0x3131 && ch <= 0x3163)
1031 {
1032 unsigned short tmp;
1033
1034 if (!state->hangul)
1035 {
1036 state->hlead = state->hvowel = state->htail = 0;
1037 state->hangul = true;
1038 }
1039
1040 if (!state->hvowel)
1041 {
1042 state->hvowel = ch;
1043 }
1044 else if (!state->htail)
1045 {
1046 state->htail = ch;
1047 }
1048 else
1049 {
1050 /* previous hangul complete */
1051 /* check whether tail is actually lead of next char */
1052 tmp = hangul_join(state->htail, ch, 0);
1053
1054 if (tmp != 0xfffd)
1055 {
1056 tmp = hangul_join(state->hlead, state->hvowel, 0);
1057 kbd_delchar(state);
1058 kbd_inschar(state, tmp);
1059 /* insert dummy char */
1060 kbd_inschar(state, ' ');
1061 state->hlead = state->htail;
1062 state->hvowel = ch;
1063 state->htail = 0;
1064 }
1065 else
1066 {
1067 state->hvowel = state->htail = 0;
1068 state->hlead = ch;
1069 }
1070 }
1071
1072 /* combine into hangul */
1073 tmp = hangul_join(state->hlead, state->hvowel, state->htail);
1074
1075 if (tmp != 0xfffd)
1076 {
1077 kbd_delchar(state);
1078 ch = tmp;
1079 }
1080 else
1081 {
1082 state->hvowel = state->htail = 0;
1083 state->hlead = ch;
1084 }
1085 }
1086 else
1087 {
1088 state->hangul = false;
1089 }
1090
1091 /* insert char */
1092 kbd_inschar(state, ch);
1093}
1094
1095static void kbd_backspace(struct edit_state *state)
1096{
1097 unsigned short ch;
1098 if (state->hangul)
1099 {
1100 if (state->htail)
1101 state->htail = 0;
1102 else if (state->hvowel)
1103 state->hvowel = 0;
1104 else
1105 state->hangul = false;
1106 }
1107
1108 kbd_delchar(state);
1109
1110 if (state->hangul)
1111 {
1112 if (state->hvowel)
1113 ch = hangul_join(state->hlead, state->hvowel, state->htail);
1114 else
1115 ch = state->hlead;
1116 kbd_inschar(state, ch);
1117 }
1118}
1119
1120static void kbd_move_cursor(struct edit_state *state, int dir)
1121{
1122 state->hangul = false;
1123 state->editpos += dir;
1124
1125 if (state->editpos >= 0 && state->editpos <= state->len_utf8)
1126 {
1127 state->changed = CHANGED_CURSOR;
1128 }
1129 else
1130 {
1131 state->editpos -= dir;
1132#if CONFIG_CODEC == SWCODEC
1133 if (global_settings.talk_menu)
1134 pcmbuf_beep(1000, 150, 1500);
1135#endif
1136 }
1137}
1138
1139static void kbd_move_picker_vertical(struct keyboard_parameters *pm,
1140 struct edit_state *state, int dir)
1141{
1142 (void) state;
1143 state->changed = CHANGED_PICKER;
1144#ifdef HAVE_MORSE_INPUT
1145 if (state->morse_mode)
1146 {
1147#ifdef KBD_MODES
1148 pm->line_edit = !pm->line_edit;
1149#endif
1150 return;
1151 }
1152#endif /* HAVE_MORSE_INPUT */
1153 pm->y += dir;
1154#ifdef KBD_MODES
1155 if (pm->line_edit)
1156 {
1157 pm->y = (dir > 0 ? 0 : pm->lines - 1);
1158 pm->line_edit = false;
1159 }
1160 else if (pm->y < 0 || pm->y >= pm->lines)
1161 {
1162 pm->line_edit = true;
1163 }
1164#else
1165 if (pm->y >= pm->lines)
1166 pm->y = 0;
1167 if (pm->y < 0)
1168 pm->y = pm->lines - 1;
1169#endif
1170}