1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2006 Jonathan Gordon
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
34 static int last_button
= BUTTON_NONE
|BUTTON_REL
; /* allow the ipod wheel to
36 static intptr_t last_data
= 0;
37 static int last_action
= ACTION_NONE
;
38 static bool repeated
= false;
41 static bool short_press
= false;
44 #define REPEAT_WINDOW_TICKS HZ/10
45 static int last_action_tick
= 0;
47 /* software keylock stuff */
48 #ifndef HAS_BUTTON_HOLD
49 static bool keys_locked
= false;
50 static int unlock_combo
= BUTTON_NONE
;
51 static bool screen_has_lock
= false;
52 #endif /* HAVE_SOFTWARE_KEYLOCK */
55 * do_button_check is the worker function for get_default_action.
56 * returns ACTION_UNKNOWN or the requested return value from the list.
58 static inline int do_button_check(const struct button_mapping
*items
,
59 int button
, int last_button
, int *start
)
62 int ret
= ACTION_UNKNOWN
;
64 return ACTION_UNKNOWN
;
66 while (items
[i
].button_code
!= BUTTON_NONE
)
68 if (items
[i
].button_code
== button
)
70 if ((items
[i
].pre_button_code
== BUTTON_NONE
)
71 || (items
[i
].pre_button_code
== last_button
))
73 ret
= items
[i
].action_code
;
83 static inline int get_next_context(const struct button_mapping
*items
, int i
)
85 while (items
[i
].button_code
!= BUTTON_NONE
)
87 return (items
[i
].action_code
== ACTION_NONE
) ?
92 * int get_action_worker(int context, struct button_mapping *user_mappings,
94 This function searches the button list for the given context for the just
96 If there is a match it returns the value from the list.
97 If there is no match..
98 the last item in the list "points" to the next context in a chain
99 so the "chain" is followed until the button is found.
100 putting ACTION_NONE will get CONTEXT_STD which is always the last list checked.
102 Timeout can be TIMEOUT_NOBLOCK to return immediatly
103 TIMEOUT_BLOCK to wait for a button press
104 Any number >0 to wait that many ticks for a press
107 static int get_action_worker(int context
, int timeout
,
108 const struct button_mapping
* (*get_context_map
)(int) )
110 const struct button_mapping
*items
= NULL
;
113 int ret
= ACTION_UNKNOWN
;
114 static int last_context
= CONTEXT_STD
;
116 if (timeout
== TIMEOUT_NOBLOCK
)
117 button
= button_get(false);
118 else if (timeout
== TIMEOUT_BLOCK
)
119 button
= button_get(true);
121 button
= button_get_w_tmo(timeout
);
123 /* Data from sys events can be pulled with button_get_data */
124 if (button
== BUTTON_NONE
|| button
& SYS_EVENT
)
127 #if CONFIG_CODEC == SWCODEC
128 /* Produce keyclick */
129 if (global_settings
.keyclick
&& !(button
& BUTTON_REL
))
130 if (!(button
& BUTTON_REPEAT
) || global_settings
.keyclick_repeats
)
131 pcmbuf_beep(5000, 2, 2500*global_settings
.keyclick
);
134 if ((context
!= last_context
) && ((last_button
& BUTTON_REL
) == 0))
136 if (button
& BUTTON_REL
)
138 last_button
= button
;
139 last_action
= ACTION_NONE
;
141 /* eat all buttons until the previous button was |BUTTON_REL
142 (also eat the |BUTTON_REL button) */
143 return ACTION_NONE
; /* "safest" return value */
145 last_context
= context
;
147 if (button
& BUTTON_TOUCHPAD
)
151 if (last_button
& BUTTON_TOUCHPAD
)
153 if ((button
& BUTTON_REL
) &&
154 ((last_button
& BUTTON_REPEAT
)==0))
158 else if (button
& BUTTON_REPEAT
)
161 last_button
= button
;
162 return ACTION_TOUCHPAD
;
165 #ifndef HAS_BUTTON_HOLD
166 screen_has_lock
= ((context
& ALLOW_SOFTLOCK
) == ALLOW_SOFTLOCK
);
167 if (screen_has_lock
&& (keys_locked
== true))
169 if (button
== unlock_combo
)
171 last_button
= BUTTON_NONE
;
173 gui_syncsplash(HZ
/2, str(LANG_KEYLOCK_OFF
));
174 return ACTION_REDRAW
;
177 #if (BUTTON_REMOTE != 0)
178 if ((button
& BUTTON_REMOTE
) == 0)
181 if ((button
& BUTTON_REL
))
182 gui_syncsplash(HZ
/2, str(LANG_KEYLOCK_ON
));
183 return ACTION_REDRAW
;
186 context
&= ~ALLOW_SOFTLOCK
;
187 #endif /* HAS_BUTTON_HOLD */
189 /* logf("%x,%x",last_button,button); */
192 /* logf("context = %x",context); */
193 #if (BUTTON_REMOTE != 0)
194 if (button
& BUTTON_REMOTE
)
195 context
|= CONTEXT_REMOTE
;
197 if ((context
& CONTEXT_CUSTOM
) && get_context_map
)
198 items
= get_context_map(context
);
200 items
= get_context_mapping(context
);
202 ret
= do_button_check(items
,button
,last_button
,&i
);
204 if ((context
==(int)CONTEXT_STOPSEARCHING
) ||
208 if (ret
== ACTION_UNKNOWN
)
210 context
= get_next_context(items
,i
);
215 /* DEBUGF("ret = %x\n",ret); */
216 #ifndef HAS_BUTTON_HOLD
217 if (screen_has_lock
&& (ret
== ACTION_STD_KEYLOCK
))
219 unlock_combo
= button
;
221 gui_syncsplash(HZ
/2, str(LANG_KEYLOCK_ON
));
223 button_clear_queue();
224 return ACTION_REDRAW
;
227 if ((current_tick
- last_action_tick
< REPEAT_WINDOW_TICKS
)
228 && (ret
== last_action
))
233 last_button
= button
;
235 last_data
= button_get_data();
236 last_action_tick
= current_tick
;
240 int get_action(int context
, int timeout
)
242 return get_action_worker(context
,timeout
,NULL
);
245 int get_custom_action(int context
,int timeout
,
246 const struct button_mapping
* (*get_context_map
)(int))
248 return get_action_worker(context
,timeout
,get_context_map
);
251 bool action_userabort(int timeout
)
253 int action
= get_action_worker(CONTEXT_STD
,timeout
,NULL
);
254 bool ret
= (action
== ACTION_STD_CANCEL
);
258 #ifndef HAS_BUTTON_HOLD
259 bool is_keys_locked(void)
261 return (screen_has_lock
&& (keys_locked
== true));
265 intptr_t get_action_data(void)
270 int get_action_statuscode(int *button
)
274 *button
= last_button
;
276 if (last_button
& BUTTON_REMOTE
)
277 ret
|= ACTION_REMOTE
;
279 ret
|= ACTION_REPEAT
;
284 /* return BUTTON_NONE on error
285 BUTTON_REPEAT if repeated press
286 BUTTON_REL if its a short press
287 BUTTON_TOUCHPAD otherwise
289 int action_get_touchpad_press(short *x
, short *y
)
291 static int last_data
= 0;
293 if ((last_button
& BUTTON_TOUCHPAD
) == 0)
295 data
= button_get_data();
296 if (last_button
& BUTTON_REL
)
298 *x
= (last_data
&0xffff0000)>>16;
299 *y
= (last_data
&0xffff);
303 *x
= (data
&0xffff0000)>>16;
308 return BUTTON_REPEAT
;
311 return BUTTON_TOUCHPAD
;