Index: apps/action.c =================================================================== --- apps/action.c (revision 13926) +++ apps/action.c (working copy) @@ -44,6 +44,8 @@ static bool screen_has_lock = false; #endif /* HAVE_SOFTWARE_KEYLOCK */ +extern intptr_t last_data; + /* * do_button_check is the worker function for get_default_action. * returns ACTION_UNKNOWN or the requested return value from the list. @@ -237,6 +239,11 @@ } #endif +intptr_t get_action_data(void) +{ + return last_data; +} + int get_action_statuscode(int *button) { int ret = 0; Index: apps/gui/list.c =================================================================== --- apps/gui/list.c (revision 13926) +++ apps/gui/list.c (working copy) @@ -887,37 +887,32 @@ } #endif /* HAVE_LCD_BITMAP */ +extern intptr_t get_action_data(void); + unsigned gui_synclist_do_button(struct gui_synclist * lists, unsigned button,enum list_wrap wrap) { #ifdef HAVE_LCD_BITMAP static bool scrolling_left = false; #endif - static int next_item_modifier = 1; - static int last_accel_tick = 0; + uintptr_t data; + unsigned delta; + uint64_t v; int i; - if (global_settings.list_accel_start_delay) - { - int start_delay = global_settings.list_accel_start_delay * (HZ/2); - int accel_wait = global_settings.list_accel_wait * HZ/2; + data = get_action_data(); - if (get_action_statuscode(NULL)&ACTION_REPEAT) - { - if (!last_accel_tick) - last_accel_tick = current_tick + start_delay; - else if (current_tick >= - last_accel_tick + accel_wait) - { - last_accel_tick = current_tick; - next_item_modifier++; - } - } - else if (last_accel_tick) - { - next_item_modifier = 1; - last_accel_tick = 0; - } + /* get number of clicks since last reading */ + delta = data >> 24; + + /* get wheel velocity in clicks/uS - 0.24 fixed point */ + v = data & 0xffffff; + + if (v != 0) + { + /* repeat in fast mode */ + v = v * v / (0xffffff/12); + delta = delta * MAX(v, 1); } switch (wrap) @@ -952,18 +947,16 @@ case ACTION_STD_PREV: case ACTION_STD_PREVREPEAT: FOR_NB_SCREENS(i) - gui_list_select_at_offset(&(lists->gui_list[i]), -next_item_modifier); - if (queue_count(&button_queue) < FRAMEDROP_TRIGGER) - gui_synclist_draw(lists); + gui_list_select_at_offset(&(lists->gui_list[i]), -delta); + gui_synclist_draw(lists); yield(); return ACTION_STD_PREV; case ACTION_STD_NEXT: case ACTION_STD_NEXTREPEAT: FOR_NB_SCREENS(i) - gui_list_select_at_offset(&(lists->gui_list[i]), next_item_modifier); - if (queue_count(&button_queue) < FRAMEDROP_TRIGGER) - gui_synclist_draw(lists); + gui_list_select_at_offset(&(lists->gui_list[i]), delta); + gui_synclist_draw(lists); yield(); return ACTION_STD_NEXT; Index: firmware/target/arm/sandisk/sansa-e200/button-e200.c =================================================================== --- firmware/target/arm/sandisk/sansa-e200/button-e200.c (revision 13926) +++ firmware/target/arm/sandisk/sansa-e200/button-e200.c (working copy) @@ -32,8 +32,10 @@ static unsigned int old_wheel_value = 0; static unsigned int wheel_repeat = BUTTON_NONE; static unsigned int wheel_click_count = 0; +static unsigned int wheel_delta = 0; static int wheel_fast_mode = 0; static unsigned long last_wheel_tick = 0; +static unsigned long last_wheel_usec = 0; static unsigned long last_wheel_post = 0; static unsigned long next_backlight_on = 0; /* Buttons */ @@ -168,6 +170,8 @@ if (btn != BUTTON_NONE) { + unsigned int wheel_velocity; + wheel_click_count = 0; if (repeat && TIME_BEFORE(current_tick, @@ -176,11 +180,42 @@ last_wheel_post = current_tick; + if (wheel_fast_mode) + { + wheel_velocity = USEC_TIMER - last_wheel_usec; + wheel_velocity &= 0x7fffffff; + + if (wheel_delta > 0xff) + wheel_delta = 0xff; + + /* wheel velocity in 0.24 fixed point - clicks/uS */ + if (wheel_velocity == 0) + wheel_velocity = 0xffffff; + else + wheel_velocity = 0xffffff / wheel_velocity; + } + else + { + wheel_delta = 1; + wheel_velocity = 0; + } + if (queue_empty(&button_queue)) - queue_post(&button_queue, btn, 0); + { + queue_post(&button_queue, btn, (wheel_delta << 24) | + wheel_velocity); + /* message posted - reset delta */ + wheel_delta = 1; + } + else + { + /* skipped post - increment delta */ + wheel_delta++; + } } last_wheel_tick = current_tick; + last_wheel_usec = USEC_TIMER; } } Index: firmware/drivers/button.c =================================================================== --- firmware/drivers/button.c (revision 13926) +++ firmware/drivers/button.c (working copy) @@ -49,6 +49,7 @@ static long lastbtn; /* Last valid button status */ static long last_read; /* Last button status, for debouncing/filtering */ +intptr_t last_data; #ifdef HAVE_LCD_BITMAP static bool flipped; /* buttons can be flipped to match the LCD flip */ #endif @@ -309,7 +310,7 @@ if (current_tick - ev.tick > MAX_EVENT_AGE) return BUTTON_NONE; #endif - + last_data = ev.data; return ev.id; } @@ -329,7 +330,7 @@ #endif queue_wait_w_tmo(&button_queue, &ev, ticks); - return (ev.id != SYS_TIMEOUT)? ev.id: BUTTON_NONE; + return (ev.id != SYS_TIMEOUT)? (last_data = ev.data, ev.id): BUTTON_NONE; } void button_init(void)