summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Gordon <rockbox@jdgordon.info>2007-07-11 05:41:23 +0000
committerJonathan Gordon <rockbox@jdgordon.info>2007-07-11 05:41:23 +0000
commita5278fa3db2582c49d04507b31bd08405df5adb7 (patch)
tree853ffc4e0967b37b808320f99260e56e3ecdfdd4
parent50dc0cabe3bfa3aeee1cba40d1e31c69a073227f (diff)
downloadrockbox-a5278fa3db2582c49d04507b31bd08405df5adb7.tar.gz
rockbox-a5278fa3db2582c49d04507b31bd08405df5adb7.zip
Rearrange and cleanup settings code
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13851 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/gui/option_select.c487
-rw-r--r--apps/gui/option_select.h2
-rw-r--r--apps/menu.c118
-rw-r--r--apps/menus/recording_menu.c1
-rw-r--r--apps/plugin.c4
-rw-r--r--apps/plugin.h8
-rw-r--r--apps/plugins/lib/playback_control.c41
-rw-r--r--apps/recorder/recording.c79
-rw-r--r--apps/recorder/recording.h1
-rw-r--r--apps/settings.c384
-rw-r--r--apps/settings.h3
-rw-r--r--apps/settings_list.c191
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
35static 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
47char *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
115void 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
163int 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
198int 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
234static 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}
262static 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 */
270static void (*boolfunction)(bool);
271static void bool_funcwrapper(int value)
272{
273 if (value)
274 boolfunction(true);
275 else
276 boolfunction(false);
277}
278
279bool 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
452bool 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
484bool 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 */
25void option_select_init_items(struct option_select * opt, 510void 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
24bool option_screen(struct settings_list *setting, bool use_temp_var);
25
24struct option_select 26struct 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
378int do_menu(const struct menu_item_ex *start_menu, int *start_selected) 268int 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
67static bool no_source_in_menu = true; 68static 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 */
126enum plugin_status { 126enum 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
60static bool volume(void) 60static 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
66static bool shuffle(void) 67static 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
78static bool repeat_mode(void) 74static 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}
103MENUITEM_FUNCTION(prevtrack_item, 0, "Previous Track", 88MENUITEM_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 */
73static 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
93static 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 */
99static 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
119static 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 */
127const 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
134void 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 */
74enum rec_status_flags 153enum 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);
24bool recording_screen(bool no_source); 24bool recording_screen(bool no_source);
25char *rec_create_filename(char *buf); 25char *rec_create_filename(char *buf);
26int rec_create_directory(void); 26int rec_create_directory(void);
27void 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 */
29extern bool recording_start_automatic; 30extern 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
935static int selected_setting; /* Used by the callback */
936
937static 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
952bool 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
980bool set_bool(const char* string, bool* variable ) 935bool 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 */
989static void (*boolfunction)(bool);
990static void bool_funcwrapper(int value)
991{
992 if (value)
993 boolfunction(true);
994 else
995 boolfunction(false);
996}
997 943
998bool set_bool_options(const char* string, bool* variable, 944bool 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
1015static 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
1035struct 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
1049static 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))
1069static 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}
1177static 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};
1208bool 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}
1240bool set_int(const unsigned char* string, 960bool 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. */
1260bool 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 */
1308static 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
1328unsigned 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 */
1334static 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
1354unsigned 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 */
1362const 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
1369void 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,
282bool set_time_screen(const char* string, struct tm *tm); 282bool set_time_screen(const char* string, struct tm *tm);
283int read_line(int fd, char* buffer, int buffer_size); 283int read_line(int fd, char* buffer, int buffer_size);
284void set_file(char* filename, char* setting, int maxlen); 284void set_file(char* filename, char* setting, int maxlen);
285unsigned int rec_timesplit_seconds(void);
286unsigned long rec_sizesplit_bytes(void);
287void 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 */
51static const char off_on[] = "off,on"; 148static const char off_on[] = "off,on";
52static const char off_on_ask[] = "off,on,ask"; 149static 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
291static void crossfeed_format(char* buffer, int buffer_size, int value, 294static void crossfeed_format(char* buffer, int buffer_size, int value,
292 const char* unit) 295 const char* unit)