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 ****************************************************************************/
32 static int last_button
= BUTTON_NONE
|BUTTON_REL
; /* allow the ipod wheel to
34 static intptr_t last_data
= 0;
35 static int last_action
= ACTION_NONE
;
36 static bool repeated
= false;
39 static bool short_press
= false;
42 #define REPEAT_WINDOW_TICKS HZ/10
43 static int last_action_tick
= 0;
45 /* software keylock stuff */
46 #ifndef HAS_BUTTON_HOLD
47 static bool keys_locked
= false;
48 static int unlock_combo
= BUTTON_NONE
;
49 static bool screen_has_lock
= false;
50 #endif /* HAVE_SOFTWARE_KEYLOCK */
53 * do_button_check is the worker function for get_default_action.
54 * returns ACTION_UNKNOWN or the requested return value from the list.
56 static inline int do_button_check(const struct button_mapping
*items
,
57 int button
, int last_button
, int *start
)
60 int ret
= ACTION_UNKNOWN
;
62 return ACTION_UNKNOWN
;
64 while (items
[i
].button_code
!= BUTTON_NONE
)
66 if (items
[i
].button_code
== button
)
68 if ((items
[i
].pre_button_code
== BUTTON_NONE
)
69 || (items
[i
].pre_button_code
== last_button
))
71 ret
= items
[i
].action_code
;
81 static inline int get_next_context(const struct button_mapping
*items
, int i
)
83 while (items
[i
].button_code
!= BUTTON_NONE
)
85 return (items
[i
].action_code
== ACTION_NONE
) ?
90 * int get_action_worker(int context, struct button_mapping *user_mappings,
92 This function searches the button list for the given context for the just
94 If there is a match it returns the value from the list.
95 If there is no match..
96 the last item in the list "points" to the next context in a chain
97 so the "chain" is followed until the button is found.
98 putting ACTION_NONE will get CONTEXT_STD which is always the last list checked.
100 Timeout can be TIMEOUT_NOBLOCK to return immediatly
101 TIMEOUT_BLOCK to wait for a button press
102 Any number >0 to wait that many ticks for a press
105 static int get_action_worker(int context
, int timeout
,
106 const struct button_mapping
* (*get_context_map
)(int) )
108 const struct button_mapping
*items
= NULL
;
111 int ret
= ACTION_UNKNOWN
;
112 static int last_context
= CONTEXT_STD
;
114 if (timeout
== TIMEOUT_NOBLOCK
)
115 button
= button_get(false);
116 else if (timeout
== TIMEOUT_BLOCK
)
117 button
= button_get(true);
119 button
= button_get_w_tmo(timeout
);
121 /* Data from sys events can be pulled with button_get_data */
122 if (button
== BUTTON_NONE
|| button
&SYS_EVENT
)
127 if ((context
!= last_context
) && ((last_button
&BUTTON_REL
) == 0))
129 if (button
&BUTTON_REL
)
131 last_button
= button
;
132 last_action
= ACTION_NONE
;
134 /* eat all buttons until the previous button was |BUTTON_REL
135 (also eat the |BUTTON_REL button) */
136 return ACTION_NONE
; /* "safest" return value */
138 last_context
= context
;
140 if (button
&BUTTON_TOUCHPAD
)
144 if (last_button
&BUTTON_TOUCHPAD
)
146 if ((button
&BUTTON_REL
) &&
147 ((last_button
&BUTTON_REPEAT
)==0))
151 else if (button
&BUTTON_REPEAT
)
154 last_button
= button
;
155 return ACTION_TOUCHPAD
;
158 #ifndef HAS_BUTTON_HOLD
159 screen_has_lock
= ((context
&ALLOW_SOFTLOCK
)==ALLOW_SOFTLOCK
);
160 if (screen_has_lock
&& (keys_locked
== true))
162 if (button
== unlock_combo
)
164 last_button
= BUTTON_NONE
;
166 gui_syncsplash(HZ
/2, str(LANG_KEYLOCK_OFF
));
167 return ACTION_REDRAW
;
170 #if (BUTTON_REMOTE != 0)
171 if ((button
&BUTTON_REMOTE
) == 0)
174 if ((button
&BUTTON_REL
))
175 gui_syncsplash(HZ
/2, str(LANG_KEYLOCK_ON
));
176 return ACTION_REDRAW
;
179 context
&= ~ALLOW_SOFTLOCK
;
180 #endif /* HAS_BUTTON_HOLD */
182 /* logf("%x,%x",last_button,button); */
185 /* logf("context = %x",context); */
186 #if (BUTTON_REMOTE != 0)
187 if (button
&BUTTON_REMOTE
)
188 context
|= CONTEXT_REMOTE
;
190 if ((context
&CONTEXT_CUSTOM
) && get_context_map
)
191 items
= get_context_map(context
);
193 items
= get_context_mapping(context
);
195 ret
= do_button_check(items
,button
,last_button
,&i
);
197 if ((context
==(int)CONTEXT_STOPSEARCHING
) ||
201 if (ret
== ACTION_UNKNOWN
)
203 context
= get_next_context(items
,i
);
208 /* DEBUGF("ret = %x\n",ret); */
209 #ifndef HAS_BUTTON_HOLD
210 if (screen_has_lock
&& (ret
== ACTION_STD_KEYLOCK
))
212 unlock_combo
= button
;
214 gui_syncsplash(HZ
/2, str(LANG_KEYLOCK_ON
));
216 button_clear_queue();
217 return ACTION_REDRAW
;
220 if ((current_tick
- last_action_tick
< REPEAT_WINDOW_TICKS
)
221 && (ret
== last_action
))
226 last_button
= button
;
228 last_data
= button_get_data();
229 last_action_tick
= current_tick
;
233 int get_action(int context
, int timeout
)
235 return get_action_worker(context
,timeout
,NULL
);
238 int get_custom_action(int context
,int timeout
,
239 const struct button_mapping
* (*get_context_map
)(int))
241 return get_action_worker(context
,timeout
,get_context_map
);
244 bool action_userabort(int timeout
)
246 int action
= get_action_worker(CONTEXT_STD
,timeout
,NULL
);
247 bool ret
= (action
== ACTION_STD_CANCEL
);
251 #ifndef HAS_BUTTON_HOLD
252 bool is_keys_locked(void)
254 return (screen_has_lock
&& (keys_locked
== true));
258 intptr_t get_action_data(void)
263 int get_action_statuscode(int *button
)
267 *button
= last_button
;
269 if (last_button
&BUTTON_REMOTE
)
270 ret
|= ACTION_REMOTE
;
272 ret
|= ACTION_REPEAT
;
277 /* return BUTTON_NONE on error
278 BUTTON_REPEAT if repeated press
279 BUTTON_REL if its a short press
280 BUTTON_TOUCHPAD otherwise
282 int action_get_touchpad_press(short *x
, short *y
)
284 static int last_data
= 0;
286 if ((last_button
&BUTTON_TOUCHPAD
) == 0)
288 data
= button_get_data();
289 if (last_button
&BUTTON_REL
)
291 *x
= (last_data
&0xffff0000)>>16;
292 *y
= (last_data
&0xffff);
296 *x
= (data
&0xffff0000)>>16;
301 return BUTTON_REPEAT
;
304 return BUTTON_TOUCHPAD
;