Index: apps/keymaps/keymap-cowond2.c =================================================================== --- apps/keymaps/keymap-cowond2.c (revision 25412) +++ apps/keymaps/keymap-cowond2.c (working copy) @@ -64,6 +64,21 @@ { ACTION_WPS_MENU, BUTTON_MENU|BUTTON_REL, BUTTON_MENU }, { ACTION_WPS_CONTEXT, BUTTON_MENU|BUTTON_REPEAT, BUTTON_MENU }, +#ifdef HAVE_ALT_MODE + { ACTION_WPS_VOLDOWN, BUTTON_ALT|BUTTON_MINUS, BUTTON_NONE }, + { ACTION_WPS_VOLDOWN, BUTTON_ALT|BUTTON_MINUS|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_WPS_VOLUP, BUTTON_ALT|BUTTON_PLUS, BUTTON_NONE }, + { ACTION_WPS_VOLUP, BUTTON_ALT|BUTTON_PLUS|BUTTON_REPEAT, BUTTON_NONE }, + + { ACTION_WPS_PLAY, BUTTON_ALT|BUTTON_MENU|BUTTON_REL, BUTTON_ALT|BUTTON_HOLD|BUTTON_MENU }, + { ACTION_WPS_SKIPPREV, BUTTON_ALT|BUTTON_MINUS|BUTTON_REL, BUTTON_ALT|BUTTON_HOLD|BUTTON_MINUS }, + { ACTION_WPS_SEEKBACK, BUTTON_ALT|BUTTON_HOLD|BUTTON_MINUS|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_WPS_STOPSEEK, BUTTON_ALT|BUTTON_MINUS|BUTTON_REL, BUTTON_ALT|BUTTON_HOLD|BUTTON_MINUS|BUTTON_REPEAT }, + { ACTION_WPS_SKIPNEXT, BUTTON_ALT|BUTTON_PLUS|BUTTON_REL, BUTTON_ALT|BUTTON_HOLD|BUTTON_PLUS }, + { ACTION_WPS_SEEKFWD, BUTTON_ALT|BUTTON_HOLD|BUTTON_PLUS|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_WPS_STOPSEEK, BUTTON_ALT|BUTTON_PLUS|BUTTON_REL, BUTTON_ALT|BUTTON_HOLD|BUTTON_PLUS|BUTTON_REPEAT }, +#endif + LAST_ITEM_IN_LIST }; /* button_context_wps */ Index: firmware/export/button.h =================================================================== --- firmware/export/button.h (revision 25412) +++ firmware/export/button.h (working copy) @@ -51,6 +51,11 @@ #endif #endif +#ifdef HAVE_SW_HOLD +#define HAS_BUTTON_HOLD +bool button_hold(void); +#endif + #ifdef HAVE_HEADPHONE_DETECTION bool headphones_inserted(void); #endif @@ -69,6 +74,7 @@ #define BUTTON_REL 0x02000000 #define BUTTON_REPEAT 0x04000000 #define BUTTON_TOUCHSCREEN 0x08000000 +#define BUTTON_ALT 0x10000000 #ifdef HAVE_TOUCHSCREEN int touchscreen_last_touch(void); Index: firmware/export/config/cowond2.h =================================================================== --- firmware/export/config/cowond2.h (revision 25412) +++ firmware/export/config/cowond2.h (working copy) @@ -95,6 +95,12 @@ /* Define this if you have a software controlled poweroff */ #define HAVE_SW_POWEROFF +/* Define this if you have a software controlled hold */ +#define HAVE_SW_HOLD + +/* Define this if you have a alternative input mode */ +#define HAVE_ALT_MODE + /* Reduce Tremor's ICODE usage */ #define ICODE_ATTR_TREMOR_NOT_MDCT Index: firmware/target/arm/tcc780x/cowond2/button-cowond2.c =================================================================== --- firmware/target/arm/tcc780x/cowond2/button-cowond2.c (revision 25412) +++ firmware/target/arm/tcc780x/cowond2/button-cowond2.c (working copy) @@ -38,33 +38,17 @@ touchscreen_init_device(); } -bool button_hold(void) -{ - return (GPIOA & 0x8) ? false : true; -} - int button_read_device(int *data) { int btn = BUTTON_NONE; int adc; static int old_data = 0; - static bool hold_button = false; - bool hold_button_old; - *data = old_data; - hold_button_old = hold_button; - hold_button = button_hold(); + if (!(GPIOA & 0x8)) + btn |= BUTTON_HOLD; -#ifndef BOOTLOADER - if (hold_button != hold_button_old) - backlight_hold_changed(hold_button); -#endif - - if (hold_button) - return BUTTON_NONE; - if (GPIOB & 0x4) { adc = adc_read(ADC_BUTTONS); Index: firmware/target/arm/tcc780x/cowond2/button-target.h =================================================================== --- firmware/target/arm/tcc780x/cowond2/button-target.h (revision 25412) +++ firmware/target/arm/tcc780x/cowond2/button-target.h (working copy) @@ -25,9 +25,6 @@ #include #include "config.h" -#define HAS_BUTTON_HOLD - -bool button_hold(void); void button_init_device(void); int button_read_device(int *data); @@ -36,6 +33,7 @@ #define BUTTON_PLUS 0x00000002 #define BUTTON_MINUS 0x00000004 #define BUTTON_MENU 0x00000008 +#define BUTTON_HOLD 0x00000010 /* Compatibility hacks for flipping. Needs a somewhat better fix. */ #define BUTTON_LEFT BUTTON_MIDLEFT @@ -44,17 +42,17 @@ #define BUTTON_DOWN BUTTON_BOTTOMMIDDLE /* Touch Screen Area Buttons */ -#define BUTTON_TOPLEFT 0x00000010 -#define BUTTON_TOPMIDDLE 0x00000020 -#define BUTTON_TOPRIGHT 0x00000040 -#define BUTTON_MIDLEFT 0x00000080 -#define BUTTON_CENTER 0x00000100 -#define BUTTON_MIDRIGHT 0x00000200 -#define BUTTON_BOTTOMLEFT 0x00000400 -#define BUTTON_BOTTOMMIDDLE 0x00000800 -#define BUTTON_BOTTOMRIGHT 0x00001000 +#define BUTTON_TOPLEFT 0x00000020 +#define BUTTON_TOPMIDDLE 0x00000040 +#define BUTTON_TOPRIGHT 0x00000080 +#define BUTTON_MIDLEFT 0x00000100 +#define BUTTON_CENTER 0x00000200 +#define BUTTON_MIDRIGHT 0x00000400 +#define BUTTON_BOTTOMLEFT 0x00000800 +#define BUTTON_BOTTOMMIDDLE 0x00001000 +#define BUTTON_BOTTOMRIGHT 0x00002000 -#define BUTTON_MAIN 0x1FFF +#define BUTTON_MAIN 0x2FFF /* No remote */ #define BUTTON_REMOTE 0 @@ -62,5 +60,11 @@ /* Software power-off */ #define POWEROFF_BUTTON BUTTON_POWER #define POWEROFF_COUNT 10 - + +/* Software hold */ +#define HOLD_BUTTON BUTTON_HOLD + +/* Alternative input mode */ +#define ALT_BUTTON BUTTON_MENU + #endif /* _BUTTON_TARGET_H_ */ Index: firmware/drivers/button.c =================================================================== --- firmware/drivers/button.c (revision 25412) +++ firmware/drivers/button.c (working copy) @@ -59,6 +59,9 @@ #ifdef HAVE_LCD_BITMAP static bool flipped; /* buttons can be flipped to match the LCD flip */ #endif +#ifdef HAVE_SW_HOLD +static bool is_hold; +#endif #ifdef HAVE_BACKLIGHT static bool filter_first_keypress; #ifdef HAVE_REMOTE_LCD @@ -83,11 +86,18 @@ #else static int button_read(void); #endif +static inline void button_activity(int btn); +#ifdef HAVE_SW_POWEROFF +static void button_poweroff(bool repeat); +#endif +#ifdef HAVE_BACKLIGHT +static bool button_need_skip(int btn); +#endif #ifdef HAVE_TOUCHSCREEN static int last_touchscreen_touch; static int lastdata = 0; -#endif +#endif #if defined(HAVE_HEADPHONE_DETECTION) static struct timeout hp_detect_timeout; /* Debouncer for headphone plug/unplug */ /* This callback can be used for many different functions if needed - @@ -104,19 +114,14 @@ static void button_tick(void) { - static int count = 0; - static int repeat_speed = REPEAT_INTERVAL_START; - static int repeat_count = 0; - static bool repeat = false; - static bool post = false; -#ifdef HAVE_BACKLIGHT - static bool skip_release = false; -#ifdef HAVE_REMOTE_LCD - static bool skip_remote_release = false; + static unsigned int count = REPEAT_START; + static unsigned int repeat_speed = REPEAT_INTERVAL_START; +#ifdef HAVE_ALT_MODE + static bool alt_mode = false; #endif -#endif int diff; int btn; + int post_btn; #ifdef HAVE_BUTTON_DATA int data = 0; #else @@ -148,168 +153,267 @@ } #endif - /* Find out if a key has been released */ diff = btn ^ lastbtn; - if(diff && (btn & diff) == 0) + +#ifdef HAVE_SW_HOLD +#ifdef HAVE_ALT_MODE + if (is_hold && !alt_mode && !(btn & HOLD_BUTTON) && btn == ALT_BUTTON) { + alt_mode = true; + btn = BUTTON_NONE; + goto exit; + } + + if (alt_mode && btn == (HOLD_BUTTON | ALT_BUTTON) && diff == HOLD_BUTTON) + { + alt_mode = false; + btn = BUTTON_NONE; + goto exit; + } + + if (!alt_mode) +#endif + { + if(is_hold) + { + if (!(btn & HOLD_BUTTON)) + { + is_hold = false; #ifdef HAVE_BACKLIGHT -#ifdef HAVE_REMOTE_LCD - if(diff & BUTTON_REMOTE) - if(!skip_remote_release) - queue_post(&button_queue, BUTTON_REL | diff, data); - else - skip_remote_release = false; - else + backlight_hold_changed(false); #endif - if(!skip_release) - queue_post(&button_queue, BUTTON_REL | diff, data); - else - skip_release = false; -#else - queue_post(&button_queue, BUTTON_REL | diff, data); + } + + btn = BUTTON_NONE; + goto exit; + } + else if(btn & HOLD_BUTTON) + { + is_hold = true; +#ifdef HAVE_BACKLIGHT + backlight_hold_changed(true); #endif + btn = BUTTON_NONE; + goto exit; + } } +#endif + + /* Find out if a key has been released */ + if(diff && (btn & diff) == BUTTON_NONE) + { + post_btn = BUTTON_REL | diff; + } else { - if ( btn ) + if(btn != BUTTON_NONE) { /* normal keypress */ - if ( btn != lastbtn ) + if(diff != BUTTON_NONE) { - post = true; - repeat = false; + count = REPEAT_START; repeat_speed = REPEAT_INTERVAL_START; + post_btn = btn; } else /* repeat? */ { - if ( repeat ) - { - if (!post) - count--; - if (count == 0) { - post = true; - /* yes we have repeat */ - if (repeat_speed > REPEAT_INTERVAL_FINISH) - repeat_speed--; - count = repeat_speed; + --count; + if(count != 0) + goto exit; + /* yes we have repeat */ + count = repeat_speed; + if(repeat_speed > REPEAT_INTERVAL_FINISH) + --repeat_speed; + post_btn = btn | BUTTON_REPEAT; + } + } + else /* none button pressed */ + goto exit; + } - repeat_count++; +#ifdef HAVE_SW_HOLD + /* hold button couldn't have repeats */ + if (post_btn == (HOLD_BUTTON | BUTTON_REPEAT)) + { + btn = BUTTON_NONE; + goto exit; + } +#endif - /* Send a SYS_POWEROFF event if we have a device - which doesn't shut down easily with the OFF - key */ +#ifdef HAVE_ALT_MODE + if(alt_mode) + { + post_btn |= BUTTON_ALT; + } +#endif + #ifdef HAVE_SW_POWEROFF - if ((btn == POWEROFF_BUTTON + if(btn == POWEROFF_BUTTON #ifdef RC_POWEROFF_BUTTON - || btn == RC_POWEROFF_BUTTON + || btn == RC_POWEROFF_BUTTON #endif - ) && -#if CONFIG_CHARGING && !defined(HAVE_POWEROFF_WHILE_CHARGING) - !charger_inserted() && + ) + button_poweroff(post_btn & BUTTON_REPEAT); #endif - repeat_count > POWEROFF_COUNT) - { - /* Tell the main thread that it's time to - power off */ - sys_poweroff(); - /* Safety net for players without hardware - poweroff */ -#ifndef SIMULATOR - if(repeat_count > POWEROFF_COUNT * 10) - power_off(); +#ifdef HAVE_ALT_MODE + if(alt_mode) + reset_poweroff_timer(); + else #endif - } + { + button_activity(post_btn); + } + + /* Only post repeat events if the queue is empty, + * to avoid afterscroll effects. */ + if((post_btn & BUTTON_REPEAT) && !queue_empty(&button_queue)) + { + ++count; + goto exit; + } + +#ifdef HAVE_ALT_MODE + if(!alt_mode) #endif - } - } - else - { - if (count++ > REPEAT_START) - { - post = true; - repeat = true; - repeat_count = 0; - /* initial repeat */ - count = REPEAT_INTERVAL_START; - } - } - } - if ( post ) - { - if (repeat) - { - /* Only post repeat events if the queue is empty, - * to avoid afterscroll effects. */ - if (queue_empty(&button_queue)) - { - queue_post(&button_queue, BUTTON_REPEAT | btn, data); + { #ifdef HAVE_BACKLIGHT -#ifdef HAVE_REMOTE_LCD - skip_remote_release = false; + if(button_need_skip(post_btn)) + goto exit; #endif - skip_release = false; + } + + queue_post(&button_queue, post_btn, data); + +exit: + lastbtn = btn; +#ifdef HAVE_BUTTON_DATA + lastdata = data; #endif - post = false; - } - } - else - { -#ifdef HAVE_BACKLIGHT +} + +static inline void button_activity(int btn) +{ + if (!(btn & BUTTON_REL)) + { #ifdef HAVE_REMOTE_LCD - if (btn & BUTTON_REMOTE) { - if (!remote_filter_first_keypress - || is_remote_backlight_on(false) -#if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES) - || (remote_type()==REMOTETYPE_H300_NONLCD) + if(btn & BUTTON_REMOTE) + remote_backlight_on(); + else #endif - ) - queue_post(&button_queue, btn, data); - else - skip_remote_release = true; - } - else + { + backlight_on(); +#ifdef HAVE_BUTTON_LIGHT + buttonlight_on(); #endif - if (!filter_first_keypress || is_backlight_on(false) -#if BUTTON_REMOTE - || (btn & BUTTON_REMOTE) + } + reset_poweroff_timer(); + } +} + +#ifdef HAVE_SW_HOLD +bool button_hold(void) +{ + return is_hold; +} #endif - ) - queue_post(&button_queue, btn, data); - else - skip_release = true; -#else /* no backlight, nothing to skip */ - queue_post(&button_queue, btn, data); + +/* Send a SYS_POWEROFF event if we have a device + which doesn't shut down easily with the OFF + key */ +#ifdef HAVE_SW_POWEROFF +static void button_poweroff(bool repeat) +{ + static int count = 0; + + if(repeat) + { + ++count; +#if CONFIG_CHARGING && !defined(HAVE_POWEROFF_WHILE_CHARGING) + if(!charger_inserted()) #endif - post = false; - } -#ifdef HAVE_REMOTE_LCD - if(btn & BUTTON_REMOTE) - remote_backlight_on(); - else + { + /* Tell the main thread that it's time to + power off */ + sys_poweroff(); + + /* Safety net for players without hardware + poweroff */ +#ifndef SIMULATOR + if(count > POWEROFF_COUNT * 10) + power_off(); #endif - { - backlight_on(); -#ifdef HAVE_BUTTON_LIGHT - buttonlight_on(); + } + } + else + count = 0; +} #endif - } - reset_poweroff_timer(); +#ifdef HAVE_BACKLIGHT +static bool button_need_skip(int btn) +{ + static bool skip_release = false; +#ifdef HAVE_REMOTE_LCD + static bool skip_remote_release = false; +#endif + if(btn & BUTTON_REL) + { +#ifdef HAVE_REMOTE_LCD + if(btn & BUTTON_REMOTE) + if(!skip_remote_release) + { + skip_remote_release = false; + return true; } - } else +#endif + if(skip_release) + { + skip_release = false; + return true; + } + } + else if(btn & BUTTON_REPEAT) + { +#ifdef HAVE_REMOTE_LCD + skip_remote_release = false; +#endif + skip_release = false; + } + else + { +#ifdef HAVE_REMOTE_LCD + if (btn & BUTTON_REMOTE) { - repeat = false; - count = 0; + if (remote_filter_first_keypress + && !is_remote_backlight_on(false) +#if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES) + && (remote_type()!=REMOTETYPE_H300_NONLCD) +#endif + ) + { + skip_remote_release = true; + return true; + } } + else +#endif + if (filter_first_keypress && !is_backlight_on(false) +#if BUTTON_REMOTE + && !(btn & BUTTON_REMOTE) +#endif + ) + { + skip_release = true; + return true; + } } - lastbtn = btn & ~(BUTTON_REL | BUTTON_REPEAT); -#ifdef HAVE_BUTTON_DATA - lastdata = data; + return false; +} #endif -} + #ifdef HAVE_ADJUSTABLE_CPU_FREQ static void button_boost(bool state) { @@ -399,6 +503,10 @@ /* hardware inits */ button_init_device(); +#ifdef HAVE_SW_HOLD + is_hold = false; +#endif + #ifdef HAVE_BUTTON_DATA button_read(&temp); lastbtn = button_read(&temp);