VBRfix description, part 2: actually this note was way outdated. Files recorded with...
[kugel-rb.git] / apps / action.c
blob80053e76467ccb46d9ecf2c205098683fc8a2032
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
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 ****************************************************************************/
19 #include <stdio.h>
20 #include <string.h>
21 #include <stdlib.h>
23 #include "config.h"
24 #include "lang.h"
26 #include "button.h"
27 #include "action.h"
28 #include "kernel.h"
29 #include "debug.h"
30 #include "splash.h"
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)
51 int i = 0;
52 int ret = ACTION_UNKNOWN;
53 if (items == NULL)
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;
64 break;
67 i++;
69 *start = i;
70 return ret;
73 static inline int get_next_context(const struct button_mapping *items, int i)
75 while (items[i].button_code != BUTTON_NONE)
76 i++;
77 return (items[i].action_code == ACTION_NONE ) ?
78 CONTEXT_STD :
79 items[i].action_code;
82 * int get_action_worker(int context, struct button_mapping *user_mappings,
83 int timeout)
84 This function searches the button list for the given context for the just
85 pressed button.
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;
101 int button;
102 int i=0;
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);
109 else
110 button = button_get_w_tmo(timeout);
112 if (button == BUTTON_NONE || button&SYS_EVENT)
114 return button;
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;
133 keys_locked = false;
134 gui_syncsplash(HZ/2, str(LANG_KEYLOCK_OFF_PLAYER));
135 return ACTION_REDRAW;
137 else
138 #if (BUTTON_REMOTE != 0)
139 if ((button&BUTTON_REMOTE) == 0)
140 #endif
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;
157 #endif
158 if ((context&CONTEXT_CUSTOM) && get_context_map)
159 items = get_context_map(context);
160 else
161 items = get_context_mapping(context);
163 ret = do_button_check(items,button,last_button,&i);
165 if ((context ==(int)CONTEXT_STOPSEARCHING) ||
166 items == NULL )
167 break;
169 if (ret == ACTION_UNKNOWN )
171 context = get_next_context(items,i);
172 i = 0;
174 else break;
175 } while (1);
176 /* DEBUGF("ret = %x\n",ret); */
177 #ifndef HAS_BUTTON_HOLD
178 if (screen_has_lock && (ret == ACTION_STD_KEYLOCK))
180 unlock_combo = button;
181 keys_locked = true;
182 action_signalscreenchange();
183 gui_syncsplash(HZ/2, str(LANG_KEYLOCK_ON_PLAYER));
185 button_clear_queue();
186 return ACTION_REDRAW;
188 #endif
189 if (ret == last_action)
190 repeated = true;
191 else
192 repeated = false;
194 last_button = button;
195 last_action = ret;
196 return ret;
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();
216 return ret;
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));
233 #endif
235 int get_action_statuscode(int *button)
237 int ret = 0;
238 if (button)
239 *button = last_button;
241 if (last_button&BUTTON_REMOTE)
242 ret |= ACTION_REMOTE;
243 if (repeated)
244 ret |= ACTION_REPEAT;
245 if (ignore_until_release)
246 ret |= ACTION_IGNORING;
247 return ret;