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;
38 #define REPEAT_WINDOW_TICKS HZ/10
39 static int last_action_tick
= 0;
41 /* software keylock stuff */
42 #ifndef HAS_BUTTON_HOLD
43 static bool keys_locked
= false;
44 static int unlock_combo
= BUTTON_NONE
;
45 static bool screen_has_lock
= false;
46 #endif /* HAVE_SOFTWARE_KEYLOCK */
49 * do_button_check is the worker function for get_default_action.
50 * returns ACTION_UNKNOWN or the requested return value from the list.
52 static inline int do_button_check(const struct button_mapping
*items
,
53 int button
, int last_button
, int *start
)
56 int ret
= ACTION_UNKNOWN
;
58 return ACTION_UNKNOWN
;
60 while (items
[i
].button_code
!= BUTTON_NONE
)
62 if (items
[i
].button_code
== button
)
64 if ((items
[i
].pre_button_code
== BUTTON_NONE
)
65 || (items
[i
].pre_button_code
== last_button
))
67 ret
= items
[i
].action_code
;
77 static inline int get_next_context(const struct button_mapping
*items
, int i
)
79 while (items
[i
].button_code
!= BUTTON_NONE
)
81 return (items
[i
].action_code
== ACTION_NONE
) ?
86 * int get_action_worker(int context, struct button_mapping *user_mappings,
88 This function searches the button list for the given context for the just
90 If there is a match it returns the value from the list.
91 If there is no match..
92 the last item in the list "points" to the next context in a chain
93 so the "chain" is followed until the button is found.
94 putting ACTION_NONE will get CONTEXT_STD which is always the last list checked.
96 Timeout can be TIMEOUT_NOBLOCK to return immediatly
97 TIMEOUT_BLOCK to wait for a button press
98 Any number >0 to wait that many ticks for a press
101 static int get_action_worker(int context
, int timeout
,
102 const struct button_mapping
* (*get_context_map
)(int) )
104 const struct button_mapping
*items
= NULL
;
107 int ret
= ACTION_UNKNOWN
;
108 static int last_context
= CONTEXT_STD
;
110 if (timeout
== TIMEOUT_NOBLOCK
)
111 button
= button_get(false);
112 else if (timeout
== TIMEOUT_BLOCK
)
113 button
= button_get(true);
115 button
= button_get_w_tmo(timeout
);
117 /* Data from sys events can be pulled with button_get_data */
118 if (button
== BUTTON_NONE
|| button
&SYS_EVENT
)
123 if ((context
!= last_context
) && ((last_button
&BUTTON_REL
) == 0))
125 if (button
&BUTTON_REL
)
127 last_button
= button
;
128 last_action
= ACTION_NONE
;
130 /* eat all buttons until the previous button was |BUTTON_REL
131 (also eat the |BUTTON_REL button) */
132 return ACTION_NONE
; /* "safest" return value */
134 last_context
= context
;
136 #ifndef HAS_BUTTON_HOLD
137 screen_has_lock
= ((context
&ALLOW_SOFTLOCK
)==ALLOW_SOFTLOCK
);
138 if (screen_has_lock
&& (keys_locked
== true))
140 if (button
== unlock_combo
)
142 last_button
= BUTTON_NONE
;
144 gui_syncsplash(HZ
/2, str(LANG_KEYLOCK_OFF
));
145 return ACTION_REDRAW
;
148 #if (BUTTON_REMOTE != 0)
149 if ((button
&BUTTON_REMOTE
) == 0)
152 if ((button
&BUTTON_REL
))
153 gui_syncsplash(HZ
/2, str(LANG_KEYLOCK_ON
));
154 return ACTION_REDRAW
;
157 context
&= ~ALLOW_SOFTLOCK
;
158 #endif /* HAS_BUTTON_HOLD */
160 /* logf("%x,%x",last_button,button); */
163 /* logf("context = %x",context); */
164 #if (BUTTON_REMOTE != 0)
165 if (button
&BUTTON_REMOTE
)
166 context
|= CONTEXT_REMOTE
;
168 if ((context
&CONTEXT_CUSTOM
) && get_context_map
)
169 items
= get_context_map(context
);
171 items
= get_context_mapping(context
);
173 ret
= do_button_check(items
,button
,last_button
,&i
);
175 if ((context
==(int)CONTEXT_STOPSEARCHING
) ||
179 if (ret
== ACTION_UNKNOWN
)
181 context
= get_next_context(items
,i
);
186 /* DEBUGF("ret = %x\n",ret); */
187 #ifndef HAS_BUTTON_HOLD
188 if (screen_has_lock
&& (ret
== ACTION_STD_KEYLOCK
))
190 unlock_combo
= button
;
192 gui_syncsplash(HZ
/2, str(LANG_KEYLOCK_ON
));
194 button_clear_queue();
195 return ACTION_REDRAW
;
198 if ((current_tick
- last_action_tick
< REPEAT_WINDOW_TICKS
)
199 && (ret
== last_action
))
204 last_button
= button
;
206 last_data
= button_get_data();
207 last_action_tick
= current_tick
;
211 int get_action(int context
, int timeout
)
213 return get_action_worker(context
,timeout
,NULL
);
216 int get_custom_action(int context
,int timeout
,
217 const struct button_mapping
* (*get_context_map
)(int))
219 return get_action_worker(context
,timeout
,get_context_map
);
222 bool action_userabort(int timeout
)
224 int action
= get_action_worker(CONTEXT_STD
,timeout
,NULL
);
225 bool ret
= (action
== ACTION_STD_CANCEL
);
229 #ifndef HAS_BUTTON_HOLD
230 bool is_keys_locked(void)
232 return (screen_has_lock
&& (keys_locked
== true));
236 intptr_t get_action_data(void)
241 int get_action_statuscode(int *button
)
245 *button
= last_button
;
247 if (last_button
&BUTTON_REMOTE
)
248 ret
|= ACTION_REMOTE
;
250 ret
|= ACTION_REPEAT
;