From a5278fa3db2582c49d04507b31bd08405df5adb7 Mon Sep 17 00:00:00 2001 From: Jonathan Gordon Date: Wed, 11 Jul 2007 05:41:23 +0000 Subject: Rearrange and cleanup settings code git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13851 a1c6a512-1295-4272-9138-f99709370657 --- apps/gui/option_select.c | 487 +++++++++++++++++++++++++++++++++++- apps/gui/option_select.h | 2 + apps/menu.c | 118 +-------- apps/menus/recording_menu.c | 1 + apps/plugin.c | 4 +- apps/plugin.h | 8 +- apps/plugins/lib/playback_control.c | 41 +-- apps/recorder/recording.c | 79 ++++++ apps/recorder/recording.h | 1 + apps/settings.c | 384 +--------------------------- apps/settings.h | 3 - 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 @@ * $Id$ * * Copyright (C) 2005 by Kevin Ferrare + * Copyright (C) 2007 by Jonathan Gordon * * All files in this archive are subject to the GNU General Public License. * See the file COPYING in the source tree root for full license agreement. @@ -16,12 +17,496 @@ * KIND, either express or implied. * ****************************************************************************/ - +#include +#include "config.h" #include "option_select.h" #include "sprintf.h" #include "kernel.h" #include "lang.h" +#include "talk.h" +#include "settings_list.h" +#include "sound.h" +#include "list.h" +#include "action.h" +#include "statusbar.h" +#include "misc.h" +#include "splash.h" + +static const char *unit_strings[] = +{ + [UNIT_INT] = "", [UNIT_MS] = "ms", + [UNIT_SEC] = "s", [UNIT_MIN] = "min", + [UNIT_HOUR]= "hr", [UNIT_KHZ] = "KHz", + [UNIT_DB] = "dB", [UNIT_PERCENT] = "%", + [UNIT_MAH] = "mAh", [UNIT_PIXEL] = "px", + [UNIT_PER_SEC] = "per sec", + [UNIT_HERTZ] = "Hz", + [UNIT_MB] = "MB", [UNIT_KBIT] = "kb/s", +}; + +char *option_get_valuestring(struct settings_list *setting, + char *buffer, int buf_len, + intptr_t temp_var) +{ + if ((setting->flags & F_BOOL_SETTING) == F_BOOL_SETTING) + { + bool val = (bool)temp_var; + snprintf(buffer, buf_len, "%s", + str(val? setting->bool_setting->lang_yes : + setting->bool_setting->lang_no)); + } +#if 0 /* probably dont need this one */ + else if ((setting->flags & F_FILENAME) == F_FILENAME) + { + struct filename_setting *info = setting->filename_setting; + snprintf(buffer, buf_len, "%s%s%s", info->prefix, + (char*)temp_var, info->suffix); + } +#endif + else if ((setting->flags & F_INT_SETTING) == F_INT_SETTING) + { + struct int_setting *info = setting->int_setting; + if (info->formatter) + info->formatter(buffer, buf_len, (int)temp_var, + unit_strings[info->unit]); + else + snprintf(buffer, buf_len, "%d %s", (int)temp_var, + unit_strings[info->unit]? + unit_strings[info->unit]:""); + } + else if ((setting->flags & F_T_SOUND) == F_T_SOUND) + { + char sign = ' ', *unit; + unit = (char*)sound_unit(setting->sound_setting->setting); + if (sound_numdecimals(setting->sound_setting->setting)) + { + int integer, dec; + int val = sound_val2phys(setting->sound_setting->setting, + (int)temp_var); + if(val < 0) + { + sign = '-'; + val = abs(val); + } + integer = val / 10; dec = val % 10; + snprintf(buffer, buf_len, "%c%d.%d %s", sign, integer, dec, unit); + } + else + snprintf(buffer, buf_len, "%d %s", (int)temp_var, unit); + } + else if ((setting->flags & F_CHOICE_SETTING) == F_CHOICE_SETTING) + { + if (setting->flags & F_CHOICETALKS) + { + int setting_id; + find_setting(setting->setting, &setting_id); + cfg_int_to_string(setting_id, (int)temp_var, buffer, buf_len); + } + else + { + int value= (int)temp_var; + char *val = P2STR(setting->choice_setting->desc[value]); + snprintf(buffer, buf_len, "%s", val); + } + } + return buffer; +} + +void option_talk(struct settings_list *setting, int temp_var) +{ + if (!talk_menus_enabled()) + return; + if ((setting->flags & F_BOOL_SETTING) == F_BOOL_SETTING) + { + bool val = temp_var==1?true:false; + talk_id(val? setting->bool_setting->lang_yes : + setting->bool_setting->lang_no, false); + } +#if 0 /* probably dont need this one */ + else if ((setting->flags & F_FILENAME) == F_FILENAME) + { + } +#endif + else if ((setting->flags & F_INT_SETTING) == F_INT_SETTING) + { + struct int_setting *info = setting->int_setting; + if (info->get_talk_id) + talk_id(info->get_talk_id((int)temp_var), false); + else + talk_value((int)temp_var, info->unit, false); + } + else if ((setting->flags & F_T_SOUND) == F_T_SOUND) + { + int talkunit = UNIT_DB; + const char *unit = sound_unit(setting->sound_setting->setting); + /* crude reconstruction */ + if (*unit == '%') + talkunit = UNIT_PERCENT; + else if (*unit == 'H') + talkunit = UNIT_HERTZ; + talk_value((int)temp_var, talkunit, false); + } + else if ((setting->flags & F_CHOICE_SETTING) == F_CHOICE_SETTING) + { + int value = (int)temp_var; + if (setting->flags & F_CHOICETALKS) + { + talk_id(setting->choice_setting->talks[value], false); + } + else + { + talk_id(P2ID(setting->choice_setting->desc[value]), false); + } + } +} +#if 0 +int option_select_next_val(struct settings_list *setting, + intptr_t temp_var) +{ + int val = 0; + if ((setting->flags & F_BOOL_SETTING) == F_BOOL_SETTING) + { + val = (bool)temp_var ? 0 : 1; + } + else if ((setting->flags & F_INT_SETTING) == F_INT_SETTING) + { + struct int_setting *info = setting->int_setting; + val = (int)temp_var + info->step; + if (val > info->max) + val = info->min; + } + else if ((setting->flags & F_T_SOUND) == F_T_SOUND) + { + int setting_id = setting->sound_setting->setting; + int steps = sound_steps(setting_id); + int min = sound_min(setting_id); + int max = sound_max(setting_id); + val = (int)temp_var + steps; + if (val > max) + val = min; + } + else if ((setting->flags & F_CHOICE_SETTING) == F_CHOICE_SETTING) + { + struct choice_setting *info = setting->choice_setting; + val = (int)temp_var; + if (val > info->count) + val = 0; + } + return val; +} + +int option_select_prev_val(struct settings_list *setting, + intptr_t temp_var) +{ + int val = 0; + if ((setting->flags & F_BOOL_SETTING) == F_BOOL_SETTING) + { + val = (bool)temp_var ? 0 : 1; + } + else if ((setting->flags & F_INT_SETTING) == F_INT_SETTING) + { + struct int_setting *info = setting->int_setting; + val = (int)temp_var - info->step; + if (val < info->min) + val = info->max; + } + else if ((setting->flags & F_T_SOUND) == F_T_SOUND) + { + int setting_id = setting->sound_setting->setting; + int steps = sound_steps(setting_id); + int min = sound_min(setting_id); + int max = sound_max(setting_id); + val = (int)temp_var -+ steps; + if (val < min) + val = max; + } + else if ((setting->flags & F_CHOICE_SETTING) == F_CHOICE_SETTING) + { + struct choice_setting *info = setting->choice_setting; + val = (int)temp_var; + if (val < 0) + val = info->count - 1; + } + return val; +} +#endif + +static int selection_to_val(struct settings_list *setting, int selection) +{ + int min = 0, max = 0, step = 1; + if (((setting->flags & F_BOOL_SETTING) == F_BOOL_SETTING) || + ((setting->flags & F_CHOICE_SETTING) == F_CHOICE_SETTING)) + return selection; + else if ((setting->flags & F_T_SOUND) == F_T_SOUND) + { + int setting_id = setting->sound_setting->setting; + step = sound_steps(setting_id); + max = sound_max(setting_id); + min = sound_min(setting_id); + } + else if ((setting->flags & F_INT_SETTING) == F_INT_SETTING) + { + struct int_setting *info = setting->int_setting; + min = info->min; + max = info->max; + step = info->step; + } + if (setting->flags & F_FLIPLIST) + { + int a; + a = min; min = max; max = a; + step = -step; + } + return max- (selection * step); +} +static char * value_setting_get_name_cb(int selected_item, + void * data, char *buffer) +{ + selected_item = selection_to_val(data, selected_item); + return option_get_valuestring(data, buffer, MAX_PATH, selected_item); +} + +/* wrapper to convert from int param to bool param in option_screen */ +static void (*boolfunction)(bool); +static void bool_funcwrapper(int value) +{ + if (value) + boolfunction(true); + else + boolfunction(false); +} + +bool option_screen(struct settings_list *setting, bool use_temp_var) +{ + int action; + bool done = false; + struct gui_synclist lists; + int oldvalue, nb_items = 0, selected = 0, temp_var; + int *variable; + bool allow_wrap = ((int*)setting->setting != &global_settings.volume); + int var_type = setting->flags&F_T_MASK; + void (*function)(int) = NULL; + + if (var_type == F_T_INT || var_type == F_T_UINT) + { + variable = use_temp_var ? &temp_var: (int*)setting->setting; + temp_var = oldvalue = *(int*)setting->setting; + } + else if (var_type == F_T_BOOL) + { + /* bools always use the temp variable... + if use_temp_var is false it will be copied to setting->setting every change */ + variable = &temp_var; + temp_var = oldvalue = *(bool*)setting->setting?1:0; + } + else return false; /* only int/bools can go here */ + gui_synclist_init(&lists, value_setting_get_name_cb, + (void*)setting, false, 1); + if (setting->lang_id == -1) + gui_synclist_set_title(&lists, + (char*)setting->cfg_vals, Icon_Questionmark); + else + gui_synclist_set_title(&lists, + str(setting->lang_id), Icon_Questionmark); + gui_synclist_set_icon_callback(&lists, NULL); + + /* set the number of items and current selection */ + if (var_type == F_T_INT || var_type == F_T_UINT) + { + if (setting->flags&F_CHOICE_SETTING) + { + nb_items = setting->choice_setting->count; + selected = oldvalue; + function = setting->choice_setting->option_callback; + } + else if (setting->flags&F_T_SOUND) + { + int setting_id = setting->sound_setting->setting; + int steps = sound_steps(setting_id); + int min = sound_min(setting_id); + int max = sound_max(setting_id); + nb_items = (max-min)/steps + 1; + selected = (max-oldvalue)/steps; + function = sound_get_fn(setting_id); + } + else + { + struct int_setting *info = setting->int_setting; + int min, max, step; + if (setting->flags&F_FLIPLIST) + { + min = info->max; + max = info->min; + step = -info->step; + } + else + { + max = info->max; + min = info->min; + step = info->step; + } + nb_items = (max-min)/step + 1; + selected = (max - oldvalue)/step; + function = info->option_callback; + } + } + else if (var_type == F_T_BOOL) + { + selected = oldvalue; + nb_items = 2; + boolfunction = setting->bool_setting->option_callback; + if (boolfunction) + function = bool_funcwrapper; + } + + gui_synclist_set_nb_items(&lists, nb_items); + gui_synclist_select_item(&lists, selected); + + gui_synclist_limit_scroll(&lists, true); + gui_synclist_draw(&lists); + action_signalscreenchange(); + /* talk the item */ + option_talk(setting, *variable); + while (!done) + { + action = get_action(CONTEXT_LIST, TIMEOUT_BLOCK); + if (action == ACTION_NONE) + continue; + if (gui_synclist_do_button(&lists,action, + allow_wrap? LIST_WRAP_UNLESS_HELD: LIST_WRAP_OFF)) + { + selected = gui_synclist_get_sel_pos(&lists); + *variable = selection_to_val(setting, selected); + if (var_type == F_T_BOOL) + { + if (!use_temp_var) + *(bool*)setting->setting = selected==1?true:false; + } + /* talk */ + option_talk(setting, *variable); + } + else if (action == ACTION_STD_CANCEL) + { + bool show_cancel = false; + if (use_temp_var) + show_cancel = true; + else if (var_type == F_T_INT || var_type == F_T_UINT) + { + if (*variable != oldvalue) + { + show_cancel = true; + *variable = oldvalue; + } + } + else + { + if (*variable != oldvalue) + { + show_cancel = true; + if (!use_temp_var) + *(bool*)setting->setting = oldvalue==1?true:false; + *variable = oldvalue; + } + } + if (show_cancel) + gui_syncsplash(HZ/2, str(LANG_MENU_SETTING_CANCEL)); + done = true; + } + else if (action == ACTION_STD_OK) + { + done = true; + } + else if(default_event_handler(action) == SYS_USB_CONNECTED) + return true; + gui_syncstatusbar_draw(&statusbars, false); + /* callback */ + if ( function ) + function(*variable); + } + + if (use_temp_var) + { + if (var_type == F_T_INT || var_type == F_T_UINT) + { + if (oldvalue != *variable) + { + *(int*)setting->setting = *variable; + settings_save(); + } + } + else if (oldvalue != *variable) + { + *(bool*)setting->setting = *variable?true:false; + settings_save(); + } + } + + action_signalscreenchange(); + return false; +} + +/****************************************************** + Compatability functions +*******************************************************/ +#define MAX_OPTIONS 32 +bool set_option(const char* string, void* variable, enum optiontype type, + const struct opt_items* options, + int numoptions, void (*function)(int)) +{ + int temp; + char *strings[MAX_OPTIONS]; + struct choice_setting data; + struct settings_list item; + for (temp=0; tempvariable, &setting_id); - bool ret_val = false; - unsigned char *title; - if (setting) - { - if ((temp->flags&MENU_TYPE_MASK) == MT_SETTING_W_TEXT) - title = temp->callback_and_desc->desc; - else - title = ID2P(setting->lang_id); - - if ((setting->flags&F_BOOL_SETTING) == F_BOOL_SETTING) - { - bool temp_var, *var; - bool show_icons = global_settings.show_icons; - if (setting->flags&F_TEMPVAR) - { - temp_var = *(bool*)setting->setting; - var = &temp_var; - } - else - { - var = (bool*)setting->setting; - } - set_bool_options(P2STR(title), var, - STR(setting->bool_setting->lang_yes), - STR(setting->bool_setting->lang_no), - setting->bool_setting->option_callback); - if (setting->flags&F_TEMPVAR) - *(bool*)setting->setting = temp_var; - if (show_icons != global_settings.show_icons) - ret_val = true; - } - else if (setting->flags&F_T_SOUND) - { - set_sound(P2STR(title), setting->setting, - setting->sound_setting->setting); - } - else /* other setting, must be an INT type */ - { - int temp_var, *var; - if (setting->flags&F_TEMPVAR) - { - temp_var = *(int*)setting->setting; - var = &temp_var; - } - else - { - var = (int*)setting->setting; - } - if (setting->flags&F_INT_SETTING) - { - int min, max, step; - if (setting->flags&F_FLIPLIST) - { - min = setting->int_setting->max; - max = setting->int_setting->min; - step = -setting->int_setting->step; - } - else - { - max = setting->int_setting->max; - min = setting->int_setting->min; - step = setting->int_setting->step; - } - set_int_ex(P2STR(title), NULL, - setting->int_setting->unit,var, - setting->int_setting->option_callback, - step, min, max, - setting->int_setting->formatter, - setting->int_setting->get_talk_id); - } - else if (setting->flags&F_CHOICE_SETTING) - { - static struct opt_items options[MAX_OPTIONS]; - char buffer[256]; - char *buf_start = buffer; - int buf_free = 256; - int i,j, count = setting->choice_setting->count; - for (i=0, j=0; iflags&F_CHOICETALKS) - { - if (cfg_int_to_string(setting_id, i, - buf_start, buf_free)) - { - int len = strlen(buf_start) +1; - options[j].string = buf_start; - buf_start += len; - buf_free -= len; - options[j].voice_id = - setting->choice_setting->talks[i]; - j++; - } - } - else - { - options[j].string = - P2STR(setting-> - choice_setting->desc[i]); - options[j].voice_id = - P2ID(setting-> - choice_setting->desc[i]); - j++; - } - } - set_option(P2STR(title), var, INT, - options,j, - setting-> - choice_setting->option_callback); - } - if (setting->flags&F_TEMPVAR) - *(int*)setting->setting = temp_var; - } - } - return ret_val; + option_screen((struct settings_list *)setting, + setting->flags&F_TEMPVAR); + return false; } 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 @@ #include "general.h" #endif #include "action.h" +#include "recording.h" 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 @@ #include "powermgmt.h" #include "splash.h" #include "logf.h" +#include "option_select.h" #if CONFIG_CHARGING #include "power.h" @@ -318,7 +319,6 @@ static const struct plugin_api rockbox_api = { sound_default, #endif sound_set, - set_sound, sound_min, sound_max, @@ -405,6 +405,8 @@ static const struct plugin_api rockbox_api = { &statusbars, gui_syncstatusbar_draw, /* options */ + find_setting, + option_screen, set_option, set_bool_options, 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 @@ #define PLUGIN_MAGIC 0x526F634B /* RocK */ /* increase this every time the api struct changes */ -#define PLUGIN_API_VERSION 61 +#define PLUGIN_API_VERSION 62 /* update this to latest version if a change to the api struct breaks backwards compatibility (and please take the opportunity to sort in any new function which are "waiting" at the end of the function table) */ -#define PLUGIN_MIN_API_VERSION 61 +#define PLUGIN_MIN_API_VERSION 62 /* plugin return codes */ enum plugin_status { @@ -418,8 +418,6 @@ struct plugin_api { int (*sound_default)(int setting); #endif void (*sound_set)(int setting, int value); - bool (*set_sound)(const unsigned char * string, - int* variable, int setting); int (*sound_min)(int setting); int (*sound_max)(int setting); #ifndef SIMULATOR @@ -509,6 +507,8 @@ struct plugin_api { void (*gui_syncstatusbar_draw)(struct gui_syncstatusbar * bars, bool force_redraw); /* options */ + const struct settings_list* (*find_setting)(void* variable, int *id); + bool (*option_screen)(struct settings_list *setting, bool use_temp_var); bool (*set_option)(const char* string, void* variable, enum optiontype type, const struct opt_items* options, 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) static bool volume(void) { - return api->set_sound("Volume", &api->global_settings->volume, - SOUND_VOLUME); + const struct settings_list* vol = + api->find_setting(&api->global_settings->volume, NULL); + return api->option_screen((struct settings_list*)vol, false); } static bool shuffle(void) { - struct opt_items names[2]; - names[0].string = "No"; - names[0].voice_id = -1; - names[1].string = "Yes"; - names[1].voice_id = -1; - - return api->set_option("Shuffle", &api->global_settings->playlist_shuffle, - BOOL, names, 2,NULL); + const struct settings_list* shuffle = + api->find_setting(&api->global_settings->playlist_shuffle, NULL); + return api->option_screen((struct settings_list*)shuffle, false); } static bool repeat_mode(void) { - bool result; - static const struct opt_items names[] = { - { "Off", -1 }, - { "Repeat All", -1 }, - { "Repeat One", -1 }, - { "Repeat Shuffle", -1 }, -#ifdef AB_REPEAT_ENABLE - { "Repeat A-B", -1 } -#endif - }; - + const struct settings_list* repeat = + api->find_setting(&api->global_settings->repeat_mode, NULL); int old_repeat = api->global_settings->repeat_mode; - - result = api->set_option( "Repeat Mode", - &api->global_settings->repeat_mode, - INT, names, NUM_REPEAT_MODES, NULL ); - + + api->option_screen((struct settings_list*)repeat, false); + if (old_repeat != api->global_settings->repeat_mode && (api->audio_status() & AUDIO_STATUS_PLAY)) api->audio_flush_and_reload_tracks(); - - return result; + + return false; } MENUITEM_FUNCTION(prevtrack_item, 0, "Previous Track", 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 @@ #include "action.h" #include "radio.h" #ifdef HAVE_RECORDING +/* This array holds the record timer interval lengths, in seconds */ +static const unsigned long rec_timer_seconds[] = +{ + 0, /* 0 means OFF */ + 5*60, /* 00:05 */ + 10*60, /* 00:10 */ + 15*60, /* 00:15 */ + 30*60, /* 00:30 */ + 60*60, /* 01:00 */ + 74*60, /* 74:00 */ + 80*60, /* 80:00 */ + 2*60*60, /* 02:00 */ + 4*60*60, /* 04:00 */ + 6*60*60, /* 06:00 */ + 8*60*60, /* 08:00 */ + 10L*60*60, /* 10:00 */ + 12L*60*60, /* 12:00 */ + 18L*60*60, /* 18:00 */ + 24L*60*60 /* 24:00 */ +}; + +static unsigned int rec_timesplit_seconds(void) +{ + return rec_timer_seconds[global_settings.rec_timesplit]; +} + +/* This array holds the record size interval lengths, in bytes */ +static const unsigned long rec_size_bytes[] = +{ + 0, /* 0 means OFF */ + 5*1024*1024, /* 5MB */ + 10*1024*1024, /* 10MB */ + 15*1024*1024, /* 15MB */ + 32*1024*1024, /* 32MB */ + 64*1024*1024, /* 64MB */ + 75*1024*1024, /* 75MB */ + 100*1024*1024, /* 100MB */ + 128*1024*1024, /* 128MB */ + 256*1024*1024, /* 256MB */ + 512*1024*1024, /* 512MB */ + 650*1024*1024, /* 650MB */ + 700*1024*1024, /* 700MB */ + 1024*1024*1024, /* 1GB */ + 1536*1024*1024, /* 1.5GB */ + 1792*1024*1024, /* 1.75GB */ +}; + +static unsigned long rec_sizesplit_bytes(void) +{ + return rec_size_bytes[global_settings.rec_sizesplit]; +} +/* + * Time strings used for the trigger durations. + * Keep synchronous to trigger_times in settings_apply_trigger + */ +const char * const trig_durations[TRIG_DURATION_COUNT] = +{ + "0s", "1s", "2s", "5s", + "10s", "15s", "20s", "25s", "30s", + "1min", "2min", "5min", "10min" +}; +void settings_apply_trigger(void) +{ + /* Keep synchronous to trig_durations and trig_durations_conf*/ + static const long trigger_times[TRIG_DURATION_COUNT] = { + 0, HZ, 2*HZ, 5*HZ, + 10*HZ, 15*HZ, 20*HZ, 25*HZ, 30*HZ, + 60*HZ, 2*60*HZ, 5*60*HZ, 10*60*HZ + }; + + peak_meter_define_trigger( + global_settings.rec_start_thres, + trigger_times[global_settings.rec_start_duration], + MIN(trigger_times[global_settings.rec_start_duration] / 2, 2*HZ), + global_settings.rec_stop_thres, + trigger_times[global_settings.rec_stop_postrec], + trigger_times[global_settings.rec_stop_gap] + ); +} /* recording screen status flags */ enum rec_status_flags { 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); bool recording_screen(bool no_source); char *rec_create_filename(char *buf); int rec_create_directory(void); +void settings_apply_trigger(void); /* If true, start recording automatically when recording_sreen() is entered */ 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) talk_id(setting->lang_id,false); } -static int selected_setting; /* Used by the callback */ - -static void dec_sound_formatter(char *buffer, int buffer_size, - int val, const char *unit) -{ - val = sound_val2phys(selected_setting, val); - char sign = ' '; - if(val < 0) - { - sign = '-'; - val = abs(val); - } - int integer = val / 10; - int dec = val % 10; - snprintf(buffer, buffer_size, "%c%d.%d %s", sign, integer, dec, unit); -} - -bool set_sound(const unsigned char * string, - int* variable, - int setting) -{ - int talkunit = UNIT_INT; - const char* unit = sound_unit(setting); - int numdec = sound_numdecimals(setting); - int steps = sound_steps(setting); - int min = sound_min(setting); - int max = sound_max(setting); - sound_set_type* sound_callback = sound_get_fn(setting); - if (*unit == 'd') /* crude reconstruction */ - talkunit = UNIT_DB; - else if (*unit == '%') - talkunit = UNIT_PERCENT; - else if (*unit == 'H') - talkunit = UNIT_HERTZ; - if (!numdec) - return set_int(string, unit, talkunit, variable, sound_callback, - steps, min, max, NULL ); - else - {/* Decimal number */ - selected_setting=setting; - return set_int(string, unit, talkunit, variable, sound_callback, - steps, min, max, &dec_sound_formatter ); - } -} - bool set_bool(const char* string, bool* variable ) { return set_bool_options(string, variable, @@ -985,15 +940,6 @@ bool set_bool(const char* string, bool* variable ) NULL); } -/* wrapper to convert from int param to bool param in set_option */ -static void (*boolfunction)(bool); -static void bool_funcwrapper(int value) -{ - if (value) - boolfunction(true); - else - boolfunction(false); -} bool set_bool_options(const char* string, bool* variable, const char* yes_str, int yes_voice, @@ -1006,237 +952,11 @@ bool set_bool_options(const char* string, bool* variable, }; bool result; - boolfunction = function; result = set_option(string, variable, BOOL, names, 2, - function ? bool_funcwrapper : NULL); + (void (*)(int))function); return result; } -static void talk_unit(int unit, int value, long (*get_talk_id)(int value)) -{ - if (talk_menus_enabled()) - { - if (get_talk_id) - { - talk_id(get_talk_id(value),false); - } - else if (unit < UNIT_LAST) - { /* use the available unit definition */ - talk_value(value, unit, false); - } - else - { /* say the number, followed by an arbitrary voice ID */ - talk_number(value, false); - talk_id(unit, true); - } - } -} - -struct value_setting_data { - enum optiontype type; - /* used for "value" settings.. */ - int max; - int step; - int voice_unit; - const char * unit; - void (*formatter)(char* dest, int dest_length, - int value, const char* unit); - long (*get_talk_id)(int value); - /* used for BOOL and "choice" settings */ - struct opt_items* options; -}; - -static char * value_setting_get_name_cb(int selected_item,void * data, char *buffer) -{ - struct value_setting_data* cb_data = - (struct value_setting_data*)data; - if (cb_data->type == INT && !cb_data->options) - { - int item = cb_data->max -(selected_item*cb_data->step); - if (cb_data->formatter) - cb_data->formatter(buffer, MAX_PATH,item,cb_data->unit); - else - snprintf(buffer, MAX_PATH,"%d %s",item,cb_data->unit); - } - else strcpy(buffer,P2STR(cb_data->options[selected_item].string)); - return buffer; -} -#define type_fromvoidptr(type, value) \ - (type == INT)? \ - (int)(*(int*)(value)) \ - : \ - (bool)(*(bool*)(value)) -static bool do_set_setting(const unsigned char* string, void *variable, - int nb_items,int selected, - struct value_setting_data *cb_data, - void (*function)(int)) -{ - int action; - bool done = false; - struct gui_synclist lists; - int oldvalue; - bool allow_wrap = true; - - if (cb_data->type == INT) - { - oldvalue = *(int*)variable; - if (variable == &global_settings.volume) - allow_wrap = false; - } - else oldvalue = *(bool*)variable; - - gui_synclist_init(&lists,value_setting_get_name_cb,(void*)cb_data,false,1); - gui_synclist_set_title(&lists, (char*)string,Icon_Questionmark); - gui_synclist_set_icon_callback(&lists,NULL); - gui_synclist_set_nb_items(&lists,nb_items); - gui_synclist_limit_scroll(&lists,true); - gui_synclist_select_item(&lists, selected); - - if (talk_menus_enabled()) - { - if (cb_data->type == INT && !cb_data->options) - talk_unit(cb_data->voice_unit, *(int*)variable, cb_data->get_talk_id); - else - talk_id(cb_data->options[selected].voice_id, false); - } - - gui_synclist_draw(&lists); - action_signalscreenchange(); - while (!done) - { - - action = get_action(CONTEXT_LIST,TIMEOUT_BLOCK); - if (action == ACTION_NONE) - continue; - if (gui_synclist_do_button(&lists,action, - allow_wrap?LIST_WRAP_UNLESS_HELD:LIST_WRAP_OFF)) - { - if (talk_menus_enabled()) - { - int value; - if (cb_data->type == INT && !cb_data->options) - { - value = cb_data->max - - gui_synclist_get_sel_pos(&lists)*cb_data->step; - talk_unit(cb_data->voice_unit, value, cb_data->get_talk_id); - } - else - { - value = gui_synclist_get_sel_pos(&lists); - talk_id(cb_data->options[value].voice_id, false); - } - } - if (cb_data->type == INT && !cb_data->options) - *(int*)variable = cb_data->max - - gui_synclist_get_sel_pos(&lists)*cb_data->step; - else if (cb_data->type == BOOL) - *(bool*)variable = gui_synclist_get_sel_pos(&lists) ? true : false; - else *(int*)variable = gui_synclist_get_sel_pos(&lists); - } - else if (action == ACTION_STD_CANCEL) - { - if (cb_data->type == INT) - { - if (*(int*)variable != oldvalue) - { - gui_syncsplash(HZ/2, str(LANG_MENU_SETTING_CANCEL)); - *(int*)variable = oldvalue; - } - } - else - { - if (*(bool*)variable != (bool)oldvalue) - { - gui_syncsplash(HZ/2, str(LANG_MENU_SETTING_CANCEL)); - *(bool*)variable = (bool)oldvalue; - } - } - done = true; - } - else if (action == ACTION_STD_OK) - { - done = true; - } - else if(default_event_handler(action) == SYS_USB_CONNECTED) - return true; - gui_syncstatusbar_draw(&statusbars, false); - if ( function ) - function(type_fromvoidptr(cb_data->type,variable)); - } - if (cb_data->type == INT) - { - if (oldvalue != *(int*)variable) - settings_save(); - } - else if (oldvalue != *(bool*)variable) - settings_save(); - - action_signalscreenchange(); - return false; -} -static const char *unit_strings[] = -{ - [UNIT_INT] - = "", - [UNIT_MS] - = "ms", - [UNIT_SEC] - = "s", - [UNIT_MIN] - = "min", - [UNIT_HOUR] - = "hr", - [UNIT_KHZ] - = "KHz", - [UNIT_DB] - = "dB", - [UNIT_PERCENT] - = "%", - [UNIT_MAH] - = "mAh", - [UNIT_PIXEL] - = "px", - [UNIT_PER_SEC] - = "per sec", - [UNIT_HERTZ] - = "Hz", - [UNIT_MB] - = "MB", - [UNIT_KBIT] - = "kb/s", -}; -bool set_int_ex(const unsigned char* string, - const char* unit, - int voice_unit, - int* variable, - void (*function)(int), - int step, - int min, - int max, - void (*formatter)(char*, int, int, const char*), - long (*get_talk_id)(int)) -{ - int count = (max-min)/step + 1; -#if CONFIG_KEYPAD != PLAYER_PAD - struct value_setting_data data = { - INT,max, step, voice_unit,unit,formatter,get_talk_id,NULL }; - if (voice_unit < UNIT_LAST) - data.unit = unit_strings[voice_unit]; - else - data.unit = str(voice_unit); - return do_set_setting(string,variable,count, - (max-*variable)/step, &data,function); -#else - struct value_setting_data data = { - INT,min, -step, voice_unit,unit,formatter,get_talk_id,NULL }; - if (voice_unit < UNIT_LAST) - data.unit = unit_strings[voice_unit]; - else - data.unit = str(voice_unit); - return do_set_setting(string,variable,count, - (*variable-min)/step, &data,function); -#endif -} bool set_int(const unsigned char* string, const char* unit, int voice_unit, @@ -1250,25 +970,7 @@ bool set_int(const unsigned char* string, return set_int_ex(string, unit, voice_unit, variable, function, step, min, max, formatter, NULL); } -/* NOTE: the 'type' parameter specifies the actual type of the variable - that 'variable' points to. not the value within. Only variables with - type 'bool' should use parameter BOOL. - - The type separation is necessary since int and bool are fundamentally - different and bit-incompatible types and can not share the same access - code. */ -bool set_option(const char* string, void* variable, enum optiontype type, - const struct opt_items* options, int numoptions, void (*function)(int)) -{ - struct value_setting_data data = { - type,0, 0, 0,NULL,NULL,NULL,(struct opt_items*)options }; - int selected; - if (type == BOOL) - selected = *(bool*)variable ? 1 : 0; - else selected = *(int*)variable; - return do_set_setting(string,variable,numoptions, - selected, &data,function); -} + /** extra stuff which is probably misplaced **/ @@ -1303,85 +1005,3 @@ void set_file(char* filename, char* setting, int maxlen) settings_save(); } -#ifdef HAVE_RECORDING -/* This array holds the record timer interval lengths, in seconds */ -static const unsigned long rec_timer_seconds[] = -{ - 0, /* 0 means OFF */ - 5*60, /* 00:05 */ - 10*60, /* 00:10 */ - 15*60, /* 00:15 */ - 30*60, /* 00:30 */ - 60*60, /* 01:00 */ - 74*60, /* 74:00 */ - 80*60, /* 80:00 */ - 2*60*60, /* 02:00 */ - 4*60*60, /* 04:00 */ - 6*60*60, /* 06:00 */ - 8*60*60, /* 08:00 */ - 10L*60*60, /* 10:00 */ - 12L*60*60, /* 12:00 */ - 18L*60*60, /* 18:00 */ - 24L*60*60 /* 24:00 */ -}; - -unsigned int rec_timesplit_seconds(void) -{ - return rec_timer_seconds[global_settings.rec_timesplit]; -} - -/* This array holds the record size interval lengths, in bytes */ -static const unsigned long rec_size_bytes[] = -{ - 0, /* 0 means OFF */ - 5*1024*1024, /* 5MB */ - 10*1024*1024, /* 10MB */ - 15*1024*1024, /* 15MB */ - 32*1024*1024, /* 32MB */ - 64*1024*1024, /* 64MB */ - 75*1024*1024, /* 75MB */ - 100*1024*1024, /* 100MB */ - 128*1024*1024, /* 128MB */ - 256*1024*1024, /* 256MB */ - 512*1024*1024, /* 512MB */ - 650*1024*1024, /* 650MB */ - 700*1024*1024, /* 700MB */ - 1024*1024*1024, /* 1GB */ - 1536*1024*1024, /* 1.5GB */ - 1792*1024*1024, /* 1.75GB */ -}; - -unsigned long rec_sizesplit_bytes(void) -{ - return rec_size_bytes[global_settings.rec_sizesplit]; -} -/* - * Time strings used for the trigger durations. - * Keep synchronous to trigger_times in settings_apply_trigger - */ -const char * const trig_durations[TRIG_DURATION_COUNT] = -{ - "0s", "1s", "2s", "5s", - "10s", "15s", "20s", "25s", "30s", - "1min", "2min", "5min", "10min" -}; - -void settings_apply_trigger(void) -{ - /* Keep synchronous to trig_durations and trig_durations_conf*/ - static const long trigger_times[TRIG_DURATION_COUNT] = { - 0, HZ, 2*HZ, 5*HZ, - 10*HZ, 15*HZ, 20*HZ, 25*HZ, 30*HZ, - 60*HZ, 2*60*HZ, 5*60*HZ, 10*60*HZ - }; - - peak_meter_define_trigger( - global_settings.rec_start_thres, - trigger_times[global_settings.rec_start_duration], - MIN(trigger_times[global_settings.rec_start_duration] / 2, 2*HZ), - global_settings.rec_stop_thres, - trigger_times[global_settings.rec_stop_postrec], - trigger_times[global_settings.rec_stop_gap] - ); -} -#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, bool set_time_screen(const char* string, struct tm *tm); int read_line(int fd, char* buffer, int buffer_size); void set_file(char* filename, char* setting, int maxlen); -unsigned int rec_timesplit_seconds(void); -unsigned long rec_sizesplit_bytes(void); -void settings_apply_trigger(void); /** 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 @@ #include "radio.h" #endif + +#define NVRAM(bytes) (bytes<