From 88fdf8789bd052abadfade8132358c418ffcaf72 Mon Sep 17 00:00:00 2001 From: Mikael Magnusson Date: Sun, 14 Jun 2009 19:21:03 +0200 Subject: [PATCH] Honeycomb patch and needed changes --- apps/plugin.c | 11 ++ apps/plugin.h | 4 + apps/recorder/keyboard.c | 200 +++++++++++++++++++++++++- firmware/drivers/button.c | 12 ++- firmware/export/button.h | 9 ++ firmware/target/arm/ipod/button-clickwheel.c | 43 +++++- firmware/target/arm/ipod/button-target.h | 4 + uisimulator/sdl/button.c | 13 ++ 8 files changed, 285 insertions(+), 11 deletions(-) diff --git a/apps/plugin.c b/apps/plugin.c index 05a27ea..93ca93c 100644 --- a/apps/plugin.c +++ b/apps/plugin.c @@ -244,6 +244,7 @@ static const struct plugin_api rockbox_api = { /* button */ button_get, + button_get_with_data, button_get_w_tmo, button_status, #ifdef HAVE_BUTTON_DATA @@ -593,7 +594,10 @@ static const struct plugin_api rockbox_api = { #ifdef HAVE_WHEEL_POSITION wheel_status, wheel_send_events, + wheel_send_touch_events, + wheel_send_accel_events, #endif + set_trigger_delta, #ifdef IRIVER_H100_SERIES /* Routines for the iriver_flash -plugin. */ @@ -776,6 +780,13 @@ int plugin_load(const char* plugin, const void* parameter) viewportmanager_set_statusbar(oldbars); +#if CONFIG_KEYPAD == IPOD_4G_PAD && ! defined(SIMULATOR) + /* using the menu probably isn't fun without wheel events */ + wheel_send_events(true); + wheel_send_accel_events(true); + wheel_send_touch_events(false); +#endif + button_clear_queue(); #ifdef HAVE_LCD_BITMAP diff --git a/apps/plugin.h b/apps/plugin.h index 8ec0f19..89e1d51 100644 --- a/apps/plugin.h +++ b/apps/plugin.h @@ -353,6 +353,7 @@ struct plugin_api { /* button */ long (*button_get)(bool block); + long (*button_get_with_data)(bool block, long *data); long (*button_get_w_tmo)(int ticks); int (*button_status)(void); #ifdef HAVE_BUTTON_DATA @@ -748,7 +749,10 @@ struct plugin_api { #ifdef HAVE_WHEEL_POSITION int (*wheel_status)(void); void (*wheel_send_events)(bool send); + void (*wheel_send_touch_events)(bool send); + void (*wheel_send_accel_events)(bool send); #endif + void (*set_trigger_delta)(unsigned int delta); #ifdef IRIVER_H100_SERIES /* Routines for the iriver_flash -plugin. */ diff --git a/apps/recorder/keyboard.c b/apps/recorder/keyboard.c index 6ad6ca1..9453ef1 100644 --- a/apps/recorder/keyboard.c +++ b/apps/recorder/keyboard.c @@ -59,8 +59,7 @@ #elif (CONFIG_KEYPAD == IPOD_1G2G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD) \ || (CONFIG_KEYPAD == IPOD_4G_PAD) -#define KBD_MODES /* iPod uses 2 modes, picker and line edit */ -#define KBD_MORSE_INPUT +#define HONEY_COMB #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD #define KBD_MODES /* iFP7xx uses 2 modes, picker and line edit */ @@ -244,6 +243,31 @@ static void kbd_inschar(unsigned char* text, int buflen, } } +static void kbd_insutf8(unsigned char* text, int buflen, + int* editpos, unsigned char* utf8) +{ + int i, j, k, len; + + len = strlen(text); + k = utf8length(text); + j = strlen(utf8); + + if (len + j < buflen) + { + for (i = len+j; k >= *editpos; i--) + { + text[i] = text[i-j]; + if ((text[i] & MASK) != COMP) + k--; + } + + while (j--) + text[i--] = utf8[j]; + + (*editpos)++; + } +} + static void kbd_delchar(unsigned char* text, int* editpos) { int i = 0; @@ -277,6 +301,177 @@ static int get_param_k(const struct keyboard_parameters *pm) return (pm->page*pm->lines + pm->y)*pm->max_chars + pm->x; } +#ifdef HONEY_COMB +// TODO: read these from files +static char *alphabet[][9][8] = {{{"c","d","/+","/-","/d","-","a","b"}, + {"f","g","h","/l","/r","-","-","e"}, + {"i","j","k","l","-","-","-","-"}, + {"-","m","n","o","p","-","-","-"}, + {"-","-","q","r","s","t","-","-"}, + {"-","-","-","u","v","w","x","-"}, + {"-","-","-","-","y","z","å","ä"}, + {" ","-","-","-","-","ö",".",","}, + {"a","e","i","m","q","u","y","."}, /* this line is shown when + not touching to hint + what is what */ + },{ + {"あ","い","う","え","お","わ","を","ん"}, + {"は","ひ","ふ","へ","ほ","や","ゆ","よ"}, + {"ら","り","る","れ","ろ","゛","゜","ー"}, + {"た","ち","つ","て","と","っ","/+","/-"}, + {"な","に","ぬ","ね","の","ん"," "," "}, + {"さ","し","す","せ","そ"," "," "," "}, + {"か","き","く","け","こ"," "," "," "}, + {"ま","み","む","め","も"," "," "," "}, + {"あ","は","ら","た","な","さ","か","ま"} + },{ + {"ぁ","ぃ","ぅ","ぇ","ぉ","、","。","ん"}, + {"ぱ","ぴ","ぷ","ぺ","ぽ","ゃ","ゅ","ょ"}, + {"ば","び","ぶ","べ","ぼ","゛","゜","ー"}, + {"だ","ぢ","づ","で","ど","っ","/+","/-"}, + {"な","に","ぬ","ね","の","ん"," "," "}, + {"ざ","じ","ず","ぜ","ぞ"," "," "," "}, + {"が","ぎ","ぐ","げ","ご"," "," "," "}, + {"ま","み","む","め","も","、","。"," "}, + {"ぁ","ぱ","ば","だ","な","ざ","が","ま"} + } + }; + +static int charpos[8][2] = {{100,20}, {120,30}, {140,40}, {120,50}, {100,60}, {80,50}, {60,40}, {80,30}}; + +static void drawline(int page, int line, int letter) { + int i; + for (i = 0; i < 8; i++) { + if (i == letter) + lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); + lcd_putsxy(charpos[i][0], charpos[i][1], alphabet[page][line][i]); + lcd_set_drawmode(DRMODE_SOLID); + } +} + +int kbd_input(char* text, int buflen) +{ + long wheel; + int button; + int ret = 0; + int page = 0; // which alphabet array to use + int i = 0, pos = 0; // position in the alphabet array, i is set from pos + // on touch, then the new pos is used on release for + // the second index + int j = 0, k = 0; // position on screen for the test output + int editpos, len_utf8; + int ignore; // allow to press menu to abort a touch + + set_trigger_delta(1); + wheel_send_touch_events(true); + wheel_send_accel_events(false); + editpos = utf8length(text); + lcd_clear_display(); + lcd_putsxy(5, 115, text); + drawline(page, 8,-1); + lcd_update(); + while (!ret) { + button = button_get_with_data(true, &wheel); + wheel &= 0x7f; + button &= ~BUTTON_REPEAT; + len_utf8 = utf8length(text); + if ((button == BUTTON_TOUCH) || (button == BUTTON_UNTOUCH) || + (button == BUTTON_SCROLL_FWD) || (button == BUTTON_SCROLL_BACK)) { + if (wheel > 89 || wheel < 6) { // top + pos = 0; + } else if (wheel < 17) { //topleft + pos = 1; + } else if (wheel < 30) { //right + pos = 2; + } else if (wheel < 42) { //bottomright + pos = 3; + } else if (wheel < 53) { //bottom + pos = 4; + } else if (wheel < 65) { //bottomleft + pos = 5; + } else if (wheel < 77) { //left + pos = 6; + } else { //topleft + pos = 7; + } + if (button == BUTTON_TOUCH) { + i = pos; //draw a preview of the currently selected line here + drawline(page, i,-1); + lcd_update(); + ignore = 0; + } else if (button == BUTTON_UNTOUCH && ignore == 0) { + char *symbol = alphabet[page][i][pos]; + if (symbol[0] == '/' && symbol[1] != '\0') { + switch (symbol[1]) { + case '+': + page++; + if (page >= (signed)(sizeof(alphabet)/sizeof(*alphabet))) + page = 0; + break; + case '-': + page--; + if (page < 0) + page = sizeof(alphabet)/sizeof(*alphabet) - 1; + break; + case 'c': + break; // abort the touch + case 'e': + return -1; + case 'd': + kbd_delchar(text, &editpos); + break; + case 'r': + if (editpos < len_utf8) + editpos++; + break; + case 'l': + if (editpos > 0) + editpos--; + } + } else { //put the symbol + kbd_insutf8(text, buflen, &editpos, symbol); + lcd_puts(j++, k, symbol); + if (j > 10) { + j=0; + k++; + } + if (k > 8) + k=0; + } + lcd_putsxy(5, 115, text); + ignore = 1; // redraw summary screen + } else if (!ignore && ((button == BUTTON_SCROLL_FWD) || (button == BUTTON_SCROLL_BACK))) { + drawline(page,i,pos); + lcd_update(); + } + } else if (button == BUTTON_RIGHT && editpos < len_utf8) { + editpos++; + ignore = 1; + } else if (button == BUTTON_LEFT && editpos > 0) { + editpos--; + ignore = 1; + } else if (button == BUTTON_MENU) { + ignore = 1; + } else if (button == BUTTON_PLAY) { + kbd_delchar(text, &editpos); + ignore = 1; + } else if (button == BUTTON_SELECT) { + ret = 1; + } + + if (ignore) { + drawline(page, 8,-1); + lcd_update(); + lcd_clear_display(); + lcd_putsxy(5, 115, text); + } + } + wheel_send_touch_events(false); + wheel_send_accel_events(true); + set_trigger_delta(0); + return 0; +} +#else int kbd_input(char* text, int buflen) { bool done = false; @@ -1247,3 +1442,4 @@ int kbd_input(char* text, int buflen) return 0; } +#endif diff --git a/firmware/drivers/button.c b/firmware/drivers/button.c index 6fbe5de..0f11023 100644 --- a/firmware/drivers/button.c +++ b/firmware/drivers/button.c @@ -170,7 +170,7 @@ static void button_tick(void) if ( btn ) { /* normal keypress */ - if ( btn != lastbtn ) + if ( btn != lastbtn || btn == BUTTON_HOLD ) { post = true; repeat = false; @@ -354,6 +354,16 @@ long button_get(bool block) return BUTTON_NONE; } +long button_get_with_data(bool block, long *data) +{ + long button; + + button = button_get(block); + *data = button_data; + + return button; +} + long button_get_w_tmo(int ticks) { struct queue_event ev; diff --git a/firmware/export/button.h b/firmware/export/button.h index 3947f07..fb9b621 100644 --- a/firmware/export/button.h +++ b/firmware/export/button.h @@ -34,9 +34,18 @@ void button_init (void); void button_close(void); int button_queue_count(void); long button_get (bool block); +long button_get_with_data (bool block, long *data); long button_get_w_tmo(int ticks); intptr_t button_get_data(void); int button_status(void); +#if (CONFIG_KEYPAD == IPOD_4G_PAD) +int wheel_status(void); +void wheel_send_events(bool send); +void wheel_send_touch_events(bool send); +void wheel_send_accel_events(bool send); +void set_trigger_delta(unsigned int delta); +#endif + void button_clear_queue(void); #ifdef HAVE_LCD_BITMAP void button_set_flip(bool flip); /* turn 180 degrees */ diff --git a/firmware/target/arm/ipod/button-clickwheel.c b/firmware/target/arm/ipod/button-clickwheel.c index 7278428..6efa77d 100644 --- a/firmware/target/arm/ipod/button-clickwheel.c +++ b/firmware/target/arm/ipod/button-clickwheel.c @@ -69,7 +69,10 @@ int int_btn = BUTTON_NONE; #ifdef HAVE_WHEEL_POSITION static int wheel_position = -1; static bool send_events = true; + static bool send_touch_events = false; + static bool send_accel_events = true; #endif +static int trigger_delta = WHEEL_SENSITIVITY; static void opto_i2c_init(void) { @@ -108,6 +111,8 @@ static inline int ipod_4g_button_read(void) btn |= BUTTON_PLAY; if (status & 0x00001000) btn |= BUTTON_MENU; + if (button_hold()) + btn |= BUTTON_HOLD; if (status & 0x40000000) { unsigned long usec = USEC_TIMER; @@ -115,6 +120,10 @@ static inline int ipod_4g_button_read(void) /* Highest wheel = 0x5F, clockwise increases */ new_wheel_value = (status >> 16) & 0x7f; whl = new_wheel_value; + if (send_touch_events) { + if (wheel_position == -1 && new_wheel_value != -1) + queue_post(&button_queue, BUTTON_TOUCH, (intptr_t)new_wheel_value); + } /* switch on backlight (again), reset power-off timer */ backlight_on(); @@ -151,9 +160,9 @@ static inline int ipod_4g_button_read(void) /* Getting direction and wheel_keycode from wheel_delta. * Need at least some clicks to be sure to avoid haptic fuzziness */ - if (wheel_delta >= WHEEL_SENSITIVITY) + if (wheel_delta >= trigger_delta) wheel_keycode = BUTTON_SCROLL_FWD; - else if (wheel_delta <= -WHEEL_SENSITIVITY) + else if (wheel_delta <= -trigger_delta) wheel_keycode = BUTTON_SCROLL_BACK; else wheel_keycode = BUTTON_NONE; @@ -205,20 +214,21 @@ static inline int ipod_4g_button_read(void) /* The queue should have no other events when scrolling */ if (queue_empty(&button_queue)) { - /* each WHEEL_SENSITIVITY clicks = scrolling 1 item */ - accumulated_wheel_delta /= WHEEL_SENSITIVITY; + /* each trigger_delta clicks = scrolling 1 item */ + accumulated_wheel_delta /= trigger_delta; #ifdef HAVE_SCROLLWHEEL /* use data-format for HAVE_SCROLLWHEEL */ /* always use acceleration mode (1<<31) */ /* always set message post count to (1<<24) for iPod */ /* this way the scrolling is always calculated from wheel_velocity */ - queue_post(&button_queue, wheel_keycode | repeat, - (1<<31) | (1 << 24) | wheel_velocity); + if (send_accel_events) + queue_post(&button_queue, wheel_keycode | repeat, + (1<<31) | (1 << 24) | wheel_velocity); -#else + else +#endif queue_post(&button_queue, wheel_keycode | repeat, (accumulated_wheel_delta << 16) | new_wheel_value); -#endif accumulated_wheel_delta = 0; } last_wheel_usec = usec; @@ -240,6 +250,8 @@ static inline int ipod_4g_button_read(void) } } + if (send_touch_events && wheel_position != -1 && whl == -1) + queue_post(&button_queue, BUTTON_UNTOUCH, (intptr_t)wheel_position); #ifdef HAVE_WHEEL_POSITION /* Save the new absolute wheel position */ @@ -258,8 +270,23 @@ void wheel_send_events(bool send) { send_events = send; } +void wheel_send_touch_events(bool send) +{ + send_touch_events = send; +} +void wheel_send_accel_events(bool send) +{ + send_accel_events = send; +} #endif +void set_trigger_delta(unsigned int delta) { + if (delta == 0) + trigger_delta = WHEEL_SENSITIVITY; + else + trigger_delta = delta; +} + void ipod_4g_button_int(void) { CPU_HI_INT_DIS = I2C_MASK; diff --git a/firmware/target/arm/ipod/button-target.h b/firmware/target/arm/ipod/button-target.h index 67bdc72..76275bf 100644 --- a/firmware/target/arm/ipod/button-target.h +++ b/firmware/target/arm/ipod/button-target.h @@ -45,6 +45,10 @@ void ipod_4g_button_int(void); #define BUTTON_SCROLL_BACK 0x00000020 #define BUTTON_PLAY 0x00000040 +#define BUTTON_HOLD 0x00000080 + +#define BUTTON_UNTOUCH 0x00000100 +#define BUTTON_TOUCH 0x00000200 #define BUTTON_MAIN (BUTTON_SELECT|BUTTON_MENU\ |BUTTON_LEFT|BUTTON_RIGHT|BUTTON_SCROLL_FWD\ diff --git a/uisimulator/sdl/button.c b/uisimulator/sdl/button.c index 9c8f334..872bd7c 100644 --- a/uisimulator/sdl/button.c +++ b/uisimulator/sdl/button.c @@ -1268,6 +1268,16 @@ long button_get(bool block) return BUTTON_NONE; } +long button_get_with_data(bool block, long *data) +{ + long button; + + button = button_get(block); + *data = button_data; + + return button; +} + long button_get_w_tmo(int ticks) { struct queue_event ev; @@ -1339,3 +1349,6 @@ void button_clear_queue(void) queue_clear(&button_queue); } +void set_trigger_delta(unsigned int unused) {} +void wheel_send_touch_events(bool unused) {} +void wheel_send_accel_events(bool unused) {} -- 1.6.3.GIT