Be a bit more accurate in the manual: use better options to include or exclude parts...
[kugel-rb.git] / apps / settings.c
blob8834c9d9bf9750fed5da6bf43784ad953e89fd68
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2002 by Stuart Martin
11 * RTC config saving code (C) 2002 by hessu@hes.iki.fi
13 * All files in this archive are subject to the GNU General Public License.
14 * See the file COPYING in the source tree root for full license agreement.
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
19 ****************************************************************************/
20 #include <stdio.h>
21 #include <stddef.h>
22 #include <stdlib.h>
23 #include <limits.h>
24 #include "inttypes.h"
25 #include "config.h"
26 #include "action.h"
27 #include "crc32.h"
28 #include "settings.h"
29 #include "debug.h"
30 #include "usb.h"
31 #include "backlight.h"
32 #include "audio.h"
33 #include "mpeg.h"
34 #include "talk.h"
35 #include "string.h"
36 #include "rtc.h"
37 #include "power.h"
38 #include "ata_idle_notify.h"
39 #include "screens.h"
40 #include "ctype.h"
41 #include "file.h"
42 #include "system.h"
43 #include "misc.h"
44 #ifdef HAVE_LCD_BITMAP
45 #include "icons.h"
46 #include "font.h"
47 #include "peakmeter.h"
48 #endif
49 #include "lang.h"
50 #include "language.h"
51 #include "gwps.h"
52 #include "powermgmt.h"
53 #include "sprintf.h"
54 #include "keyboard.h"
55 #include "version.h"
56 #include "sound.h"
57 #include "rbunicode.h"
58 #include "dircache.h"
59 #include "statusbar.h"
60 #include "splash.h"
61 #include "list.h"
62 #include "settings_list.h"
63 #include "filetypes.h"
64 #include "option_select.h"
65 #include "backdrop.h"
67 #if CONFIG_TUNER
68 #include "radio.h"
69 #endif
71 #if CONFIG_CODEC == MAS3507D
72 void dac_line_in(bool enable);
73 #endif
74 struct user_settings global_settings;
75 struct system_status global_status;
77 #if CONFIG_CODEC == SWCODEC
78 #include "dsp.h"
79 #include "playback.h"
80 #ifdef HAVE_RECORDING
81 #include "enc_config.h"
82 #endif
83 #endif /* CONFIG_CODEC == SWCODEC */
85 #define NVRAM_BLOCK_SIZE 44
87 #ifdef HAVE_LCD_BITMAP
88 #define MAX_LINES 10
89 #else
90 #define MAX_LINES 2
91 #endif
93 #ifdef HAVE_REMOTE_LCD
94 #include "lcd-remote.h"
95 #endif
97 long lasttime = 0;
99 /** NVRAM stuff, if the target doesnt have NVRAM it is saved in ROCKBOX_DIR /nvram.bin **/
100 /* NVRAM is set out as
101 [0] 'R'
102 [1] 'b'
103 [2] version
104 [3] stored variable count
105 [4-7] crc32 checksum
106 [8-NVRAM_BLOCK_SIZE] data
108 #define NVRAM_DATA_START 8
109 #define NVRAM_FILE ROCKBOX_DIR "/nvram.bin"
110 static char nvram_buffer[NVRAM_BLOCK_SIZE];
112 static bool read_nvram_data(char* buf, int max_len)
114 unsigned crc32 = 0xffffffff;
115 int var_count = 0, i = 0, buf_pos = 0;
116 #ifndef HAVE_RTC_RAM
117 int fd = open(NVRAM_FILE,O_RDONLY);
118 if (fd < 0)
119 return false;
120 memset(buf,0,max_len);
121 if (read(fd,buf,max_len) < 8) /* min is 8 bytes,magic, ver, vars, crc32 */
122 return false;
123 close(fd);
124 #else
125 memset(buf,0,max_len);
126 /* read rtc block */
127 for (i=0; i < max_len; i++ )
128 buf[i] = rtc_read(0x14+i);
129 #endif
130 /* check magic, version */
131 if ((buf[0] != 'R') || (buf[1] != 'b')
132 || (buf[2] != NVRAM_CONFIG_VERSION))
133 return false;
134 /* check crc32 */
135 crc32 = crc_32(&buf[NVRAM_DATA_START],
136 max_len-NVRAM_DATA_START-1,0xffffffff);
137 if (memcmp(&crc32,&buf[4],4))
138 return false;
139 /* all good, so read in the settings */
140 var_count = buf[3];
141 buf_pos = NVRAM_DATA_START;
142 for(i=0; i<nb_settings; i++)
144 int nvram_bytes = (settings[i].flags&F_NVRAM_BYTES_MASK)
145 >>F_NVRAM_MASK_SHIFT;
146 if (nvram_bytes)
148 if ((var_count>0) && (buf_pos<max_len))
150 memcpy(settings[i].setting,&buf[buf_pos],nvram_bytes);
151 buf_pos += nvram_bytes;
152 var_count--;
154 else /* should only happen when new items are added to the end */
156 memcpy(settings[i].setting, &settings[i].default_val, nvram_bytes);
160 return true;
162 static bool write_nvram_data(char* buf, int max_len)
164 unsigned crc32 = 0xffffffff;
165 int i = 0, buf_pos = 0;
166 char var_count = 0;
167 #ifndef HAVE_RTC_RAM
168 int fd;
169 #endif
170 memset(buf,0,max_len);
171 /* magic, version */
172 buf[0] = 'R'; buf[1] = 'b';
173 buf[2] = NVRAM_CONFIG_VERSION;
174 buf_pos = NVRAM_DATA_START;
175 for(i=0; (i<nb_settings) && (buf_pos<max_len); i++)
177 int nvram_bytes = (settings[i].flags&F_NVRAM_BYTES_MASK)
178 >>F_NVRAM_MASK_SHIFT;
179 if (nvram_bytes)
181 memcpy(&buf[buf_pos],settings[i].setting,nvram_bytes);
182 buf_pos += nvram_bytes;
183 var_count++;
186 /* count and crc32 */
187 buf[3] = var_count;
188 crc32 = crc_32(&buf[NVRAM_DATA_START],
189 max_len-NVRAM_DATA_START-1,0xffffffff);
190 memcpy(&buf[4],&crc32,4);
191 #ifndef HAVE_RTC_RAM
192 fd = open(NVRAM_FILE,O_CREAT|O_TRUNC|O_WRONLY);
193 if (fd >= 0)
195 int len = write(fd,buf,max_len);
196 close(fd);
197 if (len < 8)
198 return false;
200 #else
201 /* FIXME: okay, it _would_ be cleaner and faster to implement rtc_write so
202 that it would write a number of bytes at a time since the RTC chip
203 supports that, but this will have to do for now 8-) */
204 for (i=0; i < NVRAM_BLOCK_SIZE; i++ ) {
205 int r = rtc_write(0x14+i, buf[i]);
206 if (r)
207 return false;
209 #endif
210 return true;
213 /** Reading from a config file **/
215 * load settings from disk or RTC RAM
217 void settings_load(int which)
219 if (which&SETTINGS_RTC)
220 read_nvram_data(nvram_buffer,NVRAM_BLOCK_SIZE);
221 if (which&SETTINGS_HD)
223 settings_load_config(CONFIGFILE,false);
224 settings_load_config(FIXEDSETTINGSFILE,false);
228 static bool cfg_string_to_int(int setting_id, int* out, const char* str)
230 const char* start = settings[setting_id].cfg_vals;
231 char* end = NULL;
232 char temp[MAX_PATH];
233 int count = 0;
234 while (1)
236 end = strchr(start, ',');
237 if (!end)
239 if (!strcmp(str, start))
241 *out = count;
242 return true;
244 else return false;
246 strncpy(temp, start, end-start);
247 temp[end-start] = '\0';
248 if (!strcmp(str, temp))
250 *out = count;
251 return true;
253 start = end +1;
254 count++;
256 return false;
259 bool settings_load_config(const char* file, bool apply)
261 int fd;
262 char line[128];
263 char* name;
264 char* value;
265 int i;
266 fd = open(file, O_RDONLY);
267 if (fd < 0)
268 return false;
270 while (read_line(fd, line, sizeof line) > 0)
272 if (!settings_parseline(line, &name, &value))
273 continue;
274 for(i=0; i<nb_settings; i++)
276 if (settings[i].cfg_name == NULL)
277 continue;
278 if (!strcasecmp(name,settings[i].cfg_name))
280 switch (settings[i].flags&F_T_MASK)
282 case F_T_INT:
283 case F_T_UINT:
284 #ifdef HAVE_LCD_COLOR
285 if (settings[i].flags&F_RGB)
286 hex_to_rgb(value, (int*)settings[i].setting);
287 else
288 #endif
289 if (settings[i].cfg_vals == NULL)
291 *(int*)settings[i].setting = atoi(value);
293 else
295 int temp, *v = (int*)settings[i].setting;
296 bool found = cfg_string_to_int(i, &temp, value);
297 if (found)
299 if (settings[i].flags&F_TABLE_SETTING)
300 *v = settings[i].table_setting->values[temp];
301 else
302 *v = temp;
304 else
305 *v = atoi(value);
307 break;
308 case F_T_BOOL:
310 int temp;
311 if (cfg_string_to_int(i,&temp,value))
312 *(bool*)settings[i].setting = (temp==0?false:true);
313 break;
315 case F_T_CHARPTR:
316 case F_T_UCHARPTR:
318 char storage[MAX_PATH];
319 if (settings[i].filename_setting->prefix)
321 int len = strlen(settings[i].filename_setting->prefix);
322 if (!strncasecmp(value,
323 settings[i].filename_setting->prefix,
324 len))
326 strncpy(storage,&value[len],MAX_PATH);
328 else strncpy(storage,value,MAX_PATH);
330 else strncpy(storage,value,MAX_PATH);
331 if (settings[i].filename_setting->suffix)
333 char *s = strcasestr(storage,settings[i].filename_setting->suffix);
334 if (s) *s = '\0';
336 strncpy((char*)settings[i].setting,storage,
337 settings[i].filename_setting->max_len);
338 ((char*)settings[i].setting)
339 [settings[i].filename_setting->max_len-1] = '\0';
340 break;
343 break;
344 } /* if (!strcmp(name,settings[i].cfg_name)) */
345 } /* for(...) */
346 } /* while(...) */
348 close(fd);
349 settings_save();
350 if (apply)
351 settings_apply(true);
352 return true;
355 /** Writing to a config file and saving settings **/
357 bool cfg_int_to_string(int setting_id, int val, char* buf, int buf_len)
359 int flags = settings[setting_id].flags;
360 const char* start = settings[setting_id].cfg_vals;
361 char* end = NULL;
362 int count = 0;
364 if ((flags&F_T_MASK)==F_T_INT &&
365 flags&F_TABLE_SETTING)
367 const int *value = settings[setting_id].table_setting->values;
368 while (start)
370 end = strchr(start,',');
371 if (value[count] == val)
373 if (end == NULL)
374 strncpy(buf, start, buf_len);
375 else
377 int len = (buf_len > (end-start))? end-start: buf_len;
378 strncpy(buf, start, len);
379 buf[len] = '\0';
381 return true;
383 count++;
385 if (end)
386 start = end+1;
387 else
388 break;
390 return false;
393 while (count < val)
395 start = strchr(start,',');
396 if (!start)
397 return false;
398 count++;
399 start++;
401 end = strchr(start,',');
402 if (end == NULL)
403 strncpy(buf, start, buf_len);
404 else
406 int len = (buf_len > (end-start))? end-start: buf_len;
407 strncpy(buf, start, len);
408 buf[len] = '\0';
410 return true;
414 static bool is_changed(int setting_id)
416 const struct settings_list *setting = &settings[setting_id];
417 switch (setting->flags&F_T_MASK)
419 case F_T_INT:
420 case F_T_UINT:
421 if (setting->flags&F_DEF_ISFUNC)
423 if (*(int*)setting->setting == setting->default_val.func())
424 return false;
426 else if (setting->flags&F_T_SOUND)
428 if (*(int*)setting->setting ==
429 sound_default(setting->sound_setting->setting))
430 return false;
432 else if (*(int*)setting->setting == setting->default_val.int_)
433 return false;
434 break;
435 case F_T_BOOL:
436 if (*(bool*)setting->setting == setting->default_val.bool_)
437 return false;
438 break;
439 case F_T_CHARPTR:
440 case F_T_UCHARPTR:
441 if (!strcmp((char*)setting->setting, setting->default_val.charptr))
442 return false;
443 break;
445 return true;
448 static bool settings_write_config(const char* filename, int options)
450 int i;
451 int fd;
452 char value[MAX_PATH];
453 fd = open(filename,O_CREAT|O_TRUNC|O_WRONLY);
454 if (fd < 0)
455 return false;
456 #if CONFIG_TUNER
457 bool statusbar = global_settings.statusbar;
458 if (global_status.statusbar_forced != 0 && statusbar)
459 global_settings.statusbar = false;
460 #endif
461 fdprintf(fd, "# .cfg file created by rockbox %s - "
462 "http://www.rockbox.org\r\n\r\n", appsversion);
463 for(i=0; i<nb_settings; i++)
465 if (settings[i].cfg_name == NULL)
466 continue;
467 value[0] = '\0';
469 switch (options)
471 case SETTINGS_SAVE_CHANGED:
472 if (!is_changed(i))
473 continue;
474 break;
475 case SETTINGS_SAVE_SOUND:
476 if ((settings[i].flags&F_SOUNDSETTING) == 0)
477 continue;
478 break;
479 case SETTINGS_SAVE_THEME:
480 if ((settings[i].flags&F_THEMESETTING) == 0)
481 continue;
482 break;
483 #ifdef HAVE_RECORDING
484 case SETTINGS_SAVE_RECPRESETS:
485 if ((settings[i].flags&F_RECSETTING) == 0)
486 continue;
487 break;
488 #endif
489 #if CONFIG_CODEC == SWCODEC
490 case SETTINGS_SAVE_EQPRESET:
491 if ((settings[i].flags&F_EQSETTING) == 0)
492 continue;
493 break;
494 #endif
496 switch (settings[i].flags&F_T_MASK)
498 case F_T_INT:
499 case F_T_UINT:
500 #ifdef HAVE_LCD_COLOR
501 if (settings[i].flags&F_RGB)
503 int colour = *(int*)settings[i].setting;
504 snprintf(value,MAX_PATH,"%02x%02x%02x",
505 (int)RGB_UNPACK_RED(colour),
506 (int)RGB_UNPACK_GREEN(colour),
507 (int)RGB_UNPACK_BLUE(colour));
509 else
510 #endif
511 if (settings[i].cfg_vals == NULL)
513 snprintf(value,MAX_PATH,"%d",*(int*)settings[i].setting);
515 else
517 if (cfg_int_to_string(i, *(int*)settings[i].setting,
518 value, MAX_PATH) == false)
520 snprintf(value,MAX_PATH,"%d",*(int*)settings[i].setting);
523 break;
524 case F_T_BOOL:
525 cfg_int_to_string(i,
526 *(bool*)settings[i].setting==false?0:1, value, MAX_PATH);
527 break;
528 case F_T_CHARPTR:
529 case F_T_UCHARPTR:
530 if (((char*)settings[i].setting)[0]
531 && settings[i].filename_setting->prefix)
533 snprintf(value,MAX_PATH,"%s%s%s",
534 settings[i].filename_setting->prefix,
535 (char*)settings[i].setting,
536 settings[i].filename_setting->suffix);
538 else strncpy(value,(char*)settings[i].setting,
539 settings[i].filename_setting->max_len);
540 break;
541 } /* switch () */
542 fdprintf(fd,"%s: %s\r\n",settings[i].cfg_name,value);
543 } /* for(...) */
544 close(fd);
545 #if CONFIG_TUNER
546 global_settings.statusbar = statusbar;
547 #endif
548 return true;
550 #ifndef HAVE_RTC_RAM
551 static bool flush_global_status_callback(void)
553 return write_nvram_data(nvram_buffer,NVRAM_BLOCK_SIZE);
555 #endif
556 static bool flush_config_block_callback(void)
558 bool r1, r2;
559 r1 = write_nvram_data(nvram_buffer,NVRAM_BLOCK_SIZE);
560 r2 = settings_write_config(CONFIGFILE, SETTINGS_SAVE_CHANGED);
561 return r1 || r2;
565 * persist all runtime user settings to disk or RTC RAM
567 static void update_runtime(void)
569 int elapsed_secs;
571 elapsed_secs = (current_tick - lasttime) / HZ;
572 global_status.runtime += elapsed_secs;
573 lasttime += (elapsed_secs * HZ);
575 if ( global_status.runtime > global_status.topruntime )
576 global_status.topruntime = global_status.runtime;
579 void status_save(void)
581 update_runtime();
582 #ifdef HAVE_RTC_RAM
583 /* this will be done in the ata_callback if
584 target doesnt have rtc ram */
585 write_nvram_data(nvram_buffer,NVRAM_BLOCK_SIZE);
586 #else
587 register_ata_idle_func(flush_global_status_callback);
588 #endif
591 int settings_save(void)
593 update_runtime();
594 #ifdef HAVE_RTC_RAM
595 /* this will be done in the ata_callback if
596 target doesnt have rtc ram */
597 write_nvram_data(nvram_buffer,NVRAM_BLOCK_SIZE);
598 #endif
599 register_ata_idle_func(flush_config_block_callback);
600 return 0;
603 bool settings_save_config(int options)
605 char filename[MAX_PATH];
606 char *folder;
607 switch (options)
609 case SETTINGS_SAVE_THEME:
610 folder = THEME_DIR;
611 break;
612 #ifdef HAVE_RECORDING
613 case SETTINGS_SAVE_RECPRESETS:
614 folder = RECPRESETS_DIR;
615 break;
616 #endif
617 #if CONFIG_CODEC == SWCODEC
618 case SETTINGS_SAVE_EQPRESET:
619 folder = EQS_DIR;
620 break;
621 #endif
622 case SETTINGS_SAVE_SOUND:
623 default:
624 folder = ROCKBOX_DIR;
626 create_numbered_filename(filename, folder, "config", ".cfg", 2
627 IF_CNFN_NUM_(, NULL));
629 /* allow user to modify filename */
630 while (true) {
631 if (!kbd_input(filename, sizeof filename)) {
632 break;
634 else {
635 gui_syncsplash(HZ, ID2P(LANG_CANCEL));
636 return false;
640 if (settings_write_config(filename, options))
641 gui_syncsplash(HZ, ID2P(LANG_SETTINGS_SAVED));
642 else
643 gui_syncsplash(HZ, ID2P(LANG_FAILED));
644 return true;
647 /** Apply and Reset settings **/
650 #ifdef HAVE_LCD_BITMAP
652 * Applies the range infos stored in global_settings to
653 * the peak meter.
655 void settings_apply_pm_range(void)
657 int pm_min, pm_max;
659 /* depending on the scale mode (dBfs or percent) the values
660 of global_settings.peak_meter_dbfs have different meanings */
661 if (global_settings.peak_meter_dbfs)
663 /* convert to dBfs * 100 */
664 pm_min = -(((int)global_settings.peak_meter_min) * 100);
665 pm_max = -(((int)global_settings.peak_meter_max) * 100);
667 else
669 /* percent is stored directly -> no conversion */
670 pm_min = global_settings.peak_meter_min;
671 pm_max = global_settings.peak_meter_max;
674 /* apply the range */
675 peak_meter_init_range(global_settings.peak_meter_dbfs, pm_min, pm_max);
677 #endif /* HAVE_LCD_BITMAP */
679 void sound_settings_apply(void)
681 #if CONFIG_CODEC == SWCODEC
682 sound_set_dsp_callback(dsp_callback);
683 #endif
684 sound_set(SOUND_BASS, global_settings.bass);
685 sound_set(SOUND_TREBLE, global_settings.treble);
686 sound_set(SOUND_BALANCE, global_settings.balance);
687 sound_set(SOUND_VOLUME, global_settings.volume);
688 sound_set(SOUND_CHANNELS, global_settings.channel_config);
689 sound_set(SOUND_STEREO_WIDTH, global_settings.stereo_width);
690 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
691 sound_set(SOUND_LOUDNESS, global_settings.loudness);
692 sound_set(SOUND_AVC, global_settings.avc);
693 sound_set(SOUND_MDB_STRENGTH, global_settings.mdb_strength);
694 sound_set(SOUND_MDB_HARMONICS, global_settings.mdb_harmonics);
695 sound_set(SOUND_MDB_CENTER, global_settings.mdb_center);
696 sound_set(SOUND_MDB_SHAPE, global_settings.mdb_shape);
697 sound_set(SOUND_MDB_ENABLE, global_settings.mdb_enable);
698 sound_set(SOUND_SUPERBASS, global_settings.superbass);
699 #endif
701 #ifdef HAVE_WM8758
702 sound_set(SOUND_BASS_CUTOFF, global_settings.bass_cutoff);
703 sound_set(SOUND_TREBLE_CUTOFF, global_settings.treble_cutoff);
704 #endif
706 #ifdef HAVE_USB_POWER
707 #if CONFIG_CHARGING
708 usb_charging_enable(global_settings.usb_charging);
709 #endif
710 #endif
713 void settings_apply(bool read_disk)
715 char buf[64];
716 #if CONFIG_CODEC == SWCODEC
717 int i;
718 #endif
720 sound_settings_apply();
722 #ifndef HAVE_FLASH_STORAGE
723 audio_set_buffer_margin(global_settings.buffer_margin);
724 #endif
726 #ifdef HAVE_LCD_CONTRAST
727 lcd_set_contrast(global_settings.contrast);
728 #endif
729 lcd_scroll_speed(global_settings.scroll_speed);
730 #ifdef HAVE_REMOTE_LCD
731 lcd_remote_set_contrast(global_settings.remote_contrast);
732 lcd_remote_set_invert_display(global_settings.remote_invert);
733 lcd_remote_set_flip(global_settings.remote_flip_display);
734 lcd_remote_scroll_speed(global_settings.remote_scroll_speed);
735 lcd_remote_scroll_step(global_settings.remote_scroll_step);
736 lcd_remote_scroll_delay(global_settings.remote_scroll_delay);
737 lcd_remote_bidir_scroll(global_settings.remote_bidir_limit);
738 #ifdef HAVE_REMOTE_LCD_TICKING
739 lcd_remote_emireduce(global_settings.remote_reduce_ticking);
740 #endif
741 remote_backlight_set_timeout(global_settings.remote_backlight_timeout);
742 #if CONFIG_CHARGING
743 remote_backlight_set_timeout_plugged(global_settings.remote_backlight_timeout_plugged);
744 #endif
745 #ifdef HAS_REMOTE_BUTTON_HOLD
746 remote_backlight_set_on_button_hold(global_settings.remote_backlight_on_button_hold);
747 #endif
748 #endif /* HAVE_REMOTE_LCD */
749 #ifdef HAVE_BACKLIGHT_BRIGHTNESS
750 backlight_set_brightness(global_settings.brightness);
751 #endif
752 #ifdef HAVE_BACKLIGHT
753 backlight_set_timeout(global_settings.backlight_timeout);
754 #if CONFIG_CHARGING
755 backlight_set_timeout_plugged(global_settings.backlight_timeout_plugged);
756 #endif
757 #if defined(HAVE_BACKLIGHT_PWM_FADING) && !defined(SIMULATOR)
758 backlight_set_fade_in(global_settings.backlight_fade_in);
759 backlight_set_fade_out(global_settings.backlight_fade_out);
760 #endif
761 #endif
762 #ifdef HAVE_BUTTONLIGHT_BRIGHTNESS
763 buttonlight_set_brightness(global_settings.buttonlight_brightness);
764 #endif
765 #ifdef HAVE_BUTTON_LIGHT
766 buttonlight_set_timeout(global_settings.buttonlight_timeout);
767 #endif
768 #ifndef HAVE_FLASH_STORAGE
769 ata_spindown(global_settings.disk_spindown);
770 #endif
771 #if (CONFIG_CODEC == MAS3507D) && !defined(SIMULATOR)
772 dac_line_in(global_settings.line_in);
773 #endif
774 set_poweroff_timeout(global_settings.poweroff);
776 set_battery_capacity(global_settings.battery_capacity);
777 #if BATTERY_TYPES_COUNT > 1
778 set_battery_type(global_settings.battery_type);
779 #endif
781 #ifdef HAVE_LCD_BITMAP
782 lcd_set_invert_display(global_settings.invert);
783 lcd_set_flip(global_settings.flip_display);
784 button_set_flip(global_settings.flip_display);
785 lcd_update(); /* refresh after flipping the screen */
786 settings_apply_pm_range();
787 peak_meter_init_times(
788 global_settings.peak_meter_release, global_settings.peak_meter_hold,
789 global_settings.peak_meter_clip_hold);
790 #endif
792 if (read_disk)
795 #ifdef HAVE_LCD_BITMAP
796 /* fonts need to be loaded before the WPS */
797 if ( global_settings.font_file[0]) {
798 snprintf(buf, sizeof buf, FONT_DIR "/%s.fnt",
799 global_settings.font_file);
800 font_load(buf);
802 else
803 font_reset();
805 if ( global_settings.kbd_file[0]) {
806 snprintf(buf, sizeof buf, ROCKBOX_DIR "/%s.kbd",
807 global_settings.kbd_file);
808 load_kbd(buf);
810 else
811 load_kbd(NULL);
812 #endif
813 #if LCD_DEPTH > 1
814 unload_wps_backdrop();
815 #endif
816 #if defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1
817 unload_remote_wps_backdrop();
818 #endif
819 if ( global_settings.wps_file[0] &&
820 global_settings.wps_file[0] != 0xff ) {
821 snprintf(buf, sizeof buf, WPS_DIR "/%s.wps",
822 global_settings.wps_file);
823 wps_data_load(gui_wps[0].data, &screens[0], buf, true);
825 else
827 wps_data_init(gui_wps[0].data);
828 #ifdef HAVE_REMOTE_LCD
829 gui_wps[0].data->remote_wps = false;
830 #endif
833 #if LCD_DEPTH > 1
834 if ( global_settings.backdrop_file[0] &&
835 global_settings.backdrop_file[0] != 0xff ) {
836 snprintf(buf, sizeof buf, BACKDROP_DIR "/%s.bmp",
837 global_settings.backdrop_file);
838 load_main_backdrop(buf);
839 } else {
840 unload_main_backdrop();
842 show_main_backdrop();
843 #endif
844 #if defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1
845 show_remote_main_backdrop();
846 #endif
848 #if defined(HAVE_REMOTE_LCD) && (NB_SCREENS > 1)
849 if ( global_settings.rwps_file[0]) {
850 snprintf(buf, sizeof buf, WPS_DIR "/%s.rwps",
851 global_settings.rwps_file);
852 wps_data_load(gui_wps[1].data, &screens[1], buf, true);
854 else
856 wps_data_init(gui_wps[1].data);
857 gui_wps[1].data->remote_wps = true;
859 #endif
860 if ( global_settings.lang_file[0]) {
861 snprintf(buf, sizeof buf, LANG_DIR "/%s.lng",
862 global_settings.lang_file);
863 lang_load(buf);
864 talk_init(); /* use voice of same language */
866 /* load the icon set */
867 icons_init();
869 #ifdef HAVE_LCD_COLOR
870 if (global_settings.colors_file[0])
871 read_color_theme_file();
872 #endif
875 #ifdef HAVE_LCD_COLOR
876 screens[SCREEN_MAIN].set_foreground(global_settings.fg_color);
877 screens[SCREEN_MAIN].set_background(global_settings.bg_color);
878 screens[SCREEN_MAIN].set_selector_start(global_settings.lss_color);
879 screens[SCREEN_MAIN].set_selector_end(global_settings.lse_color);
880 screens[SCREEN_MAIN].set_selector_text(global_settings.lst_color);
881 #endif
883 #ifdef HAVE_LCD_BITMAP
884 lcd_scroll_step(global_settings.scroll_step);
885 gui_list_screen_scroll_step(global_settings.screen_scroll_step);
886 gui_list_screen_scroll_out_of_view(global_settings.offset_out_of_view);
887 #else
888 lcd_jump_scroll(global_settings.jump_scroll);
889 lcd_jump_scroll_delay(global_settings.jump_scroll_delay);
890 #endif
891 lcd_bidir_scroll(global_settings.bidir_limit);
892 lcd_scroll_delay(global_settings.scroll_delay);
895 set_codepage(global_settings.default_codepage);
897 #if CONFIG_CODEC == SWCODEC
898 audio_set_crossfade(global_settings.crossfade);
899 dsp_set_replaygain();
900 dsp_set_crossfeed(global_settings.crossfeed);
901 dsp_set_crossfeed_direct_gain(global_settings.crossfeed_direct_gain);
902 dsp_set_crossfeed_cross_params(global_settings.crossfeed_cross_gain,
903 global_settings.crossfeed_hf_attenuation,
904 global_settings.crossfeed_hf_cutoff);
906 /* Configure software equalizer, hardware eq is handled in audio_init() */
907 dsp_set_eq(global_settings.eq_enabled);
908 dsp_set_eq_precut(global_settings.eq_precut);
909 for(i = 0; i < 5; i++) {
910 dsp_set_eq_coefs(i);
913 dsp_dither_enable(global_settings.dithering_enabled);
914 #endif
916 #ifdef HAVE_SPDIF_POWER
917 spdif_power_enable(global_settings.spdif_enable);
918 #endif
920 #ifdef HAVE_BACKLIGHT
921 set_backlight_filter_keypress(global_settings.bl_filter_first_keypress);
922 #ifdef HAVE_REMOTE_LCD
923 set_remote_backlight_filter_keypress(global_settings.remote_bl_filter_first_keypress);
924 #endif
925 #ifdef HAS_BUTTON_HOLD
926 backlight_set_on_button_hold(global_settings.backlight_on_button_hold);
927 #endif
928 #ifdef HAVE_LCD_SLEEP_SETTING
929 lcd_set_sleep_after_backlight_off(global_settings.lcd_sleep_after_backlight_off);
930 #endif
931 #endif /* HAVE_BACKLIGHT */
933 #ifdef HAVE_TOUCHPAD_SENSITIVITY_SETTING
934 touchpad_set_sensitivity(global_settings.touchpad_sensitivity);
935 #endif
937 /* This should stay last */
938 #if defined(HAVE_RECORDING) && CONFIG_CODEC == SWCODEC
939 enc_global_settings_apply();
940 #endif
941 list_init_viewports(NULL);
946 * reset all settings to their default value
948 void reset_setting(const struct settings_list *setting, void *var)
950 switch (setting->flags&F_T_MASK)
952 case F_T_INT:
953 case F_T_UINT:
954 if (setting->flags&F_DEF_ISFUNC)
955 *(int*)var = setting->default_val.func();
956 else if (setting->flags&F_T_SOUND)
957 *(int*)var = sound_default(setting->sound_setting->setting);
958 else *(int*)var = setting->default_val.int_;
959 break;
960 case F_T_BOOL:
961 *(bool*)var = setting->default_val.bool_;
962 break;
963 case F_T_CHARPTR:
964 case F_T_UCHARPTR:
965 strncpy((char*)var, setting->default_val.charptr,
966 setting->filename_setting->max_len);
967 break;
971 void settings_reset(void)
973 int i;
975 for(i=0; i<nb_settings; i++)
976 reset_setting(&settings[i], settings[i].setting);
977 #if defined (HAVE_RECORDING) && CONFIG_CODEC == SWCODEC
978 enc_global_settings_reset();
979 #endif
982 /** Changing setting values **/
983 const struct settings_list* find_setting(const void* variable, int *id)
985 int i;
986 for(i=0;i<nb_settings;i++)
988 if (settings[i].setting == variable)
990 if (id)
991 *id = i;
992 return &settings[i];
995 return NULL;
998 bool set_bool(const char* string, const bool* variable )
1000 return set_bool_options(string, variable,
1001 (char *)STR(LANG_SET_BOOL_YES),
1002 (char *)STR(LANG_SET_BOOL_NO),
1003 NULL);
1007 bool set_bool_options(const char* string, const bool* variable,
1008 const char* yes_str, int yes_voice,
1009 const char* no_str, int no_voice,
1010 void (*function)(bool))
1012 struct opt_items names[] = {
1013 {(unsigned const char *)no_str, no_voice},
1014 {(unsigned const char *)yes_str, yes_voice}
1016 bool result;
1018 result = set_option(string, variable, BOOL, names, 2,
1019 (void (*)(int))function);
1020 return result;
1023 bool set_int(const unsigned char* string,
1024 const char* unit,
1025 int voice_unit,
1026 const int* variable,
1027 void (*function)(int),
1028 int step,
1029 int min,
1030 int max,
1031 void (*formatter)(char*, size_t, int, const char*) )
1033 return set_int_ex(string, unit, voice_unit, variable, function,
1034 step, min, max, formatter, NULL);
1037 bool set_int_ex(const unsigned char* string,
1038 const char* unit,
1039 int voice_unit,
1040 const int* variable,
1041 void (*function)(int),
1042 int step,
1043 int min,
1044 int max,
1045 void (*formatter)(char*, size_t, int, const char*),
1046 int32_t (*get_talk_id)(int, int))
1048 (void)unit;
1049 struct settings_list item;
1050 struct int_setting data = {
1051 function, voice_unit, min, max, step,
1052 formatter, get_talk_id
1054 item.int_setting = &data;
1055 item.flags = F_INT_SETTING|F_T_INT;
1056 item.lang_id = -1;
1057 item.cfg_vals = (char*)string;
1058 item.setting = (void *)variable;
1059 return option_screen(&item, NULL, false, NULL);
1063 static const struct opt_items *set_option_options;
1064 static void set_option_formatter(char* buf, size_t size, int item, const char* unit)
1066 (void)unit;
1067 const unsigned char *text = set_option_options[item].string;
1068 snprintf(buf, size, "%s", P2STR(text));
1070 static int32_t set_option_get_talk_id(int value, int unit)
1072 (void)unit;
1073 return set_option_options[value].voice_id;
1075 bool set_option(const char* string, const void* variable, enum optiontype type,
1076 const struct opt_items* options,
1077 int numoptions, void (*function)(int))
1079 int temp;
1080 struct settings_list item;
1081 struct int_setting data = {
1082 function, UNIT_INT, 0, numoptions-1, 1,
1083 set_option_formatter, set_option_get_talk_id
1085 set_option_options = options;
1086 item.int_setting = &data;
1087 item.flags = F_INT_SETTING|F_T_INT;
1088 item.lang_id = -1;
1089 item.cfg_vals = (char*)string;
1090 item.setting = &temp;
1091 if (type == BOOL)
1092 temp = *(bool*)variable? 1: 0;
1093 else
1094 temp = *(int*)variable;
1095 if (!option_screen(&item, NULL, false, NULL))
1097 if (type == BOOL)
1098 *(bool*)variable = (temp == 1? true: false);
1099 else
1100 *(int*)variable = temp;
1101 return false;
1103 return true;
1107 void set_file(const char* filename, char* setting, int maxlen)
1109 char* fptr = strrchr(filename,'/');
1110 int len;
1111 int extlen = 0;
1112 char* ptr;
1114 if (!fptr)
1115 return;
1117 *fptr = 0;
1118 fptr++;
1120 len = strlen(fptr);
1121 ptr = fptr + len;
1122 while ((*ptr != '.') && (ptr != fptr)) {
1123 extlen++;
1124 ptr--;
1126 if(ptr == fptr) extlen = 0;
1128 if (strncasecmp(ROCKBOX_DIR, filename ,strlen(ROCKBOX_DIR)) ||
1129 (len-extlen > maxlen))
1130 return;
1132 strncpy(setting, fptr, len-extlen);
1133 setting[len-extlen]=0;
1135 settings_save();