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 bool ignore_until_release
= false;
33 static int last_button
= BUTTON_NONE
;
34 static int last_action
= ACTION_NONE
;
35 static bool repeated
= false;
37 /* software keylock stuff */
38 #ifndef HAS_BUTTON_HOLD
39 static bool keys_locked
= false;
40 static int unlock_combo
= BUTTON_NONE
;
41 static bool screen_has_lock
= false;
42 #endif /* HAVE_SOFTWARE_KEYLOCK */
45 * do_button_check is the worker function for get_default_action.
46 * returns ACTION_UNKNOWN or the requested return value from the list.
48 static inline int do_button_check(const struct button_mapping
*items
,
49 int button
, int last_button
, int *start
)
52 int ret
= ACTION_UNKNOWN
;
54 return ACTION_UNKNOWN
;
56 while (items
[i
].button_code
!= BUTTON_NONE
)
58 if (items
[i
].button_code
== button
)
60 if ((items
[i
].pre_button_code
== BUTTON_NONE
)
61 || (items
[i
].pre_button_code
== last_button
))
63 ret
= items
[i
].action_code
;
73 static inline int get_next_context(const struct button_mapping
*items
, int i
)
75 while (items
[i
].button_code
!= BUTTON_NONE
)
77 return (items
[i
].action_code
== ACTION_NONE
) ?
82 * int get_action_worker(int context, struct button_mapping *user_mappings,
84 This function searches the button list for the given context for the just
86 If there is a match it returns the value from the list.
87 If there is no match..
88 the last item in the list "points" to the next context in a chain
89 so the "chain" is followed until the button is found.
90 putting ACTION_NONE will get CONTEXT_STD which is always the last list checked.
92 Timeout can be TIMEOUT_NOBLOCK to return immediatly
93 TIMEOUT_BLOCK to wait for a button press
94 Any number >0 to wait that many ticks for a press
97 static int get_action_worker(int context
, int timeout
,
98 const struct button_mapping
* (*get_context_map
)(int) )
100 const struct button_mapping
*items
= NULL
;
103 int ret
= ACTION_UNKNOWN
;
105 if (timeout
== TIMEOUT_NOBLOCK
)
106 button
= button_get(false);
107 else if (timeout
== TIMEOUT_BLOCK
)
108 button
= button_get(true);
110 button
= button_get_w_tmo(timeout
);
112 if (button
== BUTTON_NONE
|| button
&SYS_EVENT
)
117 if (ignore_until_release
== true)
119 if (button
&BUTTON_REL
)
121 ignore_until_release
= false;
123 return ACTION_NONE
; /* "safest" return value */
126 #ifndef HAS_BUTTON_HOLD
127 screen_has_lock
= ((context
&ALLOW_SOFTLOCK
)==ALLOW_SOFTLOCK
);
128 if (screen_has_lock
&& (keys_locked
== true))
130 if (button
== unlock_combo
)
132 last_button
= BUTTON_NONE
;
134 gui_syncsplash(HZ
/2, str(LANG_KEYLOCK_OFF_PLAYER
));
135 return ACTION_REDRAW
;
138 #if (BUTTON_REMOTE != 0)
139 if ((button
&BUTTON_REMOTE
) == 0)
142 if ((button
&BUTTON_REL
))
143 gui_syncsplash(HZ
/2, str(LANG_KEYLOCK_ON_PLAYER
));
144 return ACTION_REDRAW
;
147 context
&= ~ALLOW_SOFTLOCK
;
148 #endif /* HAS_BUTTON_HOLD */
150 /* logf("%x,%x",last_button,button); */
153 /* logf("context = %x",context); */
154 #if (BUTTON_REMOTE != 0)
155 if (button
&BUTTON_REMOTE
)
156 context
|= CONTEXT_REMOTE
;
158 if ((context
&CONTEXT_CUSTOM
) && get_context_map
)
159 items
= get_context_map(context
);
161 items
= get_context_mapping(context
);
163 ret
= do_button_check(items
,button
,last_button
,&i
);
165 if ((context
==(int)CONTEXT_STOPSEARCHING
) ||
169 if (ret
== ACTION_UNKNOWN
)
171 context
= get_next_context(items
,i
);
176 /* DEBUGF("ret = %x\n",ret); */
177 #ifndef HAS_BUTTON_HOLD
178 if (screen_has_lock
&& (ret
== ACTION_STD_KEYLOCK
))
180 unlock_combo
= button
;
182 action_signalscreenchange();
183 gui_syncsplash(HZ
/2, str(LANG_KEYLOCK_ON_PLAYER
));
185 button_clear_queue();
186 return ACTION_REDRAW
;
189 if (ret
== last_action
)
194 last_button
= button
;
199 int get_action(int context
, int timeout
)
201 return get_action_worker(context
,timeout
,NULL
);
204 int get_custom_action(int context
,int timeout
,
205 const struct button_mapping
* (*get_context_map
)(int))
207 return get_action_worker(context
,timeout
,get_context_map
);
210 bool action_userabort(int timeout
)
212 action_signalscreenchange();
213 int action
= get_action_worker(CONTEXT_STD
,timeout
,NULL
);
214 bool ret
= (action
== ACTION_STD_CANCEL
);
215 action_signalscreenchange();
219 void action_signalscreenchange(void)
221 if ((last_button
!= BUTTON_NONE
) &&
222 !(last_button
&BUTTON_REL
))
224 ignore_until_release
= true;
226 last_button
= BUTTON_NONE
;
228 #ifndef HAS_BUTTON_HOLD
229 bool is_keys_locked(void)
231 return (screen_has_lock
&& (keys_locked
== true));
235 int get_action_statuscode(int *button
)
239 *button
= last_button
;
241 if (last_button
&BUTTON_REMOTE
)
242 ret
|= ACTION_REMOTE
;
244 ret
|= ACTION_REPEAT
;
245 if (ignore_until_release
)
246 ret
|= ACTION_IGNORING
;