diff options
-rw-r--r-- | apps/gui/option_select.c | 487 | ||||
-rw-r--r-- | apps/gui/option_select.h | 2 | ||||
-rw-r--r-- | apps/menu.c | 118 | ||||
-rw-r--r-- | apps/menus/recording_menu.c | 1 | ||||
-rw-r--r-- | apps/plugin.c | 4 | ||||
-rw-r--r-- | apps/plugin.h | 8 | ||||
-rw-r--r-- | apps/plugins/lib/playback_control.c | 41 | ||||
-rw-r--r-- | apps/recorder/recording.c | 79 | ||||
-rw-r--r-- | apps/recorder/recording.h | 1 | ||||
-rw-r--r-- | apps/settings.c | 384 | ||||
-rw-r--r-- | apps/settings.h | 3 | ||||
-rw-r--r-- | apps/settings_list.c | 191 |
12 files changed, 692 insertions, 627 deletions
diff --git a/apps/gui/option_select.c b/apps/gui/option_select.c index 0098cf198f..7d74e202be 100644 --- a/apps/gui/option_select.c +++ b/apps/gui/option_select.c | |||
@@ -8,6 +8,7 @@ | |||
8 | * $Id$ | 8 | * $Id$ |
9 | * | 9 | * |
10 | * Copyright (C) 2005 by Kevin Ferrare | 10 | * Copyright (C) 2005 by Kevin Ferrare |
11 | * Copyright (C) 2007 by Jonathan Gordon | ||
11 | * | 12 | * |
12 | * All files in this archive are subject to the GNU General Public License. | 13 | * 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. | 14 | * See the file COPYING in the source tree root for full license agreement. |
@@ -16,12 +17,496 @@ | |||
16 | * KIND, either express or implied. | 17 | * KIND, either express or implied. |
17 | * | 18 | * |
18 | ****************************************************************************/ | 19 | ****************************************************************************/ |
19 | 20 | #include <stdlib.h> | |
21 | #include "config.h" | ||
20 | #include "option_select.h" | 22 | #include "option_select.h" |
21 | #include "sprintf.h" | 23 | #include "sprintf.h" |
22 | #include "kernel.h" | 24 | #include "kernel.h" |
23 | #include "lang.h" | 25 | #include "lang.h" |
26 | #include "talk.h" | ||
27 | #include "settings_list.h" | ||
28 | #include "sound.h" | ||
29 | #include "list.h" | ||
30 | #include "action.h" | ||
31 | #include "statusbar.h" | ||
32 | #include "misc.h" | ||
33 | #include "splash.h" | ||
34 | |||
35 | static const char *unit_strings[] = | ||
36 | { | ||
37 | [UNIT_INT] = "", [UNIT_MS] = "ms", | ||
38 | [UNIT_SEC] = "s", [UNIT_MIN] = "min", | ||
39 | [UNIT_HOUR]= "hr", [UNIT_KHZ] = "KHz", | ||
40 | [UNIT_DB] = "dB", [UNIT_PERCENT] = "%", | ||
41 | [UNIT_MAH] = "mAh", [UNIT_PIXEL] = "px", | ||
42 | [UNIT_PER_SEC] = "per sec", | ||
43 | [UNIT_HERTZ] = "Hz", | ||
44 | [UNIT_MB] = "MB", [UNIT_KBIT] = "kb/s", | ||
45 | }; | ||
46 | |||
47 | char *option_get_valuestring(struct settings_list *setting, | ||
48 | char *buffer, int buf_len, | ||
49 | intptr_t temp_var) | ||
50 | { | ||
51 | if ((setting->flags & F_BOOL_SETTING) == F_BOOL_SETTING) | ||
52 | { | ||
53 | bool val = (bool)temp_var; | ||
54 | snprintf(buffer, buf_len, "%s", | ||
55 | str(val? setting->bool_setting->lang_yes : | ||
56 | setting->bool_setting->lang_no)); | ||
57 | } | ||
58 | #if 0 /* probably dont need this one */ | ||
59 | else if ((setting->flags & F_FILENAME) == F_FILENAME) | ||
60 | { | ||
61 | struct filename_setting *info = setting->filename_setting; | ||
62 | snprintf(buffer, buf_len, "%s%s%s", info->prefix, | ||
63 | (char*)temp_var, info->suffix); | ||
64 | } | ||
65 | #endif | ||
66 | else if ((setting->flags & F_INT_SETTING) == F_INT_SETTING) | ||
67 | { | ||
68 | struct int_setting *info = setting->int_setting; | ||
69 | if (info->formatter) | ||
70 | info->formatter(buffer, buf_len, (int)temp_var, | ||
71 | unit_strings[info->unit]); | ||
72 | else | ||
73 | snprintf(buffer, buf_len, "%d %s", (int)temp_var, | ||
74 | unit_strings[info->unit]? | ||
75 | unit_strings[info->unit]:""); | ||
76 | } | ||
77 | else if ((setting->flags & F_T_SOUND) == F_T_SOUND) | ||
78 | { | ||
79 | char sign = ' ', *unit; | ||
80 | unit = (char*)sound_unit(setting->sound_setting->setting); | ||
81 | if (sound_numdecimals(setting->sound_setting->setting)) | ||
82 | { | ||
83 | int integer, dec; | ||
84 | int val = sound_val2phys(setting->sound_setting->setting, | ||
85 | (int)temp_var); | ||
86 | if(val < 0) | ||
87 | { | ||
88 | sign = '-'; | ||
89 | val = abs(val); | ||
90 | } | ||
91 | integer = val / 10; dec = val % 10; | ||
92 | snprintf(buffer, buf_len, "%c%d.%d %s", sign, integer, dec, unit); | ||
93 | } | ||
94 | else | ||
95 | snprintf(buffer, buf_len, "%d %s", (int)temp_var, unit); | ||
96 | } | ||
97 | else if ((setting->flags & F_CHOICE_SETTING) == F_CHOICE_SETTING) | ||
98 | { | ||
99 | if (setting->flags & F_CHOICETALKS) | ||
100 | { | ||
101 | int setting_id; | ||
102 | find_setting(setting->setting, &setting_id); | ||
103 | cfg_int_to_string(setting_id, (int)temp_var, buffer, buf_len); | ||
104 | } | ||
105 | else | ||
106 | { | ||
107 | int value= (int)temp_var; | ||
108 | char *val = P2STR(setting->choice_setting->desc[value]); | ||
109 | snprintf(buffer, buf_len, "%s", val); | ||
110 | } | ||
111 | } | ||
112 | return buffer; | ||
113 | } | ||
114 | |||
115 | void option_talk(struct settings_list *setting, int temp_var) | ||
116 | { | ||
117 | if (!talk_menus_enabled()) | ||
118 | return; | ||
119 | if ((setting->flags & F_BOOL_SETTING) == F_BOOL_SETTING) | ||
120 | { | ||
121 | bool val = temp_var==1?true:false; | ||
122 | talk_id(val? setting->bool_setting->lang_yes : | ||
123 | setting->bool_setting->lang_no, false); | ||
124 | } | ||
125 | #if 0 /* probably dont need this one */ | ||
126 | else if ((setting->flags & F_FILENAME) == F_FILENAME) | ||
127 | { | ||
128 | } | ||
129 | #endif | ||
130 | else if ((setting->flags & F_INT_SETTING) == F_INT_SETTING) | ||
131 | { | ||
132 | struct int_setting *info = setting->int_setting; | ||
133 | if (info->get_talk_id) | ||
134 | talk_id(info->get_talk_id((int)temp_var), false); | ||
135 | else | ||
136 | talk_value((int)temp_var, info->unit, false); | ||
137 | } | ||
138 | else if ((setting->flags & F_T_SOUND) == F_T_SOUND) | ||
139 | { | ||
140 | int talkunit = UNIT_DB; | ||
141 | const char *unit = sound_unit(setting->sound_setting->setting); | ||
142 | /* crude reconstruction */ | ||
143 | if (*unit == '%') | ||
144 | talkunit = UNIT_PERCENT; | ||
145 | else if (*unit == 'H') | ||
146 | talkunit = UNIT_HERTZ; | ||
147 | talk_value((int)temp_var, talkunit, false); | ||
148 | } | ||
149 | else if ((setting->flags & F_CHOICE_SETTING) == F_CHOICE_SETTING) | ||
150 | { | ||
151 | int value = (int)temp_var; | ||
152 | if (setting->flags & F_CHOICETALKS) | ||
153 | { | ||
154 | talk_id(setting->choice_setting->talks[value], false); | ||
155 | } | ||
156 | else | ||
157 | { | ||
158 | talk_id(P2ID(setting->choice_setting->desc[value]), false); | ||
159 | } | ||
160 | } | ||
161 | } | ||
162 | #if 0 | ||
163 | int option_select_next_val(struct settings_list *setting, | ||
164 | intptr_t temp_var) | ||
165 | { | ||
166 | int val = 0; | ||
167 | if ((setting->flags & F_BOOL_SETTING) == F_BOOL_SETTING) | ||
168 | { | ||
169 | val = (bool)temp_var ? 0 : 1; | ||
170 | } | ||
171 | else if ((setting->flags & F_INT_SETTING) == F_INT_SETTING) | ||
172 | { | ||
173 | struct int_setting *info = setting->int_setting; | ||
174 | val = (int)temp_var + info->step; | ||
175 | if (val > info->max) | ||
176 | val = info->min; | ||
177 | } | ||
178 | else if ((setting->flags & F_T_SOUND) == F_T_SOUND) | ||
179 | { | ||
180 | int setting_id = setting->sound_setting->setting; | ||
181 | int steps = sound_steps(setting_id); | ||
182 | int min = sound_min(setting_id); | ||
183 | int max = sound_max(setting_id); | ||
184 | val = (int)temp_var + steps; | ||
185 | if (val > max) | ||
186 | val = min; | ||
187 | } | ||
188 | else if ((setting->flags & F_CHOICE_SETTING) == F_CHOICE_SETTING) | ||
189 | { | ||
190 | struct choice_setting *info = setting->choice_setting; | ||
191 | val = (int)temp_var; | ||
192 | if (val > info->count) | ||
193 | val = 0; | ||
194 | } | ||
195 | return val; | ||
196 | } | ||
197 | |||
198 | int option_select_prev_val(struct settings_list *setting, | ||
199 | intptr_t temp_var) | ||
200 | { | ||
201 | int val = 0; | ||
202 | if ((setting->flags & F_BOOL_SETTING) == F_BOOL_SETTING) | ||
203 | { | ||
204 | val = (bool)temp_var ? 0 : 1; | ||
205 | } | ||
206 | else if ((setting->flags & F_INT_SETTING) == F_INT_SETTING) | ||
207 | { | ||
208 | struct int_setting *info = setting->int_setting; | ||
209 | val = (int)temp_var - info->step; | ||
210 | if (val < info->min) | ||
211 | val = info->max; | ||
212 | } | ||
213 | else if ((setting->flags & F_T_SOUND) == F_T_SOUND) | ||
214 | { | ||
215 | int setting_id = setting->sound_setting->setting; | ||
216 | int steps = sound_steps(setting_id); | ||
217 | int min = sound_min(setting_id); | ||
218 | int max = sound_max(setting_id); | ||
219 | val = (int)temp_var -+ steps; | ||
220 | if (val < min) | ||
221 | val = max; | ||
222 | } | ||
223 | else if ((setting->flags & F_CHOICE_SETTING) == F_CHOICE_SETTING) | ||
224 | { | ||
225 | struct choice_setting *info = setting->choice_setting; | ||
226 | val = (int)temp_var; | ||
227 | if (val < 0) | ||
228 | val = info->count - 1; | ||
229 | } | ||
230 | return val; | ||
231 | } | ||
232 | #endif | ||
233 | |||
234 | static int selection_to_val(struct settings_list *setting, int selection) | ||
235 | { | ||
236 | int min = 0, max = 0, step = 1; | ||
237 | if (((setting->flags & F_BOOL_SETTING) == F_BOOL_SETTING) || | ||
238 | ((setting->flags & F_CHOICE_SETTING) == F_CHOICE_SETTING)) | ||
239 | return selection; | ||
240 | else if ((setting->flags & F_T_SOUND) == F_T_SOUND) | ||
241 | { | ||
242 | int setting_id = setting->sound_setting->setting; | ||
243 | step = sound_steps(setting_id); | ||
244 | max = sound_max(setting_id); | ||
245 | min = sound_min(setting_id); | ||
246 | } | ||
247 | else if ((setting->flags & F_INT_SETTING) == F_INT_SETTING) | ||
248 | { | ||
249 | struct int_setting *info = setting->int_setting; | ||
250 | min = info->min; | ||
251 | max = info->max; | ||
252 | step = info->step; | ||
253 | } | ||
254 | if (setting->flags & F_FLIPLIST) | ||
255 | { | ||
256 | int a; | ||
257 | a = min; min = max; max = a; | ||
258 | step = -step; | ||
259 | } | ||
260 | return max- (selection * step); | ||
261 | } | ||
262 | static char * value_setting_get_name_cb(int selected_item, | ||
263 | void * data, char *buffer) | ||
264 | { | ||
265 | selected_item = selection_to_val(data, selected_item); | ||
266 | return option_get_valuestring(data, buffer, MAX_PATH, selected_item); | ||
267 | } | ||
268 | |||
269 | /* wrapper to convert from int param to bool param in option_screen */ | ||
270 | static void (*boolfunction)(bool); | ||
271 | static void bool_funcwrapper(int value) | ||
272 | { | ||
273 | if (value) | ||
274 | boolfunction(true); | ||
275 | else | ||
276 | boolfunction(false); | ||
277 | } | ||
278 | |||
279 | bool option_screen(struct settings_list *setting, bool use_temp_var) | ||
280 | { | ||
281 | int action; | ||
282 | bool done = false; | ||
283 | struct gui_synclist lists; | ||
284 | int oldvalue, nb_items = 0, selected = 0, temp_var; | ||
285 | int *variable; | ||
286 | bool allow_wrap = ((int*)setting->setting != &global_settings.volume); | ||
287 | int var_type = setting->flags&F_T_MASK; | ||
288 | void (*function)(int) = NULL; | ||
289 | |||
290 | if (var_type == F_T_INT || var_type == F_T_UINT) | ||
291 | { | ||
292 | variable = use_temp_var ? &temp_var: (int*)setting->setting; | ||
293 | temp_var = oldvalue = *(int*)setting->setting; | ||
294 | } | ||
295 | else if (var_type == F_T_BOOL) | ||
296 | { | ||
297 | /* bools always use the temp variable... | ||
298 | if use_temp_var is false it will be copied to setting->setting every change */ | ||
299 | variable = &temp_var; | ||
300 | temp_var = oldvalue = *(bool*)setting->setting?1:0; | ||
301 | } | ||
302 | else return false; /* only int/bools can go here */ | ||
303 | gui_synclist_init(&lists, value_setting_get_name_cb, | ||
304 | (void*)setting, false, 1); | ||
305 | if (setting->lang_id == -1) | ||
306 | gui_synclist_set_title(&lists, | ||
307 | (char*)setting->cfg_vals, Icon_Questionmark); | ||
308 | else | ||
309 | gui_synclist_set_title(&lists, | ||
310 | str(setting->lang_id), Icon_Questionmark); | ||
311 | gui_synclist_set_icon_callback(&lists, NULL); | ||
312 | |||
313 | /* set the number of items and current selection */ | ||
314 | if (var_type == F_T_INT || var_type == F_T_UINT) | ||
315 | { | ||
316 | if (setting->flags&F_CHOICE_SETTING) | ||
317 | { | ||
318 | nb_items = setting->choice_setting->count; | ||
319 | selected = oldvalue; | ||
320 | function = setting->choice_setting->option_callback; | ||
321 | } | ||
322 | else if (setting->flags&F_T_SOUND) | ||
323 | { | ||
324 | int setting_id = setting->sound_setting->setting; | ||
325 | int steps = sound_steps(setting_id); | ||
326 | int min = sound_min(setting_id); | ||
327 | int max = sound_max(setting_id); | ||
328 | nb_items = (max-min)/steps + 1; | ||
329 | selected = (max-oldvalue)/steps; | ||
330 | function = sound_get_fn(setting_id); | ||
331 | } | ||
332 | else | ||
333 | { | ||
334 | struct int_setting *info = setting->int_setting; | ||
335 | int min, max, step; | ||
336 | if (setting->flags&F_FLIPLIST) | ||
337 | { | ||
338 | min = info->max; | ||
339 | max = info->min; | ||
340 | step = -info->step; | ||
341 | } | ||
342 | else | ||
343 | { | ||
344 | max = info->max; | ||
345 | min = info->min; | ||
346 | step = info->step; | ||
347 | } | ||
348 | nb_items = (max-min)/step + 1; | ||
349 | selected = (max - oldvalue)/step; | ||
350 | function = info->option_callback; | ||
351 | } | ||
352 | } | ||
353 | else if (var_type == F_T_BOOL) | ||
354 | { | ||
355 | selected = oldvalue; | ||
356 | nb_items = 2; | ||
357 | boolfunction = setting->bool_setting->option_callback; | ||
358 | if (boolfunction) | ||
359 | function = bool_funcwrapper; | ||
360 | } | ||
361 | |||
362 | gui_synclist_set_nb_items(&lists, nb_items); | ||
363 | gui_synclist_select_item(&lists, selected); | ||
364 | |||
365 | gui_synclist_limit_scroll(&lists, true); | ||
366 | gui_synclist_draw(&lists); | ||
367 | action_signalscreenchange(); | ||
368 | /* talk the item */ | ||
369 | option_talk(setting, *variable); | ||
370 | while (!done) | ||
371 | { | ||
372 | action = get_action(CONTEXT_LIST, TIMEOUT_BLOCK); | ||
373 | if (action == ACTION_NONE) | ||
374 | continue; | ||
375 | if (gui_synclist_do_button(&lists,action, | ||
376 | allow_wrap? LIST_WRAP_UNLESS_HELD: LIST_WRAP_OFF)) | ||
377 | { | ||
378 | selected = gui_synclist_get_sel_pos(&lists); | ||
379 | *variable = selection_to_val(setting, selected); | ||
380 | if (var_type == F_T_BOOL) | ||
381 | { | ||
382 | if (!use_temp_var) | ||
383 | *(bool*)setting->setting = selected==1?true:false; | ||
384 | } | ||
385 | /* talk */ | ||
386 | option_talk(setting, *variable); | ||
387 | } | ||
388 | else if (action == ACTION_STD_CANCEL) | ||
389 | { | ||
390 | bool show_cancel = false; | ||
391 | if (use_temp_var) | ||
392 | show_cancel = true; | ||
393 | else if (var_type == F_T_INT || var_type == F_T_UINT) | ||
394 | { | ||
395 | if (*variable != oldvalue) | ||
396 | { | ||
397 | show_cancel = true; | ||
398 | *variable = oldvalue; | ||
399 | } | ||
400 | } | ||
401 | else | ||
402 | { | ||
403 | if (*variable != oldvalue) | ||
404 | { | ||
405 | show_cancel = true; | ||
406 | if (!use_temp_var) | ||
407 | *(bool*)setting->setting = oldvalue==1?true:false; | ||
408 | *variable = oldvalue; | ||
409 | } | ||
410 | } | ||
411 | if (show_cancel) | ||
412 | gui_syncsplash(HZ/2, str(LANG_MENU_SETTING_CANCEL)); | ||
413 | done = true; | ||
414 | } | ||
415 | else if (action == ACTION_STD_OK) | ||
416 | { | ||
417 | done = true; | ||
418 | } | ||
419 | else if(default_event_handler(action) == SYS_USB_CONNECTED) | ||
420 | return true; | ||
421 | gui_syncstatusbar_draw(&statusbars, false); | ||
422 | /* callback */ | ||
423 | if ( function ) | ||
424 | function(*variable); | ||
425 | } | ||
426 | |||
427 | if (use_temp_var) | ||
428 | { | ||
429 | if (var_type == F_T_INT || var_type == F_T_UINT) | ||
430 | { | ||
431 | if (oldvalue != *variable) | ||
432 | { | ||
433 | *(int*)setting->setting = *variable; | ||
434 | settings_save(); | ||
435 | } | ||
436 | } | ||
437 | else if (oldvalue != *variable) | ||
438 | { | ||
439 | *(bool*)setting->setting = *variable?true:false; | ||
440 | settings_save(); | ||
441 | } | ||
442 | } | ||
443 | |||
444 | action_signalscreenchange(); | ||
445 | return false; | ||
446 | } | ||
447 | |||
448 | /****************************************************** | ||
449 | Compatability functions | ||
450 | *******************************************************/ | ||
451 | #define MAX_OPTIONS 32 | ||
452 | bool set_option(const char* string, void* variable, enum optiontype type, | ||
453 | const struct opt_items* options, | ||
454 | int numoptions, void (*function)(int)) | ||
455 | { | ||
456 | int temp; | ||
457 | char *strings[MAX_OPTIONS]; | ||
458 | struct choice_setting data; | ||
459 | struct settings_list item; | ||
460 | for (temp=0; temp<MAX_OPTIONS && temp<numoptions; temp++) | ||
461 | strings[temp] = (char*)options[temp].string; | ||
462 | if (type == BOOL) | ||
463 | { | ||
464 | temp = *(bool*)variable? 1: 0; | ||
465 | item.setting = &temp; | ||
466 | } | ||
467 | else | ||
468 | item.setting = variable; | ||
469 | item.flags = F_CHOICE_SETTING|F_T_INT; | ||
470 | item.lang_id = -1; | ||
471 | item.cfg_vals = (char*)string; | ||
472 | data.count = numoptions<MAX_OPTIONS ? numoptions: MAX_OPTIONS; | ||
473 | data.desc = (void*)strings; /* shutup gcc... */ | ||
474 | data.option_callback = function; | ||
475 | item.choice_setting = &data; | ||
476 | option_screen(&item, false); | ||
477 | if (type == BOOL) | ||
478 | { | ||
479 | *(bool*)variable = (temp == 1? true: false); | ||
480 | } | ||
481 | return false; | ||
482 | } | ||
483 | |||
484 | bool set_int_ex(const unsigned char* string, | ||
485 | const char* unit, | ||
486 | int voice_unit, | ||
487 | int* variable, | ||
488 | void (*function)(int), | ||
489 | int step, | ||
490 | int min, | ||
491 | int max, | ||
492 | void (*formatter)(char*, int, int, const char*), | ||
493 | long (*get_talk_id)(int)) | ||
494 | { | ||
495 | (void)unit; | ||
496 | struct settings_list item; | ||
497 | struct int_setting data = { | ||
498 | function, voice_unit, min, max, step, | ||
499 | formatter, get_talk_id | ||
500 | }; | ||
501 | item.int_setting = &data; | ||
502 | item.flags = F_INT_SETTING|F_T_INT; | ||
503 | item.lang_id = -1; | ||
504 | item.cfg_vals = (char*)string; | ||
505 | item.setting = variable; | ||
506 | return option_screen(&item, false); | ||
507 | } | ||
24 | 508 | ||
509 | /* to be replaced */ | ||
25 | void option_select_init_items(struct option_select * opt, | 510 | void option_select_init_items(struct option_select * opt, |
26 | const char * title, | 511 | const char * title, |
27 | int selected, | 512 | int selected, |
diff --git a/apps/gui/option_select.h b/apps/gui/option_select.h index e2ae31a848..8fc19db82d 100644 --- a/apps/gui/option_select.h +++ b/apps/gui/option_select.h | |||
@@ -21,6 +21,8 @@ | |||
21 | #define _GUI_OPTION_SELECT_H_ | 21 | #define _GUI_OPTION_SELECT_H_ |
22 | #include "settings.h" | 22 | #include "settings.h" |
23 | 23 | ||
24 | bool option_screen(struct settings_list *setting, bool use_temp_var); | ||
25 | |||
24 | struct option_select | 26 | struct option_select |
25 | { | 27 | { |
26 | const char * title; | 28 | const char * title; |
diff --git a/apps/menu.c b/apps/menu.c index 37d28eb12c..17fff25afb 100644 --- a/apps/menu.c +++ b/apps/menu.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include "panic.h" | 36 | #include "panic.h" |
37 | #include "settings.h" | 37 | #include "settings.h" |
38 | #include "settings_list.h" | 38 | #include "settings_list.h" |
39 | #include "option_select.h" | ||
39 | #include "status.h" | 40 | #include "status.h" |
40 | #include "screens.h" | 41 | #include "screens.h" |
41 | #include "talk.h" | 42 | #include "talk.h" |
@@ -259,120 +260,9 @@ bool do_setting_from_menu(const struct menu_item_ex *temp) | |||
259 | const struct settings_list *setting = find_setting( | 260 | const struct settings_list *setting = find_setting( |
260 | temp->variable, | 261 | temp->variable, |
261 | &setting_id); | 262 | &setting_id); |
262 | bool ret_val = false; | 263 | option_screen((struct settings_list *)setting, |
263 | unsigned char *title; | 264 | setting->flags&F_TEMPVAR); |
264 | if (setting) | 265 | return false; |
265 | { | ||
266 | if ((temp->flags&MENU_TYPE_MASK) == MT_SETTING_W_TEXT) | ||
267 | title = temp->callback_and_desc->desc; | ||
268 | else | ||
269 | title = ID2P(setting->lang_id); | ||
270 | |||
271 | if ((setting->flags&F_BOOL_SETTING) == F_BOOL_SETTING) | ||
272 | { | ||
273 | bool temp_var, *var; | ||
274 | bool show_icons = global_settings.show_icons; | ||
275 | if (setting->flags&F_TEMPVAR) | ||
276 | { | ||
277 | temp_var = *(bool*)setting->setting; | ||
278 | var = &temp_var; | ||
279 | } | ||
280 | else | ||
281 | { | ||
282 | var = (bool*)setting->setting; | ||
283 | } | ||
284 | set_bool_options(P2STR(title), var, | ||
285 | STR(setting->bool_setting->lang_yes), | ||
286 | STR(setting->bool_setting->lang_no), | ||
287 | setting->bool_setting->option_callback); | ||
288 | if (setting->flags&F_TEMPVAR) | ||
289 | *(bool*)setting->setting = temp_var; | ||
290 | if (show_icons != global_settings.show_icons) | ||
291 | ret_val = true; | ||
292 | } | ||
293 | else if (setting->flags&F_T_SOUND) | ||
294 | { | ||
295 | set_sound(P2STR(title), setting->setting, | ||
296 | setting->sound_setting->setting); | ||
297 | } | ||
298 | else /* other setting, must be an INT type */ | ||
299 | { | ||
300 | int temp_var, *var; | ||
301 | if (setting->flags&F_TEMPVAR) | ||
302 | { | ||
303 | temp_var = *(int*)setting->setting; | ||
304 | var = &temp_var; | ||
305 | } | ||
306 | else | ||
307 | { | ||
308 | var = (int*)setting->setting; | ||
309 | } | ||
310 | if (setting->flags&F_INT_SETTING) | ||
311 | { | ||
312 | int min, max, step; | ||
313 | if (setting->flags&F_FLIPLIST) | ||
314 | { | ||
315 | min = setting->int_setting->max; | ||
316 | max = setting->int_setting->min; | ||
317 | step = -setting->int_setting->step; | ||
318 | } | ||
319 | else | ||
320 | { | ||
321 | max = setting->int_setting->max; | ||
322 | min = setting->int_setting->min; | ||
323 | step = setting->int_setting->step; | ||
324 | } | ||
325 | set_int_ex(P2STR(title), NULL, | ||
326 | setting->int_setting->unit,var, | ||
327 | setting->int_setting->option_callback, | ||
328 | step, min, max, | ||
329 | setting->int_setting->formatter, | ||
330 | setting->int_setting->get_talk_id); | ||
331 | } | ||
332 | else if (setting->flags&F_CHOICE_SETTING) | ||
333 | { | ||
334 | static struct opt_items options[MAX_OPTIONS]; | ||
335 | char buffer[256]; | ||
336 | char *buf_start = buffer; | ||
337 | int buf_free = 256; | ||
338 | int i,j, count = setting->choice_setting->count; | ||
339 | for (i=0, j=0; i<count && i<MAX_OPTIONS; i++) | ||
340 | { | ||
341 | if (setting->flags&F_CHOICETALKS) | ||
342 | { | ||
343 | if (cfg_int_to_string(setting_id, i, | ||
344 | buf_start, buf_free)) | ||
345 | { | ||
346 | int len = strlen(buf_start) +1; | ||
347 | options[j].string = buf_start; | ||
348 | buf_start += len; | ||
349 | buf_free -= len; | ||
350 | options[j].voice_id = | ||
351 | setting->choice_setting->talks[i]; | ||
352 | j++; | ||
353 | } | ||
354 | } | ||
355 | else | ||
356 | { | ||
357 | options[j].string = | ||
358 | P2STR(setting-> | ||
359 | choice_setting->desc[i]); | ||
360 | options[j].voice_id = | ||
361 | P2ID(setting-> | ||
362 | choice_setting->desc[i]); | ||
363 | j++; | ||
364 | } | ||
365 | } | ||
366 | set_option(P2STR(title), var, INT, | ||
367 | options,j, | ||
368 | setting-> | ||
369 | choice_setting->option_callback); | ||
370 | } | ||
371 | if (setting->flags&F_TEMPVAR) | ||
372 | *(int*)setting->setting = temp_var; | ||
373 | } | ||
374 | } | ||
375 | return ret_val; | ||
376 | } | 266 | } |
377 | 267 | ||
378 | int do_menu(const struct menu_item_ex *start_menu, int *start_selected) | 268 | int do_menu(const struct menu_item_ex *start_menu, int *start_selected) |
diff --git a/apps/menus/recording_menu.c b/apps/menus/recording_menu.c index 4126b9e22a..648d9cd876 100644 --- a/apps/menus/recording_menu.c +++ b/apps/menus/recording_menu.c | |||
@@ -62,6 +62,7 @@ | |||
62 | #include "general.h" | 62 | #include "general.h" |
63 | #endif | 63 | #endif |
64 | #include "action.h" | 64 | #include "action.h" |
65 | #include "recording.h" | ||
65 | 66 | ||
66 | 67 | ||
67 | static bool no_source_in_menu = true; | 68 | static bool no_source_in_menu = true; |
diff --git a/apps/plugin.c b/apps/plugin.c index e81ae25ed1..793114539e 100644 --- a/apps/plugin.c +++ b/apps/plugin.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include "powermgmt.h" | 32 | #include "powermgmt.h" |
33 | #include "splash.h" | 33 | #include "splash.h" |
34 | #include "logf.h" | 34 | #include "logf.h" |
35 | #include "option_select.h" | ||
35 | 36 | ||
36 | #if CONFIG_CHARGING | 37 | #if CONFIG_CHARGING |
37 | #include "power.h" | 38 | #include "power.h" |
@@ -318,7 +319,6 @@ static const struct plugin_api rockbox_api = { | |||
318 | sound_default, | 319 | sound_default, |
319 | #endif | 320 | #endif |
320 | sound_set, | 321 | sound_set, |
321 | set_sound, | ||
322 | 322 | ||
323 | sound_min, | 323 | sound_min, |
324 | sound_max, | 324 | sound_max, |
@@ -405,6 +405,8 @@ static const struct plugin_api rockbox_api = { | |||
405 | &statusbars, | 405 | &statusbars, |
406 | gui_syncstatusbar_draw, | 406 | gui_syncstatusbar_draw, |
407 | /* options */ | 407 | /* options */ |
408 | find_setting, | ||
409 | option_screen, | ||
408 | set_option, | 410 | set_option, |
409 | set_bool_options, | 411 | set_bool_options, |
410 | set_int, | 412 | set_int, |
diff --git a/apps/plugin.h b/apps/plugin.h index 10dce4dce6..0edbc87e37 100644 --- a/apps/plugin.h +++ b/apps/plugin.h | |||
@@ -115,12 +115,12 @@ | |||
115 | #define PLUGIN_MAGIC 0x526F634B /* RocK */ | 115 | #define PLUGIN_MAGIC 0x526F634B /* RocK */ |
116 | 116 | ||
117 | /* increase this every time the api struct changes */ | 117 | /* increase this every time the api struct changes */ |
118 | #define PLUGIN_API_VERSION 61 | 118 | #define PLUGIN_API_VERSION 62 |
119 | 119 | ||
120 | /* update this to latest version if a change to the api struct breaks | 120 | /* update this to latest version if a change to the api struct breaks |
121 | backwards compatibility (and please take the opportunity to sort in any | 121 | backwards compatibility (and please take the opportunity to sort in any |
122 | new function which are "waiting" at the end of the function table) */ | 122 | new function which are "waiting" at the end of the function table) */ |
123 | #define PLUGIN_MIN_API_VERSION 61 | 123 | #define PLUGIN_MIN_API_VERSION 62 |
124 | 124 | ||
125 | /* plugin return codes */ | 125 | /* plugin return codes */ |
126 | enum plugin_status { | 126 | enum plugin_status { |
@@ -418,8 +418,6 @@ struct plugin_api { | |||
418 | int (*sound_default)(int setting); | 418 | int (*sound_default)(int setting); |
419 | #endif | 419 | #endif |
420 | void (*sound_set)(int setting, int value); | 420 | void (*sound_set)(int setting, int value); |
421 | bool (*set_sound)(const unsigned char * string, | ||
422 | int* variable, int setting); | ||
423 | int (*sound_min)(int setting); | 421 | int (*sound_min)(int setting); |
424 | int (*sound_max)(int setting); | 422 | int (*sound_max)(int setting); |
425 | #ifndef SIMULATOR | 423 | #ifndef SIMULATOR |
@@ -509,6 +507,8 @@ struct plugin_api { | |||
509 | void (*gui_syncstatusbar_draw)(struct gui_syncstatusbar * bars, bool force_redraw); | 507 | void (*gui_syncstatusbar_draw)(struct gui_syncstatusbar * bars, bool force_redraw); |
510 | 508 | ||
511 | /* options */ | 509 | /* options */ |
510 | const struct settings_list* (*find_setting)(void* variable, int *id); | ||
511 | bool (*option_screen)(struct settings_list *setting, bool use_temp_var); | ||
512 | bool (*set_option)(const char* string, void* variable, | 512 | bool (*set_option)(const char* string, void* variable, |
513 | enum optiontype type, const struct opt_items* options, | 513 | enum optiontype type, const struct opt_items* options, |
514 | int numoptions, void (*function)(int)); | 514 | int numoptions, void (*function)(int)); |
diff --git a/apps/plugins/lib/playback_control.c b/apps/plugins/lib/playback_control.c index 177f26a417..94f0d69c2b 100644 --- a/apps/plugins/lib/playback_control.c +++ b/apps/plugins/lib/playback_control.c | |||
@@ -59,46 +59,31 @@ bool nexttrack(void) | |||
59 | 59 | ||
60 | static bool volume(void) | 60 | static bool volume(void) |
61 | { | 61 | { |
62 | return api->set_sound("Volume", &api->global_settings->volume, | 62 | const struct settings_list* vol = |
63 | SOUND_VOLUME); | 63 | api->find_setting(&api->global_settings->volume, NULL); |
64 | return api->option_screen((struct settings_list*)vol, false); | ||
64 | } | 65 | } |
65 | 66 | ||
66 | static bool shuffle(void) | 67 | static bool shuffle(void) |
67 | { | 68 | { |
68 | struct opt_items names[2]; | 69 | const struct settings_list* shuffle = |
69 | names[0].string = "No"; | 70 | api->find_setting(&api->global_settings->playlist_shuffle, NULL); |
70 | names[0].voice_id = -1; | 71 | return api->option_screen((struct settings_list*)shuffle, false); |
71 | names[1].string = "Yes"; | ||
72 | names[1].voice_id = -1; | ||
73 | |||
74 | return api->set_option("Shuffle", &api->global_settings->playlist_shuffle, | ||
75 | BOOL, names, 2,NULL); | ||
76 | } | 72 | } |
77 | 73 | ||
78 | static bool repeat_mode(void) | 74 | static bool repeat_mode(void) |
79 | { | 75 | { |
80 | bool result; | 76 | const struct settings_list* repeat = |
81 | static const struct opt_items names[] = { | 77 | api->find_setting(&api->global_settings->repeat_mode, NULL); |
82 | { "Off", -1 }, | ||
83 | { "Repeat All", -1 }, | ||
84 | { "Repeat One", -1 }, | ||
85 | { "Repeat Shuffle", -1 }, | ||
86 | #ifdef AB_REPEAT_ENABLE | ||
87 | { "Repeat A-B", -1 } | ||
88 | #endif | ||
89 | }; | ||
90 | |||
91 | int old_repeat = api->global_settings->repeat_mode; | 78 | int old_repeat = api->global_settings->repeat_mode; |
92 | 79 | ||
93 | result = api->set_option( "Repeat Mode", | 80 | api->option_screen((struct settings_list*)repeat, false); |
94 | &api->global_settings->repeat_mode, | 81 | |
95 | INT, names, NUM_REPEAT_MODES, NULL ); | ||
96 | |||
97 | if (old_repeat != api->global_settings->repeat_mode && | 82 | if (old_repeat != api->global_settings->repeat_mode && |
98 | (api->audio_status() & AUDIO_STATUS_PLAY)) | 83 | (api->audio_status() & AUDIO_STATUS_PLAY)) |
99 | api->audio_flush_and_reload_tracks(); | 84 | api->audio_flush_and_reload_tracks(); |
100 | 85 | ||
101 | return result; | 86 | return false; |
102 | } | 87 | } |
103 | MENUITEM_FUNCTION(prevtrack_item, 0, "Previous Track", | 88 | MENUITEM_FUNCTION(prevtrack_item, 0, "Previous Track", |
104 | prevtrack, NULL, NULL, Icon_NOICON); | 89 | prevtrack, NULL, NULL, Icon_NOICON); |
diff --git a/apps/recorder/recording.c b/apps/recorder/recording.c index a085bbbc03..30e3c315c8 100644 --- a/apps/recorder/recording.c +++ b/apps/recorder/recording.c | |||
@@ -69,7 +69,86 @@ | |||
69 | #include "action.h" | 69 | #include "action.h" |
70 | #include "radio.h" | 70 | #include "radio.h" |
71 | #ifdef HAVE_RECORDING | 71 | #ifdef HAVE_RECORDING |
72 | /* This array holds the record timer interval lengths, in seconds */ | ||
73 | static const unsigned long rec_timer_seconds[] = | ||
74 | { | ||
75 | 0, /* 0 means OFF */ | ||
76 | 5*60, /* 00:05 */ | ||
77 | 10*60, /* 00:10 */ | ||
78 | 15*60, /* 00:15 */ | ||
79 | 30*60, /* 00:30 */ | ||
80 | 60*60, /* 01:00 */ | ||
81 | 74*60, /* 74:00 */ | ||
82 | 80*60, /* 80:00 */ | ||
83 | 2*60*60, /* 02:00 */ | ||
84 | 4*60*60, /* 04:00 */ | ||
85 | 6*60*60, /* 06:00 */ | ||
86 | 8*60*60, /* 08:00 */ | ||
87 | 10L*60*60, /* 10:00 */ | ||
88 | 12L*60*60, /* 12:00 */ | ||
89 | 18L*60*60, /* 18:00 */ | ||
90 | 24L*60*60 /* 24:00 */ | ||
91 | }; | ||
92 | |||
93 | static unsigned int rec_timesplit_seconds(void) | ||
94 | { | ||
95 | return rec_timer_seconds[global_settings.rec_timesplit]; | ||
96 | } | ||
97 | |||
98 | /* This array holds the record size interval lengths, in bytes */ | ||
99 | static const unsigned long rec_size_bytes[] = | ||
100 | { | ||
101 | 0, /* 0 means OFF */ | ||
102 | 5*1024*1024, /* 5MB */ | ||
103 | 10*1024*1024, /* 10MB */ | ||
104 | 15*1024*1024, /* 15MB */ | ||
105 | 32*1024*1024, /* 32MB */ | ||
106 | 64*1024*1024, /* 64MB */ | ||
107 | 75*1024*1024, /* 75MB */ | ||
108 | 100*1024*1024, /* 100MB */ | ||
109 | 128*1024*1024, /* 128MB */ | ||
110 | 256*1024*1024, /* 256MB */ | ||
111 | 512*1024*1024, /* 512MB */ | ||
112 | 650*1024*1024, /* 650MB */ | ||
113 | 700*1024*1024, /* 700MB */ | ||
114 | 1024*1024*1024, /* 1GB */ | ||
115 | 1536*1024*1024, /* 1.5GB */ | ||
116 | 1792*1024*1024, /* 1.75GB */ | ||
117 | }; | ||
118 | |||
119 | static unsigned long rec_sizesplit_bytes(void) | ||
120 | { | ||
121 | return rec_size_bytes[global_settings.rec_sizesplit]; | ||
122 | } | ||
123 | /* | ||
124 | * Time strings used for the trigger durations. | ||
125 | * Keep synchronous to trigger_times in settings_apply_trigger | ||
126 | */ | ||
127 | const char * const trig_durations[TRIG_DURATION_COUNT] = | ||
128 | { | ||
129 | "0s", "1s", "2s", "5s", | ||
130 | "10s", "15s", "20s", "25s", "30s", | ||
131 | "1min", "2min", "5min", "10min" | ||
132 | }; | ||
72 | 133 | ||
134 | void settings_apply_trigger(void) | ||
135 | { | ||
136 | /* Keep synchronous to trig_durations and trig_durations_conf*/ | ||
137 | static const long trigger_times[TRIG_DURATION_COUNT] = { | ||
138 | 0, HZ, 2*HZ, 5*HZ, | ||
139 | 10*HZ, 15*HZ, 20*HZ, 25*HZ, 30*HZ, | ||
140 | 60*HZ, 2*60*HZ, 5*60*HZ, 10*60*HZ | ||
141 | }; | ||
142 | |||
143 | peak_meter_define_trigger( | ||
144 | global_settings.rec_start_thres, | ||
145 | trigger_times[global_settings.rec_start_duration], | ||
146 | MIN(trigger_times[global_settings.rec_start_duration] / 2, 2*HZ), | ||
147 | global_settings.rec_stop_thres, | ||
148 | trigger_times[global_settings.rec_stop_postrec], | ||
149 | trigger_times[global_settings.rec_stop_gap] | ||
150 | ); | ||
151 | } | ||
73 | /* recording screen status flags */ | 152 | /* recording screen status flags */ |
74 | enum rec_status_flags | 153 | enum rec_status_flags |
75 | { | 154 | { |
diff --git a/apps/recorder/recording.h b/apps/recorder/recording.h index 50a73856cf..2c3869a4fb 100644 --- a/apps/recorder/recording.h +++ b/apps/recorder/recording.h | |||
@@ -24,6 +24,7 @@ bool in_recording_screen(void); | |||
24 | bool recording_screen(bool no_source); | 24 | bool recording_screen(bool no_source); |
25 | char *rec_create_filename(char *buf); | 25 | char *rec_create_filename(char *buf); |
26 | int rec_create_directory(void); | 26 | int rec_create_directory(void); |
27 | void settings_apply_trigger(void); | ||
27 | 28 | ||
28 | /* If true, start recording automatically when recording_sreen() is entered */ | 29 | /* If true, start recording automatically when recording_sreen() is entered */ |
29 | extern bool recording_start_automatic; | 30 | extern bool recording_start_automatic; |
diff --git a/apps/settings.c b/apps/settings.c index cad5f9206c..0cf38266a6 100644 --- a/apps/settings.c +++ b/apps/settings.c | |||
@@ -932,51 +932,6 @@ void talk_setting(void *global_settings_variable) | |||
932 | talk_id(setting->lang_id,false); | 932 | talk_id(setting->lang_id,false); |
933 | } | 933 | } |
934 | 934 | ||
935 | static int selected_setting; /* Used by the callback */ | ||
936 | |||
937 | static void dec_sound_formatter(char *buffer, int buffer_size, | ||
938 | int val, const char *unit) | ||
939 | { | ||
940 | val = sound_val2phys(selected_setting, val); | ||
941 | char sign = ' '; | ||
942 | if(val < 0) | ||
943 | { | ||
944 | sign = '-'; | ||
945 | val = abs(val); | ||
946 | } | ||
947 | int integer = val / 10; | ||
948 | int dec = val % 10; | ||
949 | snprintf(buffer, buffer_size, "%c%d.%d %s", sign, integer, dec, unit); | ||
950 | } | ||
951 | |||
952 | bool set_sound(const unsigned char * string, | ||
953 | int* variable, | ||
954 | int setting) | ||
955 | { | ||
956 | int talkunit = UNIT_INT; | ||
957 | const char* unit = sound_unit(setting); | ||
958 | int numdec = sound_numdecimals(setting); | ||
959 | int steps = sound_steps(setting); | ||
960 | int min = sound_min(setting); | ||
961 | int max = sound_max(setting); | ||
962 | sound_set_type* sound_callback = sound_get_fn(setting); | ||
963 | if (*unit == 'd') /* crude reconstruction */ | ||
964 | talkunit = UNIT_DB; | ||
965 | else if (*unit == '%') | ||
966 | talkunit = UNIT_PERCENT; | ||
967 | else if (*unit == 'H') | ||
968 | talkunit = UNIT_HERTZ; | ||
969 | if (!numdec) | ||
970 | return set_int(string, unit, talkunit, variable, sound_callback, | ||
971 | steps, min, max, NULL ); | ||
972 | else | ||
973 | {/* Decimal number */ | ||
974 | selected_setting=setting; | ||
975 | return set_int(string, unit, talkunit, variable, sound_callback, | ||
976 | steps, min, max, &dec_sound_formatter ); | ||
977 | } | ||
978 | } | ||
979 | |||
980 | bool set_bool(const char* string, bool* variable ) | 935 | bool set_bool(const char* string, bool* variable ) |
981 | { | 936 | { |
982 | return set_bool_options(string, variable, | 937 | return set_bool_options(string, variable, |
@@ -985,15 +940,6 @@ bool set_bool(const char* string, bool* variable ) | |||
985 | NULL); | 940 | NULL); |
986 | } | 941 | } |
987 | 942 | ||
988 | /* wrapper to convert from int param to bool param in set_option */ | ||
989 | static void (*boolfunction)(bool); | ||
990 | static void bool_funcwrapper(int value) | ||
991 | { | ||
992 | if (value) | ||
993 | boolfunction(true); | ||
994 | else | ||
995 | boolfunction(false); | ||
996 | } | ||
997 | 943 | ||
998 | bool set_bool_options(const char* string, bool* variable, | 944 | bool set_bool_options(const char* string, bool* variable, |
999 | const char* yes_str, int yes_voice, | 945 | const char* yes_str, int yes_voice, |
@@ -1006,237 +952,11 @@ bool set_bool_options(const char* string, bool* variable, | |||
1006 | }; | 952 | }; |
1007 | bool result; | 953 | bool result; |
1008 | 954 | ||
1009 | boolfunction = function; | ||
1010 | result = set_option(string, variable, BOOL, names, 2, | 955 | result = set_option(string, variable, BOOL, names, 2, |
1011 | function ? bool_funcwrapper : NULL); | 956 | (void (*)(int))function); |
1012 | return result; | 957 | return result; |
1013 | } | 958 | } |
1014 | 959 | ||
1015 | static void talk_unit(int unit, int value, long (*get_talk_id)(int value)) | ||
1016 | { | ||
1017 | if (talk_menus_enabled()) | ||
1018 | { | ||
1019 | if (get_talk_id) | ||
1020 | { | ||
1021 | talk_id(get_talk_id(value),false); | ||
1022 | } | ||
1023 | else if (unit < UNIT_LAST) | ||
1024 | { /* use the available unit definition */ | ||
1025 | talk_value(value, unit, false); | ||
1026 | } | ||
1027 | else | ||
1028 | { /* say the number, followed by an arbitrary voice ID */ | ||
1029 | talk_number(value, false); | ||
1030 | talk_id(unit, true); | ||
1031 | } | ||
1032 | } | ||
1033 | } | ||
1034 | |||
1035 | struct value_setting_data { | ||
1036 | enum optiontype type; | ||
1037 | /* used for "value" settings.. */ | ||
1038 | int max; | ||
1039 | int step; | ||
1040 | int voice_unit; | ||
1041 | const char * unit; | ||
1042 | void (*formatter)(char* dest, int dest_length, | ||
1043 | int value, const char* unit); | ||
1044 | long (*get_talk_id)(int value); | ||
1045 | /* used for BOOL and "choice" settings */ | ||
1046 | struct opt_items* options; | ||
1047 | }; | ||
1048 | |||
1049 | static char * value_setting_get_name_cb(int selected_item,void * data, char *buffer) | ||
1050 | { | ||
1051 | struct value_setting_data* cb_data = | ||
1052 | (struct value_setting_data*)data; | ||
1053 | if (cb_data->type == INT && !cb_data->options) | ||
1054 | { | ||
1055 | int item = cb_data->max -(selected_item*cb_data->step); | ||
1056 | if (cb_data->formatter) | ||
1057 | cb_data->formatter(buffer, MAX_PATH,item,cb_data->unit); | ||
1058 | else | ||
1059 | snprintf(buffer, MAX_PATH,"%d %s",item,cb_data->unit); | ||
1060 | } | ||
1061 | else strcpy(buffer,P2STR(cb_data->options[selected_item].string)); | ||
1062 | return buffer; | ||
1063 | } | ||
1064 | #define type_fromvoidptr(type, value) \ | ||
1065 | (type == INT)? \ | ||
1066 | (int)(*(int*)(value)) \ | ||
1067 | : \ | ||
1068 | (bool)(*(bool*)(value)) | ||
1069 | static bool do_set_setting(const unsigned char* string, void *variable, | ||
1070 | int nb_items,int selected, | ||
1071 | struct value_setting_data *cb_data, | ||
1072 | void (*function)(int)) | ||
1073 | { | ||
1074 | int action; | ||
1075 | bool done = false; | ||
1076 | struct gui_synclist lists; | ||
1077 | int oldvalue; | ||
1078 | bool allow_wrap = true; | ||
1079 | |||
1080 | if (cb_data->type == INT) | ||
1081 | { | ||
1082 | oldvalue = *(int*)variable; | ||
1083 | if (variable == &global_settings.volume) | ||
1084 | allow_wrap = false; | ||
1085 | } | ||
1086 | else oldvalue = *(bool*)variable; | ||
1087 | |||
1088 | gui_synclist_init(&lists,value_setting_get_name_cb,(void*)cb_data,false,1); | ||
1089 | gui_synclist_set_title(&lists, (char*)string,Icon_Questionmark); | ||
1090 | gui_synclist_set_icon_callback(&lists,NULL); | ||
1091 | gui_synclist_set_nb_items(&lists,nb_items); | ||
1092 | gui_synclist_limit_scroll(&lists,true); | ||
1093 | gui_synclist_select_item(&lists, selected); | ||
1094 | |||
1095 | if (talk_menus_enabled()) | ||
1096 | { | ||
1097 | if (cb_data->type == INT && !cb_data->options) | ||
1098 | talk_unit(cb_data->voice_unit, *(int*)variable, cb_data->get_talk_id); | ||
1099 | else | ||
1100 | talk_id(cb_data->options[selected].voice_id, false); | ||
1101 | } | ||
1102 | |||
1103 | gui_synclist_draw(&lists); | ||
1104 | action_signalscreenchange(); | ||
1105 | while (!done) | ||
1106 | { | ||
1107 | |||
1108 | action = get_action(CONTEXT_LIST,TIMEOUT_BLOCK); | ||
1109 | if (action == ACTION_NONE) | ||
1110 | continue; | ||
1111 | if (gui_synclist_do_button(&lists,action, | ||
1112 | allow_wrap?LIST_WRAP_UNLESS_HELD:LIST_WRAP_OFF)) | ||
1113 | { | ||
1114 | if (talk_menus_enabled()) | ||
1115 | { | ||
1116 | int value; | ||
1117 | if (cb_data->type == INT && !cb_data->options) | ||
1118 | { | ||
1119 | value = cb_data->max - | ||
1120 | gui_synclist_get_sel_pos(&lists)*cb_data->step; | ||
1121 | talk_unit(cb_data->voice_unit, value, cb_data->get_talk_id); | ||
1122 | } | ||
1123 | else | ||
1124 | { | ||
1125 | value = gui_synclist_get_sel_pos(&lists); | ||
1126 | talk_id(cb_data->options[value].voice_id, false); | ||
1127 | } | ||
1128 | } | ||
1129 | if (cb_data->type == INT && !cb_data->options) | ||
1130 | *(int*)variable = cb_data->max - | ||
1131 | gui_synclist_get_sel_pos(&lists)*cb_data->step; | ||
1132 | else if (cb_data->type == BOOL) | ||
1133 | *(bool*)variable = gui_synclist_get_sel_pos(&lists) ? true : false; | ||
1134 | else *(int*)variable = gui_synclist_get_sel_pos(&lists); | ||
1135 | } | ||
1136 | else if (action == ACTION_STD_CANCEL) | ||
1137 | { | ||
1138 | if (cb_data->type == INT) | ||
1139 | { | ||
1140 | if (*(int*)variable != oldvalue) | ||
1141 | { | ||
1142 | gui_syncsplash(HZ/2, str(LANG_MENU_SETTING_CANCEL)); | ||
1143 | *(int*)variable = oldvalue; | ||
1144 | } | ||
1145 | } | ||
1146 | else | ||
1147 | { | ||
1148 | if (*(bool*)variable != (bool)oldvalue) | ||
1149 | { | ||
1150 | gui_syncsplash(HZ/2, str(LANG_MENU_SETTING_CANCEL)); | ||
1151 | *(bool*)variable = (bool)oldvalue; | ||
1152 | } | ||
1153 | } | ||
1154 | done = true; | ||
1155 | } | ||
1156 | else if (action == ACTION_STD_OK) | ||
1157 | { | ||
1158 | done = true; | ||
1159 | } | ||
1160 | else if(default_event_handler(action) == SYS_USB_CONNECTED) | ||
1161 | return true; | ||
1162 | gui_syncstatusbar_draw(&statusbars, false); | ||
1163 | if ( function ) | ||
1164 | function(type_fromvoidptr(cb_data->type,variable)); | ||
1165 | } | ||
1166 | if (cb_data->type == INT) | ||
1167 | { | ||
1168 | if (oldvalue != *(int*)variable) | ||
1169 | settings_save(); | ||
1170 | } | ||
1171 | else if (oldvalue != *(bool*)variable) | ||
1172 | settings_save(); | ||
1173 | |||
1174 | action_signalscreenchange(); | ||
1175 | return false; | ||
1176 | } | ||
1177 | static const char *unit_strings[] = | ||
1178 | { | ||
1179 | [UNIT_INT] | ||
1180 | = "", | ||
1181 | [UNIT_MS] | ||
1182 | = "ms", | ||
1183 | [UNIT_SEC] | ||
1184 | = "s", | ||
1185 | [UNIT_MIN] | ||
1186 | = "min", | ||
1187 | [UNIT_HOUR] | ||
1188 | = "hr", | ||
1189 | [UNIT_KHZ] | ||
1190 | = "KHz", | ||
1191 | [UNIT_DB] | ||
1192 | = "dB", | ||
1193 | [UNIT_PERCENT] | ||
1194 | = "%", | ||
1195 | [UNIT_MAH] | ||
1196 | = "mAh", | ||
1197 | [UNIT_PIXEL] | ||
1198 | = "px", | ||
1199 | [UNIT_PER_SEC] | ||
1200 | = "per sec", | ||
1201 | [UNIT_HERTZ] | ||
1202 | = "Hz", | ||
1203 | [UNIT_MB] | ||
1204 | = "MB", | ||
1205 | [UNIT_KBIT] | ||
1206 | = "kb/s", | ||
1207 | }; | ||
1208 | bool set_int_ex(const unsigned char* string, | ||
1209 | const char* unit, | ||
1210 | int voice_unit, | ||
1211 | int* variable, | ||
1212 | void (*function)(int), | ||
1213 | int step, | ||
1214 | int min, | ||
1215 | int max, | ||
1216 | void (*formatter)(char*, int, int, const char*), | ||
1217 | long (*get_talk_id)(int)) | ||
1218 | { | ||
1219 | int count = (max-min)/step + 1; | ||
1220 | #if CONFIG_KEYPAD != PLAYER_PAD | ||
1221 | struct value_setting_data data = { | ||
1222 | INT,max, step, voice_unit,unit,formatter,get_talk_id,NULL }; | ||
1223 | if (voice_unit < UNIT_LAST) | ||
1224 | data.unit = unit_strings[voice_unit]; | ||
1225 | else | ||
1226 | data.unit = str(voice_unit); | ||
1227 | return do_set_setting(string,variable,count, | ||
1228 | (max-*variable)/step, &data,function); | ||
1229 | #else | ||
1230 | struct value_setting_data data = { | ||
1231 | INT,min, -step, voice_unit,unit,formatter,get_talk_id,NULL }; | ||
1232 | if (voice_unit < UNIT_LAST) | ||
1233 | data.unit = unit_strings[voice_unit]; | ||
1234 | else | ||
1235 | data.unit = str(voice_unit); | ||
1236 | return do_set_setting(string,variable,count, | ||
1237 | (*variable-min)/step, &data,function); | ||
1238 | #endif | ||
1239 | } | ||
1240 | bool set_int(const unsigned char* string, | 960 | bool set_int(const unsigned char* string, |
1241 | const char* unit, | 961 | const char* unit, |
1242 | int voice_unit, | 962 | int voice_unit, |
@@ -1250,25 +970,7 @@ bool set_int(const unsigned char* string, | |||
1250 | return set_int_ex(string, unit, voice_unit, variable, function, | 970 | return set_int_ex(string, unit, voice_unit, variable, function, |
1251 | step, min, max, formatter, NULL); | 971 | step, min, max, formatter, NULL); |
1252 | } | 972 | } |
1253 | /* NOTE: the 'type' parameter specifies the actual type of the variable | 973 | |
1254 | that 'variable' points to. not the value within. Only variables with | ||
1255 | type 'bool' should use parameter BOOL. | ||
1256 | |||
1257 | The type separation is necessary since int and bool are fundamentally | ||
1258 | different and bit-incompatible types and can not share the same access | ||
1259 | code. */ | ||
1260 | bool set_option(const char* string, void* variable, enum optiontype type, | ||
1261 | const struct opt_items* options, int numoptions, void (*function)(int)) | ||
1262 | { | ||
1263 | struct value_setting_data data = { | ||
1264 | type,0, 0, 0,NULL,NULL,NULL,(struct opt_items*)options }; | ||
1265 | int selected; | ||
1266 | if (type == BOOL) | ||
1267 | selected = *(bool*)variable ? 1 : 0; | ||
1268 | else selected = *(int*)variable; | ||
1269 | return do_set_setting(string,variable,numoptions, | ||
1270 | selected, &data,function); | ||
1271 | } | ||
1272 | 974 | ||
1273 | /** extra stuff which is probably misplaced **/ | 975 | /** extra stuff which is probably misplaced **/ |
1274 | 976 | ||
@@ -1303,85 +1005,3 @@ void set_file(char* filename, char* setting, int maxlen) | |||
1303 | settings_save(); | 1005 | settings_save(); |
1304 | } | 1006 | } |
1305 | 1007 | ||
1306 | #ifdef HAVE_RECORDING | ||
1307 | /* This array holds the record timer interval lengths, in seconds */ | ||
1308 | static const unsigned long rec_timer_seconds[] = | ||
1309 | { | ||
1310 | 0, /* 0 means OFF */ | ||
1311 | 5*60, /* 00:05 */ | ||
1312 | 10*60, /* 00:10 */ | ||
1313 | 15*60, /* 00:15 */ | ||
1314 | 30*60, /* 00:30 */ | ||
1315 | 60*60, /* 01:00 */ | ||
1316 | 74*60, /* 74:00 */ | ||
1317 | 80*60, /* 80:00 */ | ||
1318 | 2*60*60, /* 02:00 */ | ||
1319 | 4*60*60, /* 04:00 */ | ||
1320 | 6*60*60, /* 06:00 */ | ||
1321 | 8*60*60, /* 08:00 */ | ||
1322 | 10L*60*60, /* 10:00 */ | ||
1323 | 12L*60*60, /* 12:00 */ | ||
1324 | 18L*60*60, /* 18:00 */ | ||
1325 | 24L*60*60 /* 24:00 */ | ||
1326 | }; | ||
1327 | |||
1328 | unsigned int rec_timesplit_seconds(void) | ||
1329 | { | ||
1330 | return rec_timer_seconds[global_settings.rec_timesplit]; | ||
1331 | } | ||
1332 | |||
1333 | /* This array holds the record size interval lengths, in bytes */ | ||
1334 | static const unsigned long rec_size_bytes[] = | ||
1335 | { | ||
1336 | 0, /* 0 means OFF */ | ||
1337 | 5*1024*1024, /* 5MB */ | ||
1338 | 10*1024*1024, /* 10MB */ | ||
1339 | 15*1024*1024, /* 15MB */ | ||
1340 | 32*1024*1024, /* 32MB */ | ||
1341 | 64*1024*1024, /* 64MB */ | ||
1342 | 75*1024*1024, /* 75MB */ | ||
1343 | 100*1024*1024, /* 100MB */ | ||
1344 | 128*1024*1024, /* 128MB */ | ||
1345 | 256*1024*1024, /* 256MB */ | ||
1346 | 512*1024*1024, /* 512MB */ | ||
1347 | 650*1024*1024, /* 650MB */ | ||
1348 | 700*1024*1024, /* 700MB */ | ||
1349 | 1024*1024*1024, /* 1GB */ | ||
1350 | 1536*1024*1024, /* 1.5GB */ | ||
1351 | 1792*1024*1024, /* 1.75GB */ | ||
1352 | }; | ||
1353 | |||
1354 | unsigned long rec_sizesplit_bytes(void) | ||
1355 | { | ||
1356 | return rec_size_bytes[global_settings.rec_sizesplit]; | ||
1357 | } | ||
1358 | /* | ||
1359 | * Time strings used for the trigger durations. | ||
1360 | * Keep synchronous to trigger_times in settings_apply_trigger | ||
1361 | */ | ||
1362 | const char * const trig_durations[TRIG_DURATION_COUNT] = | ||
1363 | { | ||
1364 | "0s", "1s", "2s", "5s", | ||
1365 | "10s", "15s", "20s", "25s", "30s", | ||
1366 | "1min", "2min", "5min", "10min" | ||
1367 | }; | ||
1368 | |||
1369 | void settings_apply_trigger(void) | ||
1370 | { | ||
1371 | /* Keep synchronous to trig_durations and trig_durations_conf*/ | ||
1372 | static const long trigger_times[TRIG_DURATION_COUNT] = { | ||
1373 | 0, HZ, 2*HZ, 5*HZ, | ||
1374 | 10*HZ, 15*HZ, 20*HZ, 25*HZ, 30*HZ, | ||
1375 | 60*HZ, 2*60*HZ, 5*60*HZ, 10*60*HZ | ||
1376 | }; | ||
1377 | |||
1378 | peak_meter_define_trigger( | ||
1379 | global_settings.rec_start_thres, | ||
1380 | trigger_times[global_settings.rec_start_duration], | ||
1381 | MIN(trigger_times[global_settings.rec_start_duration] / 2, 2*HZ), | ||
1382 | global_settings.rec_stop_thres, | ||
1383 | trigger_times[global_settings.rec_stop_postrec], | ||
1384 | trigger_times[global_settings.rec_stop_gap] | ||
1385 | ); | ||
1386 | } | ||
1387 | #endif | ||
diff --git a/apps/settings.h b/apps/settings.h index ef3b1ae85f..e9018141a3 100644 --- a/apps/settings.h +++ b/apps/settings.h | |||
@@ -282,9 +282,6 @@ bool set_int_ex(const unsigned char* string, const char* unit, int voice_unit, | |||
282 | bool set_time_screen(const char* string, struct tm *tm); | 282 | bool set_time_screen(const char* string, struct tm *tm); |
283 | int read_line(int fd, char* buffer, int buffer_size); | 283 | int read_line(int fd, char* buffer, int buffer_size); |
284 | void set_file(char* filename, char* setting, int maxlen); | 284 | void set_file(char* filename, char* setting, int maxlen); |
285 | unsigned int rec_timesplit_seconds(void); | ||
286 | unsigned long rec_sizesplit_bytes(void); | ||
287 | void settings_apply_trigger(void); | ||
288 | 285 | ||
289 | 286 | ||
290 | /** global_settings and global_status struct definitions **/ | 287 | /** global_settings and global_status struct definitions **/ |
diff --git a/apps/settings_list.c b/apps/settings_list.c index f4292cf0cb..c1c0f6a634 100644 --- a/apps/settings_list.c +++ b/apps/settings_list.c | |||
@@ -47,6 +47,103 @@ | |||
47 | #include "radio.h" | 47 | #include "radio.h" |
48 | #endif | 48 | #endif |
49 | 49 | ||
50 | |||
51 | #define NVRAM(bytes) (bytes<<F_NVRAM_MASK_SHIFT) | ||
52 | /** NOTE: NVRAM_CONFIG_VERSION is in settings_list.h | ||
53 | and you may need to update it if you edit this file */ | ||
54 | |||
55 | #define UNUSED {.RESERVED=NULL} | ||
56 | #define INT(a) {.int_ = a} | ||
57 | #define UINT(a) {.uint_ = a} | ||
58 | #define BOOL(a) {.bool_ = a} | ||
59 | #define CHARPTR(a) {.charptr = a} | ||
60 | #define UCHARPTR(a) {.ucharptr = a} | ||
61 | #define FUNCTYPE(a) {.func = a} | ||
62 | #define NODEFAULT INT(0) | ||
63 | |||
64 | /* in all the following macros the args are: | ||
65 | - flags: bitwise | or the F_ bits in settings_list.h | ||
66 | - var: pointer to the variable being changed (usually in global_settings) | ||
67 | - lang_ig: LANG_* id to display in menus and setting screens for the settings | ||
68 | - default: the default value for the variable, set if settings are reset | ||
69 | - name: the name of the setting in config files | ||
70 | - cfg_vals: comma seperated list of legal values in cfg files. | ||
71 | NULL if a number is written to the file instead. | ||
72 | - cb: the callback used by the setting screen. | ||
73 | */ | ||
74 | |||
75 | /* Use for int settings which use the set_sound() function to set them */ | ||
76 | #define SOUND_SETTING(flags,var,lang_id,name,setting) \ | ||
77 | {flags|F_T_INT|F_T_SOUND, &global_settings.var, \ | ||
78 | lang_id, NODEFAULT,name,NULL, \ | ||
79 | {.sound_setting=(struct sound_setting[]){{setting}}} } | ||
80 | |||
81 | /* Use for bool variables which don't use LANG_SET_BOOL_YES and LANG_SET_BOOL_NO, | ||
82 | or dont save as "off" or "on" in the cfg */ | ||
83 | #define BOOL_SETTING(flags,var,lang_id,default,name,cfgvals,yes,no,cb) \ | ||
84 | {flags|F_BOOL_SETTING, &global_settings.var, \ | ||
85 | lang_id, BOOL(default),name,cfgvals, \ | ||
86 | {.bool_setting=(struct bool_setting[]){{cb,yes,no}}} } | ||
87 | |||
88 | /* bool setting which does use LANG_YES and _NO and save as "off,on" */ | ||
89 | #define OFFON_SETTING(flags,var,lang_id,default,name,cb) \ | ||
90 | {flags|F_BOOL_SETTING, &global_settings.var, \ | ||
91 | lang_id, BOOL(default),name,off_on, \ | ||
92 | {.bool_setting=(struct bool_setting[]) \ | ||
93 | {{cb,LANG_SET_BOOL_YES,LANG_SET_BOOL_NO}}} } | ||
94 | |||
95 | /* int variable which is NOT saved to .cfg files, | ||
96 | (Use NVRAM() in the flags to save to the nvram (or nvram.bin file) */ | ||
97 | #define SYSTEM_SETTING(flags,var,default) \ | ||
98 | {flags|F_T_INT, &global_status.var,-1, INT(default), \ | ||
99 | NULL, NULL, UNUSED} | ||
100 | |||
101 | /* setting which stores as a filename in the .cfgvals | ||
102 | prefix: The absolute path to not save in the variable, e.g /.rockbox/wps_file | ||
103 | suffx: The file extention (usually...) e.g .wps_file */ | ||
104 | #define FILENAME_SETTING(flags,var,name,default,prefix,suffix,len) \ | ||
105 | {flags|F_T_UCHARPTR, &global_settings.var,-1, \ | ||
106 | CHARPTR(default),name,NULL, \ | ||
107 | {.filename_setting= \ | ||
108 | (struct filename_setting[]){{prefix,suffix,len}}} } | ||
109 | |||
110 | /* Used for settings which use the set_option() setting screen. | ||
111 | the ... arg is a list of pointers to strings to display in the setting screen. | ||
112 | These can either be literal strings, or ID2P(LANG_*) */ | ||
113 | #define CHOICE_SETTING(flags,var,lang_id,default,name,cfg_vals,cb,count,...) \ | ||
114 | {flags|F_CHOICE_SETTING|F_T_INT, &global_settings.var, lang_id, \ | ||
115 | INT(default), name, cfg_vals, \ | ||
116 | {.choice_setting = (struct choice_setting[]){ \ | ||
117 | {cb, count, {.desc = (unsigned char*[]){__VA_ARGS__}}}}}} | ||
118 | |||
119 | /* Similar to above, except the strings to display are taken from cfg_vals, | ||
120 | the ... arg is a list of ID's to talk for the strings... can use TALK_ID()'s */ | ||
121 | #define STRINGCHOICE_SETTING(flags,var,lang_id,default,name,cfg_vals,cb,count,...) \ | ||
122 | {flags|F_CHOICE_SETTING|F_T_INT|F_CHOICETALKS, \ | ||
123 | &global_settings.var, lang_id, \ | ||
124 | INT(default), name, cfg_vals, \ | ||
125 | {.choice_setting = (struct choice_setting[]){ \ | ||
126 | {cb, count, {.talks = (int[]){__VA_ARGS__}}}}}} | ||
127 | |||
128 | /* for settings which use the set_int() setting screen. | ||
129 | unit is the UNIT_ define to display/talk. | ||
130 | the first one saves a string to the config file, | ||
131 | the second one saves the variable value to the config file */ | ||
132 | #define INT_SETTING_W_CFGVALS(flags, var, lang_id, default, name, cfg_vals, \ | ||
133 | unit, min, max, step, formatter, get_talk_id, cb) \ | ||
134 | {flags|F_INT_SETTING|F_T_INT, &global_settings.var, \ | ||
135 | lang_id, INT(default), name, cfg_vals, \ | ||
136 | {.int_setting = (struct int_setting[]){ \ | ||
137 | {cb, unit, min, max, step, formatter, get_talk_id}}}} | ||
138 | #define INT_SETTING(flags, var, lang_id, default, name, \ | ||
139 | unit, min, max, step, formatter, get_talk_id, cb) \ | ||
140 | {flags|F_INT_SETTING|F_T_INT, &global_settings.var, \ | ||
141 | lang_id, INT(default), name, NULL, \ | ||
142 | {.int_setting = (struct int_setting[]){ \ | ||
143 | {cb, unit, min, max, step, formatter, get_talk_id}}}} | ||
144 | |||
145 | |||
146 | |||
50 | /* some sets of values which are used more than once, to save memory */ | 147 | /* some sets of values which are used more than once, to save memory */ |
51 | static const char off_on[] = "off,on"; | 148 | static const char off_on[] = "off,on"; |
52 | static const char off_on_ask[] = "off,on,ask"; | 149 | static const char off_on_ask[] = "off,on,ask"; |
@@ -193,100 +290,6 @@ static void listaccel_formatter(char *buffer, int buffer_size, | |||
193 | snprintf(buffer, buffer_size, "%d ms", 5*HZ*val); | 290 | snprintf(buffer, buffer_size, "%d ms", 5*HZ*val); |
194 | } | 291 | } |
195 | 292 | ||
196 | #define NVRAM(bytes) (bytes<<F_NVRAM_MASK_SHIFT) | ||
197 | /** NOTE: NVRAM_CONFIG_VERSION is in settings_list.h | ||
198 | and you may need to update it if you edit this file */ | ||
199 | |||
200 | #define UNUSED {.RESERVED=NULL} | ||
201 | #define INT(a) {.int_ = a} | ||
202 | #define UINT(a) {.uint_ = a} | ||
203 | #define BOOL(a) {.bool_ = a} | ||
204 | #define CHARPTR(a) {.charptr = a} | ||
205 | #define UCHARPTR(a) {.ucharptr = a} | ||
206 | #define FUNCTYPE(a) {.func = a} | ||
207 | #define NODEFAULT INT(0) | ||
208 | |||
209 | /* in all the following macros the args are: | ||
210 | - flags: bitwise | or the F_ bits in settings_list.h | ||
211 | - var: pointer to the variable being changed (usually in global_settings) | ||
212 | - lang_ig: LANG_* id to display in menus and setting screens for the settings | ||
213 | - default: the default value for the variable, set if settings are reset | ||
214 | - name: the name of the setting in config files | ||
215 | - cfg_vals: comma seperated list of legal values in cfg files. | ||
216 | NULL if a number is written to the file instead. | ||
217 | - cb: the callback used by the setting screen. | ||
218 | */ | ||
219 | |||
220 | /* Use for int settings which use the set_sound() function to set them */ | ||
221 | #define SOUND_SETTING(flags,var,lang_id,name,setting) \ | ||
222 | {flags|F_T_INT|F_T_SOUND, &global_settings.var, \ | ||
223 | lang_id, NODEFAULT,name,NULL, \ | ||
224 | {.sound_setting=(struct sound_setting[]){{setting}}} } | ||
225 | |||
226 | /* Use for bool variables which don't use LANG_SET_BOOL_YES and LANG_SET_BOOL_NO, | ||
227 | or dont save as "off" or "on" in the cfg */ | ||
228 | #define BOOL_SETTING(flags,var,lang_id,default,name,cfgvals,yes,no,cb) \ | ||
229 | {flags|F_BOOL_SETTING, &global_settings.var, \ | ||
230 | lang_id, BOOL(default),name,cfgvals, \ | ||
231 | {.bool_setting=(struct bool_setting[]){{cb,yes,no}}} } | ||
232 | |||
233 | /* bool setting which does use LANG_YES and _NO and save as "off,on" */ | ||
234 | #define OFFON_SETTING(flags,var,lang_id,default,name,cb) \ | ||
235 | {flags|F_BOOL_SETTING, &global_settings.var, \ | ||
236 | lang_id, BOOL(default),name,off_on, \ | ||
237 | {.bool_setting=(struct bool_setting[]) \ | ||
238 | {{cb,LANG_SET_BOOL_YES,LANG_SET_BOOL_NO}}} } | ||
239 | |||
240 | /* int variable which is NOT saved to .cfg files, | ||
241 | (Use NVRAM() in the flags to save to the nvram (or nvram.bin file) */ | ||
242 | #define SYSTEM_SETTING(flags,var,default) \ | ||
243 | {flags|F_T_INT, &global_status.var,-1, INT(default), \ | ||
244 | NULL, NULL, UNUSED} | ||
245 | |||
246 | /* setting which stores as a filename in the .cfgvals | ||
247 | prefix: The absolute path to not save in the variable, e.g /.rockbox/wps_file | ||
248 | suffx: The file extention (usually...) e.g .wps_file */ | ||
249 | #define FILENAME_SETTING(flags,var,name,default,prefix,suffix,len) \ | ||
250 | {flags|F_T_UCHARPTR, &global_settings.var,-1, \ | ||
251 | CHARPTR(default),name,NULL, \ | ||
252 | {.filename_setting= \ | ||
253 | (struct filename_setting[]){{prefix,suffix,len}}} } | ||
254 | |||
255 | /* Used for settings which use the set_option() setting screen. | ||
256 | the ... arg is a list of pointers to strings to display in the setting screen. | ||
257 | These can either be literal strings, or ID2P(LANG_*) */ | ||
258 | #define CHOICE_SETTING(flags,var,lang_id,default,name,cfg_vals,cb,count,...) \ | ||
259 | {flags|F_CHOICE_SETTING|F_T_INT, &global_settings.var, lang_id, \ | ||
260 | INT(default), name, cfg_vals, \ | ||
261 | {.choice_setting = (struct choice_setting[]){ \ | ||
262 | {cb, count, {.desc = (unsigned char*[]){__VA_ARGS__}}}}}} | ||
263 | |||
264 | /* Similar to above, except the strings to display are taken from cfg_vals, | ||
265 | the ... arg is a list of ID's to talk for the strings... can use TALK_ID()'s */ | ||
266 | #define STRINGCHOICE_SETTING(flags,var,lang_id,default,name,cfg_vals,cb,count,...) \ | ||
267 | {flags|F_CHOICE_SETTING|F_T_INT|F_CHOICETALKS, \ | ||
268 | &global_settings.var, lang_id, \ | ||
269 | INT(default), name, cfg_vals, \ | ||
270 | {.choice_setting = (struct choice_setting[]){ \ | ||
271 | {cb, count, {.talks = (int[]){__VA_ARGS__}}}}}} | ||
272 | |||
273 | /* for settings which use the set_int() setting screen. | ||
274 | unit is the UNIT_ define to display/talk. | ||
275 | the first one saves a string to the config file, | ||
276 | the second one saves the variable value to the config file */ | ||
277 | #define INT_SETTING_W_CFGVALS(flags, var, lang_id, default, name, cfg_vals, \ | ||
278 | unit, min, max, step, formatter, get_talk_id, cb) \ | ||
279 | {flags|F_INT_SETTING|F_T_INT, &global_settings.var, \ | ||
280 | lang_id, INT(default), name, cfg_vals, \ | ||
281 | {.int_setting = (struct int_setting[]){ \ | ||
282 | {cb, unit, min, max, step, formatter, get_talk_id}}}} | ||
283 | #define INT_SETTING(flags, var, lang_id, default, name, \ | ||
284 | unit, min, max, step, formatter, get_talk_id, cb) \ | ||
285 | {flags|F_INT_SETTING|F_T_INT, &global_settings.var, \ | ||
286 | lang_id, INT(default), name, NULL, \ | ||
287 | {.int_setting = (struct int_setting[]){ \ | ||
288 | {cb, unit, min, max, step, formatter, get_talk_id}}}} | ||
289 | |||
290 | #if CONFIG_CODEC == SWCODEC | 293 | #if CONFIG_CODEC == SWCODEC |
291 | static void crossfeed_format(char* buffer, int buffer_size, int value, | 294 | static void crossfeed_format(char* buffer, int buffer_size, int value, |
292 | const char* unit) | 295 | const char* unit) |