Index: apps/recorder/keyboard.c =================================================================== --- apps/recorder/keyboard.c (revision 24810) +++ apps/recorder/keyboard.c (working copy) @@ -152,6 +152,44 @@ 0x73,0x55,0x4c,0x61,0x5a,0x80 }; #endif +static void kbd_calc_params(struct keyboard_parameters *pm, + struct screen *sc, struct edit_state *state); +static void kbd_draw_picker(struct keyboard_parameters *pm, + struct screen *sc, struct edit_state *state); +static void kbd_draw_edit_line(struct keyboard_parameters *pm, + struct screen *sc, struct edit_state *state); +static void kbd_inschar(struct edit_state *state, unsigned short ch); + +static void kbd_delchar(struct edit_state *state); + +#ifdef HAVE_MORSE_INPUT +#ifdef KBD_TOGGLE_INPUT +static void kbd_switch_morse_mode (struct edit_state *state, + struct keyboard_parameters *param); +#endif /* KBD_TOGGLE_INPUT */ +static void kbd_morse_select(struct edit_state *state); +#endif /* HAVE_MORSE_INPUT */ + +static void kbd_right(struct keyboard_parameters *pm); + +static void kbd_left(struct keyboard_parameters *pm); + +static void kbd_down(struct edit_state *state, + struct keyboard_parameters *pm); +static void kbd_up (struct edit_state *state, + struct keyboard_parameters *pm); +static void kbd_cursor_right(struct edit_state *state); + +static void kbd_cursor_left(struct edit_state *state); + +static void kbd_backspace(struct edit_state *state); + +static void kbd_insert_current_char(struct edit_state *state, + struct keyboard_parameters *pm); +static void kbd_select(struct edit_state *state, + struct keyboard_parameters *pm); +static void kbd_none(struct edit_state *state); + /* Loads a custom keyboard into memory call with NULL to reset keyboard */ int load_kbd(unsigned char* filename) @@ -300,13 +338,341 @@ return (k < pm->nchars)? pm->kbd_buf[k]: ' '; } -static void kbd_calc_params(struct keyboard_parameters *pm, - struct screen *sc, struct edit_state *state); -static void kbd_draw_picker(struct keyboard_parameters *pm, - struct screen *sc, struct edit_state *state); -static void kbd_draw_edit_line(struct keyboard_parameters *pm, - struct screen *sc, struct edit_state *state); +#if defined(HAVE_MORSE_INPUT) && defined(KBD_TOGGLE_INPUT) +static void kbd_switch_morse_mode ( struct edit_state *state, + struct keyboard_parameters *param ) +{ + int l; + state->morse_mode = !state->morse_mode; + FOR_NB_SCREENS(l) + { + struct keyboard_parameters *pm = ¶m[l]; + int y = pm->main_y; + pm->main_y = pm->old_main_y; + pm->old_main_y = y; + } + /* FIXME: We should talk something like Morse mode.. */ +} +#endif + +static void kbd_page_flip ( struct edit_state *state, + struct keyboard_parameters *pm ) +{ +#ifdef HAVE_MORSE_INPUT + if (state->morse_mode) + return; +#endif + if (++pm->page >= pm->pages) + pm->page = 0; + + kbd_spellchar( get_kbd_ch(pm) ); +} + +static void kbd_right( struct keyboard_parameters *pm ) +{ + if (++pm->x >= pm->max_chars) { +#ifndef KBD_PAGE_FLIP + /* no dedicated flip key - flip page on wrap */ + if (++pm->page >= pm->pages) + pm->page = 0; +#endif + pm->x = 0; + } + kbd_spellchar( get_kbd_ch(pm) ); +} + + +static void kbd_left( struct keyboard_parameters *pm ) +{ + if (--pm->x < 0) { +#ifndef KBD_PAGE_FLIP + /* no dedicated flip key - flip page on wrap */ + if (--pm->page < 0) + pm->page = pm->pages - 1; +#endif + pm->x = pm->max_chars - 1; + } + kbd_spellchar( get_kbd_ch(pm) ); +} + +static void kbd_down( struct edit_state *state, + struct keyboard_parameters *pm ) +{ +#ifdef HAVE_MORSE_INPUT + if (state->morse_mode) + { +#ifdef KBD_MODES + pm->line_edit = !pm->line_edit; + if (pm->line_edit) + say_edit(); +#endif + return; + } +#endif /* HAVE_MORSE_INPUT */ + +#ifdef KBD_MODES + if (pm->line_edit) + { + pm->y = 0; + pm->line_edit = false; + } + else if (++pm->y >= pm->lines) + { + pm->line_edit = true; + say_edit(); + } + if (!pm->line_edit) + { + kbd_spellchar( get_kbd_ch(pm) ); + } + return; +#else /* KBD_MODES */ + + if (++pm->y >= pm->lines) + pm->y = 0; + + kbd_spellchar( get_kbd_ch(pm) ); +#endif +} + +static void kbd_up ( struct edit_state *state, + struct keyboard_parameters *pm ) +{ +#ifdef HAVE_MORSE_INPUT + if (state->morse_mode) + { +#ifdef KBD_MODES + pm->line_edit = !pm->line_edit; + if (pm->line_edit) + say_edit(); +#endif + return; + } +#endif /* HAVE_MORSE_INPUT */ + +#ifdef KBD_MODES + if (pm->line_edit) + { + pm->y = pm->lines - 1; + pm->line_edit = false; + } + else if (--pm->y < 0) + { + pm->line_edit = true; + say_edit(); + } + if (!pm->line_edit) + kbd_spellchar( get_kbd_ch(pm) ); +#else /* KBD_MODES */ + + if (--pm->y < 0) + pm->y = pm->lines - 1; + + kbd_spellchar( get_kbd_ch(pm) ); +#endif +} + +static void kbd_cursor_right( struct edit_state *state ) +{ + state->hangul = false; + + if (state->editpos < state->len_utf8) + { + int c = utf8seek(state->text, ++state->editpos); + kbd_spellchar(state->text[c]); + } +#if CONFIG_CODEC == SWCODEC + else if (global_settings.talk_menu) + pcmbuf_beep(1000, 150, 1500); +#endif +} + +static void kbd_cursor_left( struct edit_state *state ) +{ + state->hangul = false; + + if (state->editpos > 0) + { + int c = utf8seek(state->text, --state->editpos); + kbd_spellchar(state->text[c]); + } +#if CONFIG_CODEC == SWCODEC + else if (global_settings.talk_menu) + pcmbuf_beep(1000, 150, 1500); +#endif +} + +static void kbd_backspace( struct edit_state *state ) +{ + unsigned short ch; + + if (state->hangul) + { + if (state->htail) + state->htail = 0; + else if (state->hvowel) + state->hvowel = 0; + else + state->hangul = false; + } + + kbd_delchar(state); + + if (state->hangul) + { + if (state->hvowel) + ch = hangul_join(state->hlead, state->hvowel, state->htail); + else + ch = state->hlead; + kbd_inschar(state, ch); + } + + if (global_settings.talk_menu) /* voice UI? */ + talk_spell(state->text, false); /* speak revised text */ +} + +static void kbd_insert_current_char( struct edit_state *state, + struct keyboard_parameters *pm ) +{ + + /* inserts the selected char */ + /* find input char */ + unsigned short ch; + ch = get_kbd_ch(pm); + + /* check for hangul input */ + if (ch >= 0x3131 && ch <= 0x3163) + { + unsigned short tmp; + + if (!state->hangul) + { + state->hlead = state->hvowel = state->htail = 0; + state->hangul = true; + } + + if (!state->hvowel) + { + state->hvowel = ch; + } + else if (!state->htail) + { + state->htail = ch; + } + else + { + /* previous hangul complete */ + /* check whether tail is actually lead of next char */ + tmp = hangul_join(state->htail, ch, 0); + + if (tmp != 0xfffd) + { + tmp = hangul_join(state->hlead, state->hvowel, 0); + kbd_delchar(state); + kbd_inschar(state, tmp); + /* insert dummy char */ + kbd_inschar(state, ' '); + state->hlead = state->htail; + state->hvowel = ch; + state->htail = 0; + } + else + { + state->hvowel = state->htail = 0; + state->hlead = ch; + } + } + + /* combine into hangul */ + tmp = hangul_join(state->hlead, state->hvowel, state->htail); + + if (tmp != 0xfffd) + { + kbd_delchar(state); + ch = tmp; + } + else + { + state->hvowel = state->htail = 0; + state->hlead = ch; + } + } + else + { + state->hangul = false; + } + + /* insert char */ + kbd_inschar(state, ch); + + if (global_settings.talk_menu) /* voice UI? */ + talk_spell(state->text, false); /* speak revised text */ +} + +static void kbd_select( struct edit_state *state, + struct keyboard_parameters *pm ) +{ +#ifdef HAVE_MORSE_INPUT + if (state->morse_mode) + { + state->morse_tick = current_tick; + + if (!state->morse_reading) + { + logf("Morse char start:\n"); + state->morse_reading = true; + state->morse_code = 1; + } + } + else +#endif /* HAVE_MORSE_INPUT */ + kbd_insert_current_char( state, pm ); +} + +#ifdef HAVE_MORSE_INPUT +static void kbd_morse_select( struct edit_state *state ) +{ + if (state->morse_mode && state->morse_reading) + { + state->morse_code <<= 1; + if ((current_tick - state->morse_tick) > HZ/5) + state->morse_code |= 0x01; + } +} +#endif /* HAVE_MORSE_INPUT */ + +static void kbd_none( struct edit_state *state ) +{ +#ifdef HAVE_MORSE_INPUT + if (state->morse_reading) + { + int j; + logf("Morse: 0x%02x", state->morse_code); + state->morse_reading = false; + + for (j = 0; morse_alphabets[j] != '\0'; j++) + { + if (morse_codes[j] == state->morse_code) + break; + } + + if (morse_alphabets[j] == '\0') + { + logf("Morse code not found"); + return; + } + + /* turn off hangul input */ + state->hangul = false; + kbd_inschar(state, morse_alphabets[j]); + + if (global_settings.talk_menu) /* voice UI? */ + talk_spell(state->text, false); /* speak revised text */ + } +#endif /* HAVE_MORSE_INPUT */ +} + int kbd_input(char* text, int buflen) { bool done = false; @@ -318,7 +684,6 @@ #endif struct edit_state state; int l; /* screen loop variable */ - unsigned short ch; int ret = 0; /* assume success */ FOR_NB_SCREENS(l) { @@ -500,316 +865,54 @@ break; case ACTION_KBD_PAGE_FLIP: -#ifdef HAVE_MORSE_INPUT - if (state.morse_mode) - break; -#endif - if (++pm->page >= pm->pages) - pm->page = 0; - - ch = get_kbd_ch(pm); - kbd_spellchar(ch); + kbd_page_flip( &state, pm ); break; -#if defined(HAVE_MORSE_INPUT) && defined(KBD_TOGGLE_INPUT) +#ifdef HAVE_MORSE_INPUT +#ifdef KBD_TOGGLE_INPUT case ACTION_KBD_MORSE_INPUT: - state.morse_mode = !state.morse_mode; - - FOR_NB_SCREENS(l) - { - struct keyboard_parameters *pm = ¶m[l]; - int y = pm->main_y; - pm->main_y = pm->old_main_y; - pm->old_main_y = y; - } - /* FIXME: We should talk something like Morse mode.. */ + kbd_switch_morse_mode( &state, param ); break; -#endif /* HAVE_MORSE_INPUT && KBD_TOGGLE_INPUT */ +#endif /* KBD_TOGGLE_INPUT */ + case ACTION_KBD_MORSE_SELECT: + kbd_morse_select( &state ); + break; +#endif /* HAVE_MORSE_INPUT */ case ACTION_KBD_RIGHT: - if (++pm->x >= pm->max_chars) - { -#ifndef KBD_PAGE_FLIP - /* no dedicated flip key - flip page on wrap */ - if (++pm->page >= pm->pages) - pm->page = 0; -#endif - pm->x = 0; - } - - ch = get_kbd_ch(pm); - kbd_spellchar(ch); + kbd_right( pm ); break; case ACTION_KBD_LEFT: - if (--pm->x < 0) - { -#ifndef KBD_PAGE_FLIP - /* no dedicated flip key - flip page on wrap */ - if (--pm->page < 0) - pm->page = pm->pages - 1; -#endif - pm->x = pm->max_chars - 1; - } - - ch = get_kbd_ch(pm); - kbd_spellchar(ch); + kbd_left( pm ); break; case ACTION_KBD_DOWN: -#ifdef HAVE_MORSE_INPUT - if (state.morse_mode) - { -#ifdef KBD_MODES - pm->line_edit = !pm->line_edit; - if (pm->line_edit) - say_edit(); -#endif - break; - } -#endif /* HAVE_MORSE_INPUT */ -#ifdef KBD_MODES - if (pm->line_edit) - { - pm->y = 0; - pm->line_edit = false; - } - else if (++pm->y >= pm->lines) - { - pm->line_edit = true; - say_edit(); - } -#else - if (++pm->y >= pm->lines) - pm->y = 0; -#endif -#ifdef KBD_MODES - if (!pm->line_edit) -#endif - { - ch = get_kbd_ch(pm); - kbd_spellchar(ch); - } + kbd_down( &state, pm ); break; case ACTION_KBD_UP: -#ifdef HAVE_MORSE_INPUT - if (state.morse_mode) - { -#ifdef KBD_MODES - pm->line_edit = !pm->line_edit; - if (pm->line_edit) - say_edit(); -#endif - break; - } -#endif /* HAVE_MORSE_INPUT */ -#ifdef KBD_MODES - if (pm->line_edit) - { - pm->y = pm->lines - 1; - pm->line_edit = false; - } - else if (--pm->y < 0) - { - pm->line_edit = true; - say_edit(); - } -#else - if (--pm->y < 0) - pm->y = pm->lines - 1; -#endif -#ifdef KBD_MODES - if (!pm->line_edit) -#endif - { - ch = get_kbd_ch(pm); - kbd_spellchar(ch); - } + kbd_up( &state, pm ); break; -#ifdef HAVE_MORSE_INPUT - case ACTION_KBD_MORSE_SELECT: - if (state.morse_mode && state.morse_reading) - { - state.morse_code <<= 1; - if ((current_tick - state.morse_tick) > HZ/5) - state.morse_code |= 0x01; - } - break; -#endif /* HAVE_MORSE_INPUT */ - case ACTION_KBD_SELECT: -#ifdef HAVE_MORSE_INPUT - if (state.morse_mode) - { - state.morse_tick = current_tick; - - if (!state.morse_reading) - { - state.morse_reading = true; - state.morse_code = 1; - } - } - else -#endif /* HAVE_MORSE_INPUT */ - { - /* inserts the selected char */ - /* find input char */ - ch = get_kbd_ch(pm); - - /* check for hangul input */ - if (ch >= 0x3131 && ch <= 0x3163) - { - unsigned short tmp; - - if (!state.hangul) - { - state.hlead = state.hvowel = state.htail = 0; - state.hangul = true; - } - - if (!state.hvowel) - { - state.hvowel = ch; - } - else if (!state.htail) - { - state.htail = ch; - } - else - { - /* previous hangul complete */ - /* check whether tail is actually lead of next char */ - tmp = hangul_join(state.htail, ch, 0); - - if (tmp != 0xfffd) - { - tmp = hangul_join(state.hlead, state.hvowel, 0); - kbd_delchar(&state); - kbd_inschar(&state, tmp); - /* insert dummy char */ - kbd_inschar(&state, ' '); - state.hlead = state.htail; - state.hvowel = ch; - state.htail = 0; - } - else - { - state.hvowel = state.htail = 0; - state.hlead = ch; - } - } - - /* combine into hangul */ - tmp = hangul_join(state.hlead, state.hvowel, state.htail); - - if (tmp != 0xfffd) - { - kbd_delchar(&state); - ch = tmp; - } - else - { - state.hvowel = state.htail = 0; - state.hlead = ch; - } - } - else - { - state.hangul = false; - } - - /* insert char */ - kbd_inschar(&state, ch); - - if (global_settings.talk_menu) /* voice UI? */ - talk_spell(state.text, false); /* speak revised text */ - } + kbd_select( &state, pm ); break; case ACTION_KBD_BACKSPACE: - if (state.hangul) - { - if (state.htail) - state.htail = 0; - else if (state.hvowel) - state.hvowel = 0; - else - state.hangul = false; - } - - kbd_delchar(&state); - - if (state.hangul) - { - if (state.hvowel) - ch = hangul_join(state.hlead, state.hvowel, state.htail); - else - ch = state.hlead; - kbd_inschar(&state, ch); - } - - if (global_settings.talk_menu) /* voice UI? */ - talk_spell(state.text, false); /* speak revised text */ + kbd_backspace( &state ); break; case ACTION_KBD_CURSOR_RIGHT: - state.hangul = false; - - if (state.editpos < state.len_utf8) - { - int c = utf8seek(state.text, ++state.editpos); - kbd_spellchar(state.text[c]); - } -#if CONFIG_CODEC == SWCODEC - else if (global_settings.talk_menu) - pcmbuf_beep(1000, 150, 1500); -#endif + kbd_cursor_right( &state ); break; case ACTION_KBD_CURSOR_LEFT: - state.hangul = false; - - if (state.editpos > 0) - { - int c = utf8seek(state.text, --state.editpos); - kbd_spellchar(state.text[c]); - } -#if CONFIG_CODEC == SWCODEC - else if (global_settings.talk_menu) - pcmbuf_beep(1000, 150, 1500); -#endif + kbd_cursor_left( &state ); break; case ACTION_NONE: -#ifdef HAVE_MORSE_INPUT - if (state.morse_reading) - { - int j; - logf("Morse: 0x%02x", state.morse_code); - state.morse_reading = false; - - for (j = 0; morse_alphabets[j] != '\0'; j++) - { - if (morse_codes[j] == state.morse_code) - break ; - } - - if (morse_alphabets[j] == '\0') - { - logf("Morse code not found"); - break ; - } - - /* turn off hangul input */ - state.hangul = false; - kbd_inschar(&state, morse_alphabets[j]); - - if (global_settings.talk_menu) /* voice UI? */ - talk_spell(state.text, false); /* speak revised text */ - } -#endif /* HAVE_MORSE_INPUT */ + kbd_none( &state ); break; default: