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 int last_action
= ACTION_NONE
;
35 static bool repeated
= false;
37 #define REPEAT_WINDOW_TICKS HZ/10
38 static int last_action_tick
= 0;
40 /* software keylock stuff */
41 #ifndef HAS_BUTTON_HOLD
42 static bool keys_locked
= false;
43 static int unlock_combo
= BUTTON_NONE
;
44 static bool screen_has_lock
= false;
45 #endif /* HAVE_SOFTWARE_KEYLOCK */
48 * do_button_check is the worker function for get_default_action.
49 * returns ACTION_UNKNOWN or the requested return value from the list.
51 static inline int do_button_check(const struct button_mapping
*items
,
52 int button
, int last_button
, int *start
)
55 int ret
= ACTION_UNKNOWN
;
57 return ACTION_UNKNOWN
;
59 while (items
[i
].button_code
!= BUTTON_NONE
)
61 if (items
[i
].button_code
== button
)
63 if ((items
[i
].pre_button_code
== BUTTON_NONE
)
64 || (items
[i
].pre_button_code
== last_button
))
66 ret
= items
[i
].action_code
;
76 static inline int get_next_context(const struct button_mapping
*items
, int i
)
78 while (items
[i
].button_code
!= BUTTON_NONE
)
80 return (items
[i
].action_code
== ACTION_NONE
) ?
85 * int get_action_worker(int context, struct button_mapping *user_mappings,
87 This function searches the button list for the given context for the just
89 If there is a match it returns the value from the list.
90 If there is no match..
91 the last item in the list "points" to the next context in a chain
92 so the "chain" is followed until the button is found.
93 putting ACTION_NONE will get CONTEXT_STD which is always the last list checked.
95 Timeout can be TIMEOUT_NOBLOCK to return immediatly
96 TIMEOUT_BLOCK to wait for a button press
97 Any number >0 to wait that many ticks for a press
100 static int get_action_worker(int context
, int timeout
,
101 const struct button_mapping
* (*get_context_map
)(int) )
103 const struct button_mapping
*items
= NULL
;
106 int ret
= ACTION_UNKNOWN
;
107 static int last_context
= CONTEXT_STD
;
109 if (timeout
== TIMEOUT_NOBLOCK
)
110 button
= button_get(false);
111 else if (timeout
== TIMEOUT_BLOCK
)
112 button
= button_get(true);
114 button
= button_get_w_tmo(timeout
);
116 if (button
== BUTTON_NONE
|| button
&SYS_EVENT
)
121 if ((context
!= last_context
) && ((last_button
&BUTTON_REL
) == 0))
123 if (button
&BUTTON_REL
)
125 last_button
= button
;
126 last_action
= ACTION_NONE
;
128 /* eat all buttons until the previous button was |BUTTON_REL
129 (also eat the |BUTTON_REL button) */
130 return ACTION_NONE
; /* "safest" return value */
132 last_context
= context
;
134 #ifndef HAS_BUTTON_HOLD
135 screen_has_lock
= ((context
&ALLOW_SOFTLOCK
)==ALLOW_SOFTLOCK
);
136 if (screen_has_lock
&& (keys_locked
== true))
138 if (button
== unlock_combo
)
140 last_button
= BUTTON_NONE
;
142 gui_syncsplash(HZ
/2, str(LANG_KEYLOCK_OFF_PLAYER
));
143 return ACTION_REDRAW
;
146 #if (BUTTON_REMOTE != 0)
147 if ((button
&BUTTON_REMOTE
) == 0)
150 if ((button
&BUTTON_REL
))
151 gui_syncsplash(HZ
/2, str(LANG_KEYLOCK_ON_PLAYER
));
152 return ACTION_REDRAW
;
155 context
&= ~ALLOW_SOFTLOCK
;
156 #endif /* HAS_BUTTON_HOLD */
158 /* logf("%x,%x",last_button,button); */
161 /* logf("context = %x",context); */
162 #if (BUTTON_REMOTE != 0)
163 if (button
&BUTTON_REMOTE
)
164 context
|= CONTEXT_REMOTE
;
166 if ((context
&CONTEXT_CUSTOM
) && get_context_map
)
167 items
= get_context_map(context
);
169 items
= get_context_mapping(context
);
171 ret
= do_button_check(items
,button
,last_button
,&i
);
173 if ((context
==(int)CONTEXT_STOPSEARCHING
) ||
177 if (ret
== ACTION_UNKNOWN
)
179 context
= get_next_context(items
,i
);
184 /* DEBUGF("ret = %x\n",ret); */
185 #ifndef HAS_BUTTON_HOLD
186 if (screen_has_lock
&& (ret
== ACTION_STD_KEYLOCK
))
188 unlock_combo
= button
;
190 gui_syncsplash(HZ
/2, str(LANG_KEYLOCK_ON_PLAYER
));
192 button_clear_queue();
193 return ACTION_REDRAW
;
196 if ((current_tick
- last_action_tick
< REPEAT_WINDOW_TICKS
)
197 && (ret
== last_action
))
202 last_button
= button
;
204 last_action_tick
= current_tick
;
208 int get_action(int context
, int timeout
)
210 return get_action_worker(context
,timeout
,NULL
);
213 int get_custom_action(int context
,int timeout
,
214 const struct button_mapping
* (*get_context_map
)(int))
216 return get_action_worker(context
,timeout
,get_context_map
);
219 bool action_userabort(int timeout
)
221 int action
= get_action_worker(CONTEXT_STD
,timeout
,NULL
);
222 bool ret
= (action
== ACTION_STD_CANCEL
);
226 #ifndef HAS_BUTTON_HOLD
227 bool is_keys_locked(void)
229 return (screen_has_lock
&& (keys_locked
== true));
233 int get_action_statuscode(int *button
)
237 *button
= last_button
;
239 if (last_button
&BUTTON_REMOTE
)
240 ret
|= ACTION_REMOTE
;
242 ret
|= ACTION_REPEAT
;