if a proxy is set, pre-fill the proxy setting dialog with the old value.
[Rockbox.git] / apps / action.c
blobd9f04a8c898c87b59159f77c8b8a6d2edbaae2cf
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 #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)
54 int i = 0;
55 int ret = ACTION_UNKNOWN;
56 if (items == NULL)
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;
67 break;
70 i++;
72 *start = i;
73 return ret;
76 static inline int get_next_context(const struct button_mapping *items, int i)
78 while (items[i].button_code != BUTTON_NONE)
79 i++;
80 return (items[i].action_code == ACTION_NONE ) ?
81 CONTEXT_STD :
82 items[i].action_code;
85 * int get_action_worker(int context, struct button_mapping *user_mappings,
86 int timeout)
87 This function searches the button list for the given context for the just
88 pressed button.
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;
104 int button;
105 int i=0;
106 int ret = ACTION_UNKNOWN;
108 if (timeout == TIMEOUT_NOBLOCK)
109 button = button_get(false);
110 else if (timeout == TIMEOUT_BLOCK)
111 button = button_get(true);
112 else
113 button = button_get_w_tmo(timeout);
115 if (button == BUTTON_NONE || button&SYS_EVENT)
117 return button;
120 if (ignore_until_release == true)
122 if (button&BUTTON_REL)
124 ignore_until_release = false;
126 return ACTION_NONE; /* "safest" return value */
129 #ifndef HAS_BUTTON_HOLD
130 screen_has_lock = ((context&ALLOW_SOFTLOCK)==ALLOW_SOFTLOCK);
131 if (screen_has_lock && (keys_locked == true))
133 if (button == unlock_combo)
135 last_button = BUTTON_NONE;
136 keys_locked = false;
137 gui_syncsplash(HZ/2, str(LANG_KEYLOCK_OFF_PLAYER));
138 return ACTION_REDRAW;
140 else
141 #if (BUTTON_REMOTE != 0)
142 if ((button&BUTTON_REMOTE) == 0)
143 #endif
145 if ((button&BUTTON_REL))
146 gui_syncsplash(HZ/2, str(LANG_KEYLOCK_ON_PLAYER));
147 return ACTION_REDRAW;
150 context &= ~ALLOW_SOFTLOCK;
151 #endif /* HAS_BUTTON_HOLD */
153 /* logf("%x,%x",last_button,button); */
156 /* logf("context = %x",context); */
157 #if (BUTTON_REMOTE != 0)
158 if (button&BUTTON_REMOTE)
159 context |= CONTEXT_REMOTE;
160 #endif
161 if ((context&CONTEXT_CUSTOM) && get_context_map)
162 items = get_context_map(context);
163 else
164 items = get_context_mapping(context);
166 ret = do_button_check(items,button,last_button,&i);
168 if ((context ==(int)CONTEXT_STOPSEARCHING) ||
169 items == NULL )
170 break;
172 if (ret == ACTION_UNKNOWN )
174 context = get_next_context(items,i);
175 i = 0;
177 else break;
178 } while (1);
179 /* DEBUGF("ret = %x\n",ret); */
180 #ifndef HAS_BUTTON_HOLD
181 if (screen_has_lock && (ret == ACTION_STD_KEYLOCK))
183 unlock_combo = button;
184 keys_locked = true;
185 action_signalscreenchange();
186 gui_syncsplash(HZ/2, str(LANG_KEYLOCK_ON_PLAYER));
188 button_clear_queue();
189 return ACTION_REDRAW;
191 #endif
192 if ((current_tick - last_action_tick < REPEAT_WINDOW_TICKS)
193 && (ret == last_action))
194 repeated = true;
195 else
196 repeated = false;
198 last_button = button;
199 last_action = ret;
200 last_action_tick = current_tick;
201 return ret;
204 int get_action(int context, int timeout)
206 return get_action_worker(context,timeout,NULL);
209 int get_custom_action(int context,int timeout,
210 const struct button_mapping* (*get_context_map)(int))
212 return get_action_worker(context,timeout,get_context_map);
215 bool action_userabort(int timeout)
217 action_signalscreenchange();
218 int action = get_action_worker(CONTEXT_STD,timeout,NULL);
219 bool ret = (action == ACTION_STD_CANCEL);
220 action_signalscreenchange();
221 return ret;
224 void action_signalscreenchange(void)
226 if ((last_button != BUTTON_NONE) &&
227 !(last_button&BUTTON_REL))
229 ignore_until_release = true;
231 last_button = BUTTON_NONE;
233 #ifndef HAS_BUTTON_HOLD
234 bool is_keys_locked(void)
236 return (screen_has_lock && (keys_locked == true));
238 #endif
240 int get_action_statuscode(int *button)
242 int ret = 0;
243 if (button)
244 *button = last_button;
246 if (last_button&BUTTON_REMOTE)
247 ret |= ACTION_REMOTE;
248 if (repeated)
249 ret |= ACTION_REPEAT;
250 if (ignore_until_release)
251 ret |= ACTION_IGNORING;
252 return ret;