summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Arnold <amiconn@rockbox.org>2007-11-25 17:36:21 +0000
committerJens Arnold <amiconn@rockbox.org>2007-11-25 17:36:21 +0000
commitd490f441126542f961da4132b59d843140709b3e (patch)
treeef1c0e0cf4b5cd453d01101432990a02d8ba88a9
parent54ecc698a54cf0b30dfda243ff149a1c6858e0f2 (diff)
downloadrockbox-d490f441126542f961da4132b59d843140709b3e.tar.gz
rockbox-d490f441126542f961da4132b59d843140709b3e.zip
New way of handling integer settings with variable steps: table settings (FS #8186, with fixes by me). This allows to get rid of those synchronised tables in firmware/ and apps/, making things more flexible and less error prone. First application: backlight timeouts. * Make some more things 'const'.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@15803 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/gui/gwps-common.c6
-rw-r--r--apps/gui/option_select.c102
-rw-r--r--apps/settings.c50
-rw-r--r--apps/settings_list.c97
-rw-r--r--apps/settings_list.h34
-rw-r--r--firmware/backlight.c44
-rw-r--r--firmware/export/backlight.h11
7 files changed, 223 insertions, 121 deletions
diff --git a/apps/gui/gwps-common.c b/apps/gui/gwps-common.c
index 8491a6dc5f..ee0bc3bdb4 100644
--- a/apps/gui/gwps-common.c
+++ b/apps/gui/gwps-common.c
@@ -2009,8 +2009,7 @@ bool gui_wps_refresh(struct gui_wps *gwps,
2009 { 2009 {
2010 /* turn on backlight n seconds before track ends, and turn it off n 2010 /* turn on backlight n seconds before track ends, and turn it off n
2011 seconds into the new track. n == backlight_timeout, or 5s */ 2011 seconds into the new track. n == backlight_timeout, or 5s */
2012 int n = backlight_timeout_value[global_settings.backlight_timeout] 2012 int n = global_settings.backlight_timeout * 1000;
2013 * 1000;
2014 2013
2015 if ( n < 1000 ) 2014 if ( n < 1000 )
2016 n = 5000; /* use 5s if backlight is always on or off */ 2015 n = 5000; /* use 5s if backlight is always on or off */
@@ -2027,8 +2026,7 @@ bool gui_wps_refresh(struct gui_wps *gwps,
2027 /* turn on remote backlight n seconds before track ends, and turn it 2026 /* turn on remote backlight n seconds before track ends, and turn it
2028 off n seconds into the new track. n == remote_backlight_timeout, 2027 off n seconds into the new track. n == remote_backlight_timeout,
2029 or 5s */ 2028 or 5s */
2030 int n = backlight_timeout_value[global_settings.remote_backlight_timeout] 2029 int n = global_settings.remote_backlight_timeout * 1000;
2031 * 1000;
2032 2030
2033 if ( n < 1000 ) 2031 if ( n < 1000 )
2034 n = 5000; /* use 5s if backlight is always on or off */ 2032 n = 5000; /* use 5s if backlight is always on or off */
diff --git a/apps/gui/option_select.c b/apps/gui/option_select.c
index 47e585cdbd..54413555c8 100644
--- a/apps/gui/option_select.c
+++ b/apps/gui/option_select.c
@@ -57,7 +57,9 @@ static const char *unit_strings[] =
57 [UNIT_MB] = "MB", [UNIT_KBIT] = "kb/s", 57 [UNIT_MB] = "MB", [UNIT_KBIT] = "kb/s",
58 [UNIT_PM_TICK] = "units/10ms", 58 [UNIT_PM_TICK] = "units/10ms",
59}; 59};
60 60/* these two vars are needed so arbitrary values can be added to the
61 TABLE_SETTING settings if the F_ALLOW_ARBITRARY_VALS flag is set */
62static int table_setting_oldval = 0, table_setting_array_position = 0;
61static char *option_get_valuestring(struct settings_list *setting, 63static char *option_get_valuestring(struct settings_list *setting,
62 char *buffer, int buf_len, 64 char *buffer, int buf_len,
63 intptr_t temp_var) 65 intptr_t temp_var)
@@ -77,16 +79,27 @@ static char *option_get_valuestring(struct settings_list *setting,
77 (char*)temp_var, info->suffix); 79 (char*)temp_var, info->suffix);
78 } 80 }
79#endif 81#endif
80 else if ((setting->flags & F_INT_SETTING) == F_INT_SETTING) 82 else if (((setting->flags & F_INT_SETTING) == F_INT_SETTING) ||
83 ((setting->flags & F_TABLE_SETTING) == F_TABLE_SETTING))
81 { 84 {
82 struct int_setting *info = setting->int_setting; 85 const struct int_setting *int_info = setting->int_setting;
83 if (info->formatter) 86 const struct table_setting *tbl_info = setting->table_setting;
84 info->formatter(buffer, buf_len, (int)temp_var, 87 const char *unit;
85 unit_strings[info->unit]); 88 void (*formatter)(char*, size_t, int, const char*);
89 if ((setting->flags & F_INT_SETTING) == F_INT_SETTING)
90 {
91 formatter = int_info->formatter;
92 unit = unit_strings[int_info->unit];
93 }
94 else
95 {
96 formatter = tbl_info->formatter;
97 unit = unit_strings[tbl_info->unit];
98 }
99 if (formatter)
100 formatter(buffer, buf_len, (int)temp_var, unit);
86 else 101 else
87 snprintf(buffer, buf_len, "%d %s", (int)temp_var, 102 snprintf(buffer, buf_len, "%d %s", (int)temp_var, unit?unit:"");
88 unit_strings[info->unit]?
89 unit_strings[info->unit]:"");
90 } 103 }
91 else if ((setting->flags & F_T_SOUND) == F_T_SOUND) 104 else if ((setting->flags & F_T_SOUND) == F_T_SOUND)
92 { 105 {
@@ -113,7 +126,7 @@ static char *option_get_valuestring(struct settings_list *setting,
113 if (setting->flags & F_CHOICETALKS) 126 if (setting->flags & F_CHOICETALKS)
114 { 127 {
115 int setting_id; 128 int setting_id;
116 struct choice_setting *info = setting->choice_setting; 129 const struct choice_setting *info = setting->choice_setting;
117 if (info->talks[(int)temp_var] < LANG_LAST_INDEX_IN_ARRAY) 130 if (info->talks[(int)temp_var] < LANG_LAST_INDEX_IN_ARRAY)
118 { 131 {
119 snprintf(buffer, buf_len, "%s", str(info->talks[(int)temp_var])); 132 snprintf(buffer, buf_len, "%s", str(info->talks[(int)temp_var]));
@@ -149,13 +162,27 @@ static int option_talk(int selected_item, void * data)
149 { 162 {
150 } 163 }
151#endif 164#endif
152 else if ((setting->flags & F_INT_SETTING) == F_INT_SETTING) 165 else if (((setting->flags & F_INT_SETTING) == F_INT_SETTING) ||
166 ((setting->flags & F_TABLE_SETTING) == F_TABLE_SETTING))
153 { 167 {
154 struct int_setting *info = setting->int_setting; 168 const struct int_setting *int_info = setting->int_setting;
155 if (info->get_talk_id) 169 const struct table_setting *tbl_info = setting->table_setting;
156 talk_id(info->get_talk_id(temp_var), false); 170 int unit;
157 else 171 long (*get_talk_id)(int);
158 talk_value(temp_var, info->unit, false); 172 if ((setting->flags & F_INT_SETTING) == F_INT_SETTING)
173 {
174 unit = int_info->unit;
175 get_talk_id = int_info->get_talk_id;
176 }
177 else
178 {
179 unit = tbl_info->unit;
180 get_talk_id = tbl_info->get_talk_id;
181 }
182 if (get_talk_id)
183 talk_id(get_talk_id((int)temp_var), false);
184 else
185 talk_value((int)temp_var, unit, false);
159 } 186 }
160 else if ((setting->flags & F_T_SOUND) == F_T_SOUND) 187 else if ((setting->flags & F_T_SOUND) == F_T_SOUND)
161 { 188 {
@@ -261,6 +288,20 @@ static int selection_to_val(struct settings_list *setting, int selection)
261 if (((setting->flags & F_BOOL_SETTING) == F_BOOL_SETTING) || 288 if (((setting->flags & F_BOOL_SETTING) == F_BOOL_SETTING) ||
262 ((setting->flags & F_CHOICE_SETTING) == F_CHOICE_SETTING)) 289 ((setting->flags & F_CHOICE_SETTING) == F_CHOICE_SETTING))
263 return selection; 290 return selection;
291 else if ((setting->flags & F_TABLE_SETTING) == F_TABLE_SETTING)
292 {
293 const struct table_setting *info = setting->table_setting;
294 if (setting->flags&F_ALLOW_ARBITRARY_VALS &&
295 table_setting_array_position != -1 &&
296 (selection >= table_setting_array_position))
297 {
298 if (selection == table_setting_array_position)
299 return table_setting_oldval;
300 return info->values[selection-1];
301 }
302 else
303 return info->values[selection];
304 }
264 else if ((setting->flags & F_T_SOUND) == F_T_SOUND) 305 else if ((setting->flags & F_T_SOUND) == F_T_SOUND)
265 { 306 {
266 int setting_id = setting->sound_setting->setting; 307 int setting_id = setting->sound_setting->setting;
@@ -276,7 +317,7 @@ static int selection_to_val(struct settings_list *setting, int selection)
276 } 317 }
277 else if ((setting->flags & F_INT_SETTING) == F_INT_SETTING) 318 else if ((setting->flags & F_INT_SETTING) == F_INT_SETTING)
278 { 319 {
279 struct int_setting *info = setting->int_setting; 320 const struct int_setting *info = setting->int_setting;
280#ifndef ASCENDING_INT_SETTINGS 321#ifndef ASCENDING_INT_SETTINGS
281 min = info->min; 322 min = info->min;
282 max = info->max; 323 max = info->max;
@@ -331,7 +372,7 @@ bool option_screen(struct settings_list *setting,
331 temp_var = oldvalue = *(bool*)setting->setting?1:0; 372 temp_var = oldvalue = *(bool*)setting->setting?1:0;
332 } 373 }
333 else return false; /* only int/bools can go here */ 374 else return false; /* only int/bools can go here */
334 gui_synclist_init(&lists, value_setting_get_name_cb, 375 gui_synclist_init(&lists, value_setting_get_name_cb,
335 (void*)setting, false, 1); 376 (void*)setting, false, 1);
336 if (setting->lang_id == -1) 377 if (setting->lang_id == -1)
337 title = (char*)setting->cfg_vals; 378 title = (char*)setting->cfg_vals;
@@ -352,6 +393,28 @@ bool option_screen(struct settings_list *setting,
352 selected = oldvalue; 393 selected = oldvalue;
353 function = setting->choice_setting->option_callback; 394 function = setting->choice_setting->option_callback;
354 } 395 }
396 else if (setting->flags&F_TABLE_SETTING)
397 {
398 const struct table_setting *info = setting->table_setting;
399 int i;
400 nb_items = info->count;
401 selected = 0;
402 table_setting_array_position = -1;
403 for (i=0;selected==0 && i<nb_items;i++)
404 {
405 if (setting->flags&F_ALLOW_ARBITRARY_VALS &&
406 (oldvalue < info->values[i]))
407 {
408 table_setting_oldval = oldvalue;
409 table_setting_array_position = i;
410 selected = i;
411 nb_items++;
412 }
413 else if (oldvalue == info->values[i])
414 selected = i;
415 }
416 function = info->option_callback;
417 }
355 else if (setting->flags&F_T_SOUND) 418 else if (setting->flags&F_T_SOUND)
356 { 419 {
357 int setting_id = setting->sound_setting->setting; 420 int setting_id = setting->sound_setting->setting;
@@ -368,7 +431,7 @@ bool option_screen(struct settings_list *setting,
368 } 431 }
369 else 432 else
370 { 433 {
371 struct int_setting *info = setting->int_setting; 434 const struct int_setting *info = setting->int_setting;
372 int min, max, step; 435 int min, max, step;
373 max = info->max; 436 max = info->max;
374 min = info->min; 437 min = info->min;
@@ -390,7 +453,6 @@ bool option_screen(struct settings_list *setting,
390 if (boolfunction) 453 if (boolfunction)
391 function = bool_funcwrapper; 454 function = bool_funcwrapper;
392 } 455 }
393
394 gui_synclist_set_nb_items(&lists, nb_items); 456 gui_synclist_set_nb_items(&lists, nb_items);
395 gui_synclist_select_item(&lists, selected); 457 gui_synclist_select_item(&lists, selected);
396 458
diff --git a/apps/settings.c b/apps/settings.c
index 6467a0e4d6..b22c521fd8 100644
--- a/apps/settings.c
+++ b/apps/settings.c
@@ -299,7 +299,17 @@ bool settings_load_config(const char* file, bool apply)
299 } 299 }
300 else 300 else
301 { 301 {
302 cfg_string_to_int(i,(int*)settings[i].setting,value); 302 int temp, *v = (int*)settings[i].setting;
303 bool found = cfg_string_to_int(i, &temp, value);
304 if (found)
305 {
306 if (settings[i].flags&F_TABLE_SETTING)
307 *v = settings[i].table_setting->values[temp];
308 else
309 *v = temp;
310 }
311 else
312 *v = atoi(value);
303 } 313 }
304 break; 314 break;
305 case F_T_BOOL: 315 case F_T_BOOL:
@@ -353,9 +363,40 @@ bool settings_load_config(const char* file, bool apply)
353 363
354bool cfg_int_to_string(int setting_id, int val, char* buf, int buf_len) 364bool cfg_int_to_string(int setting_id, int val, char* buf, int buf_len)
355{ 365{
366 int flags = settings[setting_id].flags;
356 const char* start = settings[setting_id].cfg_vals; 367 const char* start = settings[setting_id].cfg_vals;
357 char* end = NULL; 368 char* end = NULL;
358 int count = 0; 369 int count = 0;
370
371 if ((flags&F_T_MASK)==F_T_INT &&
372 flags&F_TABLE_SETTING)
373 {
374 const int *value = settings[setting_id].table_setting->values;
375 while (start)
376 {
377 end = strchr(start,',');
378 if (value[count] == val)
379 {
380 if (end == NULL)
381 strncpy(buf, start, buf_len);
382 else
383 {
384 int len = (buf_len > (end-start))? end-start: buf_len;
385 strncpy(buf, start, len);
386 buf[len] = '\0';
387 }
388 return true;
389 }
390 count++;
391
392 if (end)
393 start = end+1;
394 else
395 break;
396 }
397 return false;
398 }
399
359 while (count < val) 400 while (count < val)
360 { 401 {
361 start = strchr(start,','); 402 start = strchr(start,',');
@@ -457,8 +498,11 @@ static bool settings_write_config(char* filename, int options)
457 } 498 }
458 else 499 else
459 { 500 {
460 cfg_int_to_string(i, *(int*)settings[i].setting, 501 if (cfg_int_to_string(i, *(int*)settings[i].setting,
461 value, MAX_PATH); 502 value, MAX_PATH) == false)
503 {
504 snprintf(value,MAX_PATH,"%d",*(int*)settings[i].setting);
505 }
462 } 506 }
463 break; 507 break;
464 case F_T_BOOL: 508 case F_T_BOOL:
diff --git a/apps/settings_list.c b/apps/settings_list.c
index ea1e2f9bcb..ab6af2dfad 100644
--- a/apps/settings_list.c
+++ b/apps/settings_list.c
@@ -20,6 +20,7 @@
20#include "config.h" 20#include "config.h"
21#include <stdbool.h> 21#include <stdbool.h>
22#include <string.h> 22#include <string.h>
23#include "system.h"
23#include "ata.h" 24#include "ata.h"
24#include "lang.h" 25#include "lang.h"
25#include "talk.h" 26#include "talk.h"
@@ -103,7 +104,7 @@
103#define FILENAME_SETTING(flags,var,name,default,prefix,suffix,len) \ 104#define FILENAME_SETTING(flags,var,name,default,prefix,suffix,len) \
104 {flags|F_T_UCHARPTR, &global_settings.var,-1, \ 105 {flags|F_T_UCHARPTR, &global_settings.var,-1, \
105 CHARPTR(default),name,NULL, \ 106 CHARPTR(default),name,NULL, \
106 {.filename_setting= \ 107 {.filename_setting= \
107 (struct filename_setting[]){{prefix,suffix,len}}} } 108 (struct filename_setting[]){{prefix,suffix,len}}} }
108 109
109/* Used for settings which use the set_option() setting screen. 110/* Used for settings which use the set_option() setting screen.
@@ -111,18 +112,18 @@
111 These can either be literal strings, or ID2P(LANG_*) */ 112 These can either be literal strings, or ID2P(LANG_*) */
112#define CHOICE_SETTING(flags,var,lang_id,default,name,cfg_vals,cb,count,...) \ 113#define CHOICE_SETTING(flags,var,lang_id,default,name,cfg_vals,cb,count,...) \
113 {flags|F_CHOICE_SETTING|F_T_INT, &global_settings.var, lang_id, \ 114 {flags|F_CHOICE_SETTING|F_T_INT, &global_settings.var, lang_id, \
114 INT(default), name, cfg_vals, \ 115 INT(default), name, cfg_vals, \
115 {.choice_setting = (struct choice_setting[]){ \ 116 {.choice_setting = (struct choice_setting[]){ \
116 {cb, count, {.desc = (unsigned char*[]){__VA_ARGS__}}}}}} 117 {cb, count, {.desc = (const unsigned char*[]){__VA_ARGS__}}}}}}
117 118
118/* Similar to above, except the strings to display are taken from cfg_vals, 119/* Similar to above, except the strings to display are taken from cfg_vals,
119 the ... arg is a list of ID's to talk for the strings... can use TALK_ID()'s */ 120 the ... arg is a list of ID's to talk for the strings... can use TALK_ID()'s */
120#define STRINGCHOICE_SETTING(flags,var,lang_id,default,name,cfg_vals,cb,count,...) \ 121#define STRINGCHOICE_SETTING(flags,var,lang_id,default,name,cfg_vals,cb,count,...) \
121 {flags|F_CHOICE_SETTING|F_T_INT|F_CHOICETALKS, \ 122 {flags|F_CHOICE_SETTING|F_T_INT|F_CHOICETALKS, \
122 &global_settings.var, lang_id, \ 123 &global_settings.var, lang_id, \
123 INT(default), name, cfg_vals, \ 124 INT(default), name, cfg_vals, \
124 {.choice_setting = (struct choice_setting[]){ \ 125 {.choice_setting = (struct choice_setting[]){ \
125 {cb, count, {.talks = (int[]){__VA_ARGS__}}}}}} 126 {cb, count, {.talks = (const int[]){__VA_ARGS__}}}}}}
126 127
127/* for settings which use the set_int() setting screen. 128/* for settings which use the set_int() setting screen.
128 unit is the UNIT_ define to display/talk. 129 unit is the UNIT_ define to display/talk.
@@ -134,14 +135,20 @@
134 lang_id, INT(default), name, cfg_vals, \ 135 lang_id, INT(default), name, cfg_vals, \
135 {.int_setting = (struct int_setting[]){ \ 136 {.int_setting = (struct int_setting[]){ \
136 {cb, unit, min, max, step, formatter, get_talk_id}}}} 137 {cb, unit, min, max, step, formatter, get_talk_id}}}}
137#define INT_SETTING(flags, var, lang_id, default, name, \ 138#define INT_SETTING(flags, var, lang_id, default, name, \
138 unit, min, max, step, formatter, get_talk_id, cb) \ 139 unit, min, max, step, formatter, get_talk_id, cb) \
139 {flags|F_INT_SETTING|F_T_INT, &global_settings.var, \ 140 {flags|F_INT_SETTING|F_T_INT, &global_settings.var, \
140 lang_id, INT(default), name, NULL, \ 141 lang_id, INT(default), name, NULL, \
141 {.int_setting = (struct int_setting[]){ \ 142 {.int_setting = (struct int_setting[]){ \
142 {cb, unit, min, max, step, formatter, get_talk_id}}}} 143 {cb, unit, min, max, step, formatter, get_talk_id}}}}
143 144
144 145#define TABLE_SETTING(flags, var, lang_id, default, name, cfg_vals, \
146 unit, formatter, get_talk_id, cb, count, ...) \
147 {flags|F_TABLE_SETTING|F_T_INT, &global_settings.var, \
148 lang_id, INT(default), name, cfg_vals, \
149 {.table_setting = (struct table_setting[]) { \
150 {cb, formatter, get_talk_id, unit, count, \
151 (const int[]){__VA_ARGS__}}}}}
145 152
146/* some sets of values which are used more than once, to save memory */ 153/* some sets of values which are used more than once, to save memory */
147static const char off_on[] = "off,on"; 154static const char off_on[] = "off,on";
@@ -204,26 +211,24 @@ static void rectime_formatter(char *buffer, size_t buffer_size,
204#endif /* HAVE_RECORDING */ 211#endif /* HAVE_RECORDING */
205 212
206#ifdef HAVE_BACKLIGHT 213#ifdef HAVE_BACKLIGHT
207static const char backlight_times_conf [] = 214static void backlight_formatter(char *buffer, size_t buffer_size,
208 "off,on,1,2,3,4,5,6,7,8,9,10,15,20,25,30,45,60,90";
209static void backlight_formatter(char *buffer, size_t buffer_size,
210 int val, const char *unit) 215 int val, const char *unit)
211{ 216{
212 (void)unit; 217 (void)unit;
213 if (val == 0) 218 if (val == -1)
214 strcpy(buffer, str(LANG_OFF)); 219 strcpy(buffer, str(LANG_OFF));
215 else if (val == 1) 220 else if (val == 0)
216 strcpy(buffer, str(LANG_ON)); 221 strcpy(buffer, str(LANG_ON));
217 else 222 else
218 snprintf(buffer, buffer_size, "%d s", backlight_timeout_value[val]); 223 snprintf(buffer, buffer_size, "%d s", val);
219} 224}
220static int32_t backlight_getlang(int value) 225static int32_t backlight_getlang(int value)
221{ 226{
222 if (value == 0) 227 if (value == -1)
223 return LANG_OFF; 228 return LANG_OFF;
224 else if (value == 1) 229 else if (value == 0)
225 return LANG_ON; 230 return LANG_ON;
226 return TALK_ID(backlight_timeout_value[value], UNIT_SEC); 231 return TALK_ID(value, UNIT_SEC);
227} 232}
228#endif 233#endif
229/* ffwd/rewind and scan acceleration stuff */ 234/* ffwd/rewind and scan acceleration stuff */
@@ -424,16 +429,17 @@ const struct settings_list settings[] = {
424 MAX_CONTRAST_SETTING, 1, NULL, NULL}}}}, 429 MAX_CONTRAST_SETTING, 1, NULL, NULL}}}},
425#endif 430#endif
426#ifdef HAVE_BACKLIGHT 431#ifdef HAVE_BACKLIGHT
427 INT_SETTING_W_CFGVALS(0, backlight_timeout, LANG_BACKLIGHT, 6, 432 TABLE_SETTING(F_ALLOW_ARBITRARY_VALS, backlight_timeout, LANG_BACKLIGHT, 5,
428 "backlight timeout", backlight_times_conf, UNIT_SEC, 433 "backlight timeout", off_on, UNIT_SEC, backlight_formatter,
429 0, 18, 1, backlight_formatter, backlight_getlang, 434 backlight_getlang, backlight_set_timeout, 20,
430 backlight_set_timeout), 435 -1,0,1,2,3,4,5,6,7,8,9,10,15,20,25,30,45,60,90,120),
431#if CONFIG_CHARGING 436#if CONFIG_CHARGING
432 INT_SETTING_W_CFGVALS(0, backlight_timeout_plugged, 437 TABLE_SETTING(F_ALLOW_ARBITRARY_VALS, backlight_timeout_plugged,
433 LANG_BACKLIGHT_ON_WHEN_CHARGING, 11, 438 LANG_BACKLIGHT_ON_WHEN_CHARGING, 10,
434 "backlight timeout plugged", backlight_times_conf, UNIT_SEC, 439 "backlight timeout plugged", off_on, UNIT_SEC,
435 0, 18, 1, backlight_formatter, backlight_getlang, 440 backlight_formatter, backlight_getlang,
436 backlight_set_timeout_plugged), 441 backlight_set_timeout_plugged, 20,
442 -1,0,1,2,3,4,5,6,7,8,9,10,15,20,25,30,45,60,90,120),
437#endif 443#endif
438#endif /* HAVE_BACKLIGHT */ 444#endif /* HAVE_BACKLIGHT */
439#ifdef HAVE_LCD_BITMAP 445#ifdef HAVE_LCD_BITMAP
@@ -527,16 +533,17 @@ const struct settings_list settings[] = {
527 LANG_INVERT_LCD_INVERSE, LANG_NORMAL, lcd_remote_set_invert_display), 533 LANG_INVERT_LCD_INVERSE, LANG_NORMAL, lcd_remote_set_invert_display),
528 OFFON_SETTING(0,remote_flip_display, LANG_FLIP_DISPLAY, 534 OFFON_SETTING(0,remote_flip_display, LANG_FLIP_DISPLAY,
529 false,"remote flip display", NULL), 535 false,"remote flip display", NULL),
530 INT_SETTING_W_CFGVALS(0, remote_backlight_timeout, LANG_BACKLIGHT, 6, 536 TABLE_SETTING(F_ALLOW_ARBITRARY_VALS, remote_backlight_timeout,
531 "remote backlight timeout", backlight_times_conf, UNIT_SEC, 537 LANG_BACKLIGHT, 5, "remote backlight timeout", off_on,
532 0, 18, 1, backlight_formatter, backlight_getlang, 538 UNIT_SEC, backlight_formatter, backlight_getlang,
533 remote_backlight_set_timeout), 539 remote_backlight_set_timeout, 20,
540 -1,0,1,2,3,4,5,6,7,8,9,10,15,20,25,30,45,60,90,120),
534#if CONFIG_CHARGING 541#if CONFIG_CHARGING
535 INT_SETTING_W_CFGVALS(0, remote_backlight_timeout_plugged, 542 TABLE_SETTING(F_ALLOW_ARBITRARY_VALS, remote_backlight_timeout_plugged,
536 LANG_BACKLIGHT_ON_WHEN_CHARGING, 11, 543 LANG_BACKLIGHT, 10, "remote backlight timeout plugged",
537 "remote backlight timeout plugged", backlight_times_conf, UNIT_SEC, 544 off_on, UNIT_SEC, backlight_formatter, backlight_getlang,
538 0, 18, 1, backlight_formatter, backlight_getlang, 545 remote_backlight_set_timeout_plugged, 20,
539 remote_backlight_set_timeout_plugged), 546 -1,0,1,2,3,4,5,6,7,8,9,10,15,20,25,30,45,60,90,120),
540#endif 547#endif
541#ifdef HAVE_REMOTE_LCD_TICKING 548#ifdef HAVE_REMOTE_LCD_TICKING
542 OFFON_SETTING(0,remote_reduce_ticking, LANG_REDUCE_TICKING, 549 OFFON_SETTING(0,remote_reduce_ticking, LANG_REDUCE_TICKING,
@@ -1196,11 +1203,11 @@ const struct settings_list settings[] = {
1196 THEME_DIR "/", ".colours", MAX_FILENAME+1), 1203 THEME_DIR "/", ".colours", MAX_FILENAME+1),
1197#endif 1204#endif
1198#ifdef HAVE_BUTTON_LIGHT 1205#ifdef HAVE_BUTTON_LIGHT
1199 INT_SETTING_W_CFGVALS(0, buttonlight_timeout, 1206 TABLE_SETTING(F_ALLOW_ARBITRARY_VALS, buttonlight_timeout,
1200 LANG_BUTTONLIGHT_TIMEOUT, 6, 1207 LANG_BUTTONLIGHT_TIMEOUT, 5, "button light timeout", off_on,
1201 "button light timeout", backlight_times_conf, UNIT_SEC, 1208 UNIT_SEC, backlight_formatter, backlight_getlang,
1202 0, 18, 1, backlight_formatter, backlight_getlang, 1209 buttonlight_set_timeout, 20,
1203 buttonlight_set_timeout), 1210 -1,0,1,2,3,4,5,6,7,8,9,10,15,20,25,30,45,60,90,120),
1204#endif 1211#endif
1205#ifdef HAVE_BUTTONLIGHT_BRIGHTNESS 1212#ifdef HAVE_BUTTONLIGHT_BRIGHTNESS
1206 INT_SETTING(0, buttonlight_brightness, LANG_BUTTONLIGHT_BRIGHTNESS, DEFAULT_BRIGHTNESS_SETTING, 1213 INT_SETTING(0, buttonlight_brightness, LANG_BUTTONLIGHT_BRIGHTNESS, DEFAULT_BRIGHTNESS_SETTING,
diff --git a/apps/settings_list.h b/apps/settings_list.h
index 8aa7863e55..b738076607 100644
--- a/apps/settings_list.h
+++ b/apps/settings_list.h
@@ -78,13 +78,24 @@ struct choice_setting {
78 void (*option_callback)(int); 78 void (*option_callback)(int);
79 int count; 79 int count;
80 union { 80 union {
81 unsigned char **desc; 81 const unsigned char **desc;
82 int *talks; 82 const int *talks;
83 }; 83 };
84}; 84};
85#define F_CHOICE_SETTING 0x100 85#define F_CHOICE_SETTING 0x100
86#define F_CHOICETALKS 0x200 /* uses .talks in the above struct for the talks */ 86#define F_CHOICETALKS 0x200 /* uses .talks in the above struct for the talks */
87 /* and cfg_vals for the strings to display */ 87 /* and cfg_vals for the strings to display */
88
89struct table_setting {
90 void (*option_callback)(int);
91 void (*formatter)(char*, size_t, int, const char*);
92 long (*get_talk_id)(int);
93 int unit;
94 int count;
95 const int * values;
96};
97#define F_TABLE_SETTING 0x2000
98#define F_ALLOW_ARBITRARY_VALS 0x4000
88/* these use the _isfunc_type type for the function */ 99/* these use the _isfunc_type type for the function */
89/* typedef int (*_isfunc_type)(void); */ 100/* typedef int (*_isfunc_type)(void); */
90#define F_MIN_ISFUNC 0x100000 /* min(above) is function pointer to above type */ 101#define F_MIN_ISFUNC 0x100000 /* min(above) is function pointer to above type */
@@ -94,8 +105,8 @@ struct choice_setting {
94#define F_THEMESETTING 0x0800000 105#define F_THEMESETTING 0x0800000
95#define F_RECSETTING 0x1000000 106#define F_RECSETTING 0x1000000
96 107
97#define F_NVRAM_BYTES_MASK 0xE000 /*0-4 bytes can be stored */ 108#define F_NVRAM_BYTES_MASK 0xE0000 /*0-4 bytes can be stored */
98#define F_NVRAM_MASK_SHIFT 13 109#define F_NVRAM_MASK_SHIFT 17
99#define NVRAM_CONFIG_VERSION 4 110#define NVRAM_CONFIG_VERSION 4
100/* Above define should be bumped if 111/* Above define should be bumped if
101- a new NVRAM setting is added between 2 other NVRAM settings 112- a new NVRAM setting is added between 2 other NVRAM settings
@@ -107,7 +118,7 @@ struct choice_setting {
107#define F_NO_WRAP 0x1000 /* used if the list should not wrap */ 118#define F_NO_WRAP 0x1000 /* used if the list should not wrap */
108 119
109struct settings_list { 120struct settings_list {
110 uint32_t flags; /* ____ ___R TFFF ____ NNN_ PTVC IFRB STTT */ 121 uint32_t flags; /* ____ ___R TFFF NNN_ _ATW PTVC IFRB STTT */
111 void *setting; 122 void *setting;
112 int lang_id; /* -1 for none */ 123 int lang_id; /* -1 for none */
113 union storage_type default_val; 124 union storage_type default_val;
@@ -115,12 +126,13 @@ struct settings_list {
115 const char *cfg_vals; /*comma seperated legal values, or NULL */ 126 const char *cfg_vals; /*comma seperated legal values, or NULL */
116 /* used with F_T_UCHARPTR this is the folder prefix */ 127 /* used with F_T_UCHARPTR this is the folder prefix */
117 union { 128 union {
118 void *RESERVED; /* to stop compile errors, will be removed */ 129 const void *RESERVED; /* to stop compile errors, will be removed */
119 struct sound_setting *sound_setting; /* use F_T_SOUND for this */ 130 const struct sound_setting *sound_setting; /* use F_T_SOUND for this */
120 struct bool_setting *bool_setting; /* F_BOOL_SETTING */ 131 const struct bool_setting *bool_setting; /* F_BOOL_SETTING */
121 struct filename_setting *filename_setting; /* use F_FILENAME */ 132 const struct filename_setting *filename_setting; /* use F_FILENAME */
122 struct int_setting *int_setting; /* use F_INT_SETTING */ 133 const struct int_setting *int_setting; /* use F_INT_SETTING */
123 struct choice_setting *choice_setting; /* F_CHOICE_SETTING */ 134 const struct choice_setting *choice_setting; /* F_CHOICE_SETTING */
135 const struct table_setting *table_setting; /* F_TABLE_SETTING */
124 }; 136 };
125}; 137};
126 138
diff --git a/firmware/backlight.c b/firmware/backlight.c
index 78ba492942..f3bba5b8c7 100644
--- a/firmware/backlight.c
+++ b/firmware/backlight.c
@@ -89,11 +89,6 @@ static inline void _remote_backlight_off(void)
89 89
90#if defined(HAVE_BACKLIGHT) && !defined(BOOTLOADER) 90#if defined(HAVE_BACKLIGHT) && !defined(BOOTLOADER)
91 91
92const signed char backlight_timeout_value[19] =
93{
94 -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20, 25, 30, 45, 60, 90
95};
96
97enum { 92enum {
98 BACKLIGHT_ON, 93 BACKLIGHT_ON,
99 BACKLIGHT_OFF, 94 BACKLIGHT_OFF,
@@ -159,12 +154,9 @@ void buttonlight_off(void)
159 queue_post(&backlight_queue, BUTTON_LIGHT_OFF, 0); 154 queue_post(&backlight_queue, BUTTON_LIGHT_OFF, 0);
160} 155}
161 156
162void buttonlight_set_timeout(int index) 157void buttonlight_set_timeout(int value)
163{ 158{
164 if((unsigned)index >= sizeof(backlight_timeout_value)) 159 _buttonlight_timeout = HZ * value;
165 /* if given a weird value, use default */
166 index = 6;
167 _buttonlight_timeout = HZ * backlight_timeout_value[index];
168 buttonlight_update_state(); 160 buttonlight_update_state();
169} 161}
170 162
@@ -638,22 +630,16 @@ int backlight_get_current_timeout(void)
638 return backlight_timeout; 630 return backlight_timeout;
639} 631}
640 632
641void backlight_set_timeout(int index) 633void backlight_set_timeout(int value)
642{ 634{
643 if((unsigned)index >= sizeof(backlight_timeout_value)) 635 backlight_timeout_normal = HZ * value;
644 /* if given a weird value, use default */
645 index = 6;
646 backlight_timeout_normal = HZ * backlight_timeout_value[index];
647 backlight_update_state(); 636 backlight_update_state();
648} 637}
649 638
650#if CONFIG_CHARGING 639#if CONFIG_CHARGING
651void backlight_set_timeout_plugged(int index) 640void backlight_set_timeout_plugged(int value)
652{ 641{
653 if((unsigned)index >= sizeof(backlight_timeout_value)) 642 backlight_timeout_plugged = HZ * value;
654 /* if given a weird value, use default */
655 index = 6;
656 backlight_timeout_plugged = HZ * backlight_timeout_value[index];
657 backlight_update_state(); 643 backlight_update_state();
658} 644}
659#endif /* CONFIG_CHARGING */ 645#endif /* CONFIG_CHARGING */
@@ -710,22 +696,16 @@ void remote_backlight_off(void)
710 queue_post(&backlight_queue, REMOTE_BACKLIGHT_OFF, 0); 696 queue_post(&backlight_queue, REMOTE_BACKLIGHT_OFF, 0);
711} 697}
712 698
713void remote_backlight_set_timeout(int index) 699void remote_backlight_set_timeout(int value)
714{ 700{
715 if((unsigned)index >= sizeof(backlight_timeout_value)) 701 remote_backlight_timeout_normal = HZ * value;
716 /* if given a weird value, use default */
717 index=6;
718 remote_backlight_timeout_normal = HZ * backlight_timeout_value[index];
719 remote_backlight_update_state(); 702 remote_backlight_update_state();
720} 703}
721 704
722#if CONFIG_CHARGING 705#if CONFIG_CHARGING
723void remote_backlight_set_timeout_plugged(int index) 706void remote_backlight_set_timeout_plugged(int value)
724{ 707{
725 if((unsigned)index >= sizeof(backlight_timeout_value)) 708 remote_backlight_timeout_plugged = HZ * value;
726 /* if given a weird value, use default */
727 index=6;
728 remote_backlight_timeout_plugged = HZ * backlight_timeout_value[index];
729 remote_backlight_update_state(); 709 remote_backlight_update_state();
730} 710}
731#endif /* CONFIG_CHARGING */ 711#endif /* CONFIG_CHARGING */
@@ -805,12 +785,12 @@ void backlight_init(void)
805void backlight_on(void) {} 785void backlight_on(void) {}
806void backlight_off(void) {} 786void backlight_off(void) {}
807void buttonlight_on(void) {} 787void buttonlight_on(void) {}
808void backlight_set_timeout(int index) {(void)index;} 788void backlight_set_timeout(int value) {(void)value;}
809bool is_backlight_on(void) {return true;} 789bool is_backlight_on(void) {return true;}
810#ifdef HAVE_REMOTE_LCD 790#ifdef HAVE_REMOTE_LCD
811void remote_backlight_on(void) {} 791void remote_backlight_on(void) {}
812void remote_backlight_off(void) {} 792void remote_backlight_off(void) {}
813void remote_backlight_set_timeout(int index) {(void)index;} 793void remote_backlight_set_timeout(int value) {(void)value;}
814bool is_remote_backlight_on(void) {return true;} 794bool is_remote_backlight_on(void) {return true;}
815#endif /* HAVE_REMOTE_LCD */ 795#endif /* HAVE_REMOTE_LCD */
816#ifdef HAVE_BACKLIGHT_BRIGHTNESS 796#ifdef HAVE_BACKLIGHT_BRIGHTNESS
diff --git a/firmware/export/backlight.h b/firmware/export/backlight.h
index 47fee7d59e..058f7960f9 100644
--- a/firmware/export/backlight.h
+++ b/firmware/export/backlight.h
@@ -24,7 +24,7 @@
24bool is_backlight_on(void); 24bool is_backlight_on(void);
25void backlight_on(void); 25void backlight_on(void);
26void backlight_off(void); 26void backlight_off(void);
27void backlight_set_timeout(int index); 27void backlight_set_timeout(int value);
28 28
29#ifdef HAVE_BACKLIGHT 29#ifdef HAVE_BACKLIGHT
30void backlight_init(void); 30void backlight_init(void);
@@ -36,8 +36,7 @@ void backlight_set_fade_in(int index);
36void backlight_set_fade_out(int index); 36void backlight_set_fade_out(int index);
37#endif 37#endif
38 38
39void backlight_set_timeout_plugged(int index); 39void backlight_set_timeout_plugged(int value);
40extern const signed char backlight_timeout_value[];
41 40
42#ifdef HAS_BUTTON_HOLD 41#ifdef HAS_BUTTON_HOLD
43void backlight_hold_changed(bool hold_button); 42void backlight_hold_changed(bool hold_button);
@@ -56,8 +55,8 @@ extern const signed char lcd_sleep_timeout_value[];
56#ifdef HAVE_REMOTE_LCD 55#ifdef HAVE_REMOTE_LCD
57void remote_backlight_on(void); 56void remote_backlight_on(void);
58void remote_backlight_off(void); 57void remote_backlight_off(void);
59void remote_backlight_set_timeout(int index); 58void remote_backlight_set_timeout(int value);
60void remote_backlight_set_timeout_plugged(int index); 59void remote_backlight_set_timeout_plugged(int value);
61bool is_remote_backlight_on(void); 60bool is_remote_backlight_on(void);
62 61
63#ifdef HAS_REMOTE_BUTTON_HOLD 62#ifdef HAS_REMOTE_BUTTON_HOLD
@@ -82,7 +81,7 @@ void buttonlight_set_brightness(int val);
82#ifdef HAVE_BUTTON_LIGHT 81#ifdef HAVE_BUTTON_LIGHT
83void buttonlight_on(void); 82void buttonlight_on(void);
84void buttonlight_off(void); 83void buttonlight_off(void);
85void buttonlight_set_timeout(int index); 84void buttonlight_set_timeout(int value);
86#endif 85#endif
87 86
88/* Private API for use in target tree backlight code only */ 87/* Private API for use in target tree backlight code only */