Fix some quotation marks. Thanks to Alexander Levin for pointing it out.
[Rockbox.git] / apps / settings.c
blob895db697454f4a98b59a892810227daa1cb257ef
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 "atoi.h"
40 #include "screens.h"
41 #include "ctype.h"
42 #include "file.h"
43 #include "system.h"
44 #include "misc.h"
45 #ifdef HAVE_LCD_BITMAP
46 #include "icons.h"
47 #include "font.h"
48 #include "peakmeter.h"
49 #endif
50 #include "lang.h"
51 #include "language.h"
52 #include "gwps.h"
53 #include "powermgmt.h"
54 #include "sprintf.h"
55 #include "keyboard.h"
56 #include "version.h"
57 #include "sound.h"
58 #include "rbunicode.h"
59 #include "dircache.h"
60 #include "statusbar.h"
61 #include "splash.h"
62 #include "list.h"
63 #include "settings_list.h"
64 #include "filetypes.h"
65 #include "option_select.h"
66 #include "backdrop.h"
68 #if CONFIG_TUNER
69 #include "radio.h"
70 #endif
72 #if CONFIG_CODEC == MAS3507D
73 void dac_line_in(bool enable);
74 #endif
75 struct user_settings global_settings;
76 struct system_status global_status;
78 #if CONFIG_CODEC == SWCODEC
79 #include "pcmbuf.h"
80 #include "dsp.h"
81 #include "playback.h"
82 #ifdef HAVE_RECORDING
83 #include "enc_config.h"
84 #endif
85 #endif /* CONFIG_CODEC == SWCODEC */
87 #define NVRAM_BLOCK_SIZE 44
89 #ifdef HAVE_LCD_BITMAP
90 #define MAX_LINES 10
91 #else
92 #define MAX_LINES 2
93 #endif
95 #ifdef HAVE_REMOTE_LCD
96 #include "lcd-remote.h"
97 #endif
99 long lasttime = 0;
101 /** NVRAM stuff, if the target doesnt have NVRAM it is saved in ROCKBOX_DIR /nvram.bin **/
102 /* NVRAM is set out as
103 [0] 'R'
104 [1] 'b'
105 [2] version
106 [3] stored variable count
107 [4-7] crc32 checksum
108 [8-NVRAM_BLOCK_SIZE] data
110 #define NVRAM_DATA_START 8
111 #define NVRAM_FILE ROCKBOX_DIR "/nvram.bin"
112 static char nvram_buffer[NVRAM_BLOCK_SIZE];
114 static bool read_nvram_data(char* buf, int max_len)
116 unsigned crc32 = 0xffffffff;
117 int var_count = 0, i = 0, buf_pos = 0;
118 #ifndef HAVE_RTC_RAM
119 int fd = open(NVRAM_FILE,O_RDONLY);
120 if (fd < 0)
121 return false;
122 memset(buf,0,max_len);
123 if (read(fd,buf,max_len) < 8) /* min is 8 bytes,magic, ver, vars, crc32 */
124 return false;
125 close(fd);
126 #else
127 memset(buf,0,max_len);
128 /* read rtc block */
129 for (i=0; i < max_len; i++ )
130 buf[i] = rtc_read(0x14+i);
131 #endif
132 /* check magic, version */
133 if ((buf[0] != 'R') || (buf[1] != 'b')
134 || (buf[2] != NVRAM_CONFIG_VERSION))
135 return false;
136 /* check crc32 */
137 crc32 = crc_32(&buf[NVRAM_DATA_START],
138 max_len-NVRAM_DATA_START-1,0xffffffff);
139 if (memcmp(&crc32,&buf[4],4))
140 return false;
141 /* all good, so read in the settings */
142 var_count = buf[3];
143 buf_pos = NVRAM_DATA_START;
144 for(i=0; i<nb_settings; i++)
146 int nvram_bytes = (settings[i].flags&F_NVRAM_BYTES_MASK)
147 >>F_NVRAM_MASK_SHIFT;
148 if (nvram_bytes)
150 if ((var_count>0) && (buf_pos<max_len))
152 memcpy(settings[i].setting,&buf[buf_pos],nvram_bytes);
153 buf_pos += nvram_bytes;
154 var_count--;
156 else /* should only happen when new items are added to the end */
158 memcpy(settings[i].setting, &settings[i].default_val, nvram_bytes);
162 return true;
164 static bool write_nvram_data(char* buf, int max_len)
166 unsigned crc32 = 0xffffffff;
167 int i = 0, buf_pos = 0;
168 char var_count = 0;
169 #ifndef HAVE_RTC_RAM
170 int fd;
171 #endif
172 memset(buf,0,max_len);
173 /* magic, version */
174 buf[0] = 'R'; buf[1] = 'b';
175 buf[2] = NVRAM_CONFIG_VERSION;
176 buf_pos = NVRAM_DATA_START;
177 for(i=0; (i<nb_settings) && (buf_pos<max_len); i++)
179 int nvram_bytes = (settings[i].flags&F_NVRAM_BYTES_MASK)
180 >>F_NVRAM_MASK_SHIFT;
181 if (nvram_bytes)
183 memcpy(&buf[buf_pos],settings[i].setting,nvram_bytes);
184 buf_pos += nvram_bytes;
185 var_count++;
188 /* count and crc32 */
189 buf[3] = var_count;
190 crc32 = crc_32(&buf[NVRAM_DATA_START],
191 max_len-NVRAM_DATA_START-1,0xffffffff);
192 memcpy(&buf[4],&crc32,4);
193 #ifndef HAVE_RTC_RAM
194 fd = open(NVRAM_FILE,O_CREAT|O_TRUNC|O_WRONLY);
195 if (fd >= 0)
197 int len = write(fd,buf,max_len);
198 close(fd);
199 if (len < 8)
200 return false;
202 #else
203 /* FIXME: okay, it _would_ be cleaner and faster to implement rtc_write so
204 that it would write a number of bytes at a time since the RTC chip
205 supports that, but this will have to do for now 8-) */
206 for (i=0; i < NVRAM_BLOCK_SIZE; i++ ) {
207 int r = rtc_write(0x14+i, buf[i]);
208 if (r) {
209 DEBUGF( "save_config_buffer: rtc_write failed at addr 0x%02x: %d\n",
210 14+i, r );
211 return false;
214 #endif
215 return true;
218 /** Reading from a config file **/
220 * load settings from disk or RTC RAM
222 void settings_load(int which)
224 DEBUGF( "reload_all_settings()\n" );
225 if (which&SETTINGS_RTC)
226 read_nvram_data(nvram_buffer,NVRAM_BLOCK_SIZE);
227 if (which&SETTINGS_HD)
229 settings_load_config(CONFIGFILE,false);
230 settings_load_config(FIXEDSETTINGSFILE,false);
234 static bool cfg_string_to_int(int setting_id, int* out, const char* str)
236 const char* start = settings[setting_id].cfg_vals;
237 char* end = NULL;
238 char temp[MAX_PATH];
239 int count = 0;
240 while (1)
242 end = strchr(start, ',');
243 if (!end)
245 if (!strcmp(str, start))
247 *out = count;
248 return true;
250 else return false;
252 strncpy(temp, start, end-start);
253 temp[end-start] = '\0';
254 if (!strcmp(str, temp))
256 *out = count;
257 return true;
259 start = end +1;
260 count++;
262 return false;
265 bool settings_load_config(const char* file, bool apply)
267 int fd;
268 char line[128];
269 char* name;
270 char* value;
271 int i;
272 fd = open(file, O_RDONLY);
273 if (fd < 0)
274 return false;
276 while (read_line(fd, line, sizeof line) > 0)
278 if (!settings_parseline(line, &name, &value))
279 continue;
280 for(i=0; i<nb_settings; i++)
282 if (settings[i].cfg_name == NULL)
283 continue;
284 if (!strcasecmp(name,settings[i].cfg_name))
286 switch (settings[i].flags&F_T_MASK)
288 case F_T_INT:
289 case F_T_UINT:
290 #ifdef HAVE_LCD_COLOR
291 if (settings[i].flags&F_RGB)
292 hex_to_rgb(value, (int*)settings[i].setting);
293 else
294 #endif
295 if (settings[i].cfg_vals == NULL)
297 *(int*)settings[i].setting = atoi(value);
299 else
301 int temp, *v = (int*)settings[i].setting;
302 bool found = cfg_string_to_int(i, &temp, value);
303 if (found)
305 if (settings[i].flags&F_TABLE_SETTING)
306 *v = settings[i].table_setting->values[temp];
307 else
308 *v = temp;
310 else
311 *v = atoi(value);
313 break;
314 case F_T_BOOL:
316 int temp;
317 if (cfg_string_to_int(i,&temp,value))
318 *(bool*)settings[i].setting = (temp==0?false:true);
319 break;
321 case F_T_CHARPTR:
322 case F_T_UCHARPTR:
324 char storage[MAX_PATH];
325 if (settings[i].filename_setting->prefix)
327 int len = strlen(settings[i].filename_setting->prefix);
328 if (!strncasecmp(value,
329 settings[i].filename_setting->prefix,
330 len))
332 strncpy(storage,&value[len],MAX_PATH);
334 else strncpy(storage,value,MAX_PATH);
336 else strncpy(storage,value,MAX_PATH);
337 if (settings[i].filename_setting->suffix)
339 char *s = strcasestr(storage,settings[i].filename_setting->suffix);
340 if (s) *s = '\0';
342 strncpy((char*)settings[i].setting,storage,
343 settings[i].filename_setting->max_len);
344 ((char*)settings[i].setting)
345 [settings[i].filename_setting->max_len-1] = '\0';
346 break;
349 break;
350 } /* if (!strcmp(name,settings[i].cfg_name)) */
351 } /* for(...) */
352 } /* while(...) */
354 close(fd);
355 settings_save();
356 if (apply)
357 settings_apply(true);
358 return true;
361 /** Writing to a config file and saving settings **/
363 bool cfg_int_to_string(int setting_id, int val, char* buf, int buf_len)
365 int flags = settings[setting_id].flags;
366 const char* start = settings[setting_id].cfg_vals;
367 char* end = NULL;
368 int count = 0;
370 if ((flags&F_T_MASK)==F_T_INT &&
371 flags&F_TABLE_SETTING)
373 const int *value = settings[setting_id].table_setting->values;
374 while (start)
376 end = strchr(start,',');
377 if (value[count] == val)
379 if (end == NULL)
380 strncpy(buf, start, buf_len);
381 else
383 int len = (buf_len > (end-start))? end-start: buf_len;
384 strncpy(buf, start, len);
385 buf[len] = '\0';
387 return true;
389 count++;
391 if (end)
392 start = end+1;
393 else
394 break;
396 return false;
399 while (count < val)
401 start = strchr(start,',');
402 if (!start)
403 return false;
404 count++;
405 start++;
407 end = strchr(start,',');
408 if (end == NULL)
409 strncpy(buf, start, buf_len);
410 else
412 int len = (buf_len > (end-start))? end-start: buf_len;
413 strncpy(buf, start, len);
414 buf[len] = '\0';
416 return true;
420 static bool is_changed(int setting_id)
422 const struct settings_list *setting = &settings[setting_id];
423 switch (setting->flags&F_T_MASK)
425 case F_T_INT:
426 case F_T_UINT:
427 if (setting->flags&F_DEF_ISFUNC)
429 if (*(int*)setting->setting == setting->default_val.func())
430 return false;
432 else if (setting->flags&F_T_SOUND)
434 if (*(int*)setting->setting ==
435 sound_default(setting->sound_setting->setting))
436 return false;
438 else if (*(int*)setting->setting == setting->default_val.int_)
439 return false;
440 break;
441 case F_T_BOOL:
442 if (*(bool*)setting->setting == setting->default_val.bool_)
443 return false;
444 break;
445 case F_T_CHARPTR:
446 case F_T_UCHARPTR:
447 if (!strcmp((char*)setting->setting, setting->default_val.charptr))
448 return false;
449 break;
451 return true;
454 static bool settings_write_config(const char* filename, int options)
456 int i;
457 int fd;
458 char value[MAX_PATH];
459 fd = open(filename,O_CREAT|O_TRUNC|O_WRONLY);
460 if (fd < 0)
461 return false;
462 #if CONFIG_TUNER
463 bool statusbar = global_settings.statusbar;
464 if (global_status.statusbar_forced != 0 && statusbar)
465 global_settings.statusbar = false;
466 #endif
467 fdprintf(fd, "# .cfg file created by rockbox %s - "
468 "http://www.rockbox.org\r\n\r\n", appsversion);
469 for(i=0; i<nb_settings; i++)
471 if (settings[i].cfg_name == NULL)
472 continue;
473 value[0] = '\0';
475 switch (options)
477 case SETTINGS_SAVE_CHANGED:
478 if (!is_changed(i))
479 continue;
480 break;
481 case SETTINGS_SAVE_SOUND:
482 if ((settings[i].flags&F_SOUNDSETTING) == 0)
483 continue;
484 break;
485 case SETTINGS_SAVE_THEME:
486 if ((settings[i].flags&F_THEMESETTING) == 0)
487 continue;
488 break;
489 #ifdef HAVE_RECORDING
490 case SETTINGS_SAVE_RECPRESETS:
491 if ((settings[i].flags&F_RECSETTING) == 0)
492 continue;
493 break;
494 #endif
495 #if CONFIG_CODEC == SWCODEC
496 case SETTINGS_SAVE_EQPRESET:
497 if ((settings[i].flags&F_EQSETTING) == 0)
498 continue;
499 break;
500 #endif
502 switch (settings[i].flags&F_T_MASK)
504 case F_T_INT:
505 case F_T_UINT:
506 #ifdef HAVE_LCD_COLOR
507 if (settings[i].flags&F_RGB)
509 int colour = *(int*)settings[i].setting;
510 snprintf(value,MAX_PATH,"%02x%02x%02x",
511 (int)RGB_UNPACK_RED(colour),
512 (int)RGB_UNPACK_GREEN(colour),
513 (int)RGB_UNPACK_BLUE(colour));
515 else
516 #endif
517 if (settings[i].cfg_vals == NULL)
519 snprintf(value,MAX_PATH,"%d",*(int*)settings[i].setting);
521 else
523 if (cfg_int_to_string(i, *(int*)settings[i].setting,
524 value, MAX_PATH) == false)
526 snprintf(value,MAX_PATH,"%d",*(int*)settings[i].setting);
529 break;
530 case F_T_BOOL:
531 cfg_int_to_string(i,
532 *(bool*)settings[i].setting==false?0:1, value, MAX_PATH);
533 break;
534 case F_T_CHARPTR:
535 case F_T_UCHARPTR:
536 if (((char*)settings[i].setting)[0]
537 && settings[i].filename_setting->prefix)
539 snprintf(value,MAX_PATH,"%s%s%s",
540 settings[i].filename_setting->prefix,
541 (char*)settings[i].setting,
542 settings[i].filename_setting->suffix);
544 else strncpy(value,(char*)settings[i].setting,
545 settings[i].filename_setting->max_len);
546 break;
547 } /* switch () */
548 fdprintf(fd,"%s: %s\r\n",settings[i].cfg_name,value);
549 } /* for(...) */
550 close(fd);
551 #if CONFIG_TUNER
552 global_settings.statusbar = statusbar;
553 #endif
554 return true;
556 #ifndef HAVE_RTC_RAM
557 static bool flush_global_status_callback(void)
559 return write_nvram_data(nvram_buffer,NVRAM_BLOCK_SIZE);
561 #endif
562 static bool flush_config_block_callback(void)
564 bool r1, r2;
565 r1 = write_nvram_data(nvram_buffer,NVRAM_BLOCK_SIZE);
566 r2 = settings_write_config(CONFIGFILE, SETTINGS_SAVE_CHANGED);
567 return r1 || r2;
571 * persist all runtime user settings to disk or RTC RAM
573 static void update_runtime(void)
575 int elapsed_secs;
577 elapsed_secs = (current_tick - lasttime) / HZ;
578 global_status.runtime += elapsed_secs;
579 lasttime += (elapsed_secs * HZ);
581 if ( global_status.runtime > global_status.topruntime )
582 global_status.topruntime = global_status.runtime;
585 void status_save(void)
587 update_runtime();
588 #ifdef HAVE_RTC_RAM
589 /* this will be done in the ata_callback if
590 target doesnt have rtc ram */
591 write_nvram_data(nvram_buffer,NVRAM_BLOCK_SIZE);
592 #else
593 register_ata_idle_func(flush_global_status_callback);
594 #endif
597 int settings_save(void)
599 update_runtime();
600 #ifdef HAVE_RTC_RAM
601 /* this will be done in the ata_callback if
602 target doesnt have rtc ram */
603 write_nvram_data(nvram_buffer,NVRAM_BLOCK_SIZE);
604 #endif
605 register_ata_idle_func(flush_config_block_callback);
606 return 0;
609 bool settings_save_config(int options)
611 char filename[MAX_PATH];
612 char *folder;
613 switch (options)
615 case SETTINGS_SAVE_THEME:
616 folder = THEME_DIR;
617 break;
618 #ifdef HAVE_RECORDING
619 case SETTINGS_SAVE_RECPRESETS:
620 folder = RECPRESETS_DIR;
621 break;
622 #endif
623 #if CONFIG_CODEC == SWCODEC
624 case SETTINGS_SAVE_EQPRESET:
625 folder = EQS_DIR;
626 break;
627 #endif
628 case SETTINGS_SAVE_SOUND:
629 default:
630 folder = ROCKBOX_DIR;
632 create_numbered_filename(filename, folder, "config", ".cfg", 2
633 IF_CNFN_NUM_(, NULL));
635 /* allow user to modify filename */
636 while (true) {
637 if (!kbd_input(filename, sizeof filename)) {
638 break;
640 else {
641 gui_syncsplash(HZ, ID2P(LANG_CANCEL));
642 return false;
646 if (settings_write_config(filename, options))
647 gui_syncsplash(HZ, ID2P(LANG_SETTINGS_SAVED));
648 else
649 gui_syncsplash(HZ, ID2P(LANG_FAILED));
650 return true;
653 /** Apply and Reset settings **/
656 #ifdef HAVE_LCD_BITMAP
658 * Applies the range infos stored in global_settings to
659 * the peak meter.
661 void settings_apply_pm_range(void)
663 int pm_min, pm_max;
665 /* depending on the scale mode (dBfs or percent) the values
666 of global_settings.peak_meter_dbfs have different meanings */
667 if (global_settings.peak_meter_dbfs)
669 /* convert to dBfs * 100 */
670 pm_min = -(((int)global_settings.peak_meter_min) * 100);
671 pm_max = -(((int)global_settings.peak_meter_max) * 100);
673 else
675 /* percent is stored directly -> no conversion */
676 pm_min = global_settings.peak_meter_min;
677 pm_max = global_settings.peak_meter_max;
680 /* apply the range */
681 peak_meter_init_range(global_settings.peak_meter_dbfs, pm_min, pm_max);
683 #endif /* HAVE_LCD_BITMAP */
685 void sound_settings_apply(void)
687 #if CONFIG_CODEC == SWCODEC
688 sound_set_dsp_callback(dsp_callback);
689 #endif
690 sound_set(SOUND_BASS, global_settings.bass);
691 sound_set(SOUND_TREBLE, global_settings.treble);
692 sound_set(SOUND_BALANCE, global_settings.balance);
693 sound_set(SOUND_VOLUME, global_settings.volume);
694 sound_set(SOUND_CHANNELS, global_settings.channel_config);
695 sound_set(SOUND_STEREO_WIDTH, global_settings.stereo_width);
696 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
697 sound_set(SOUND_LOUDNESS, global_settings.loudness);
698 sound_set(SOUND_AVC, global_settings.avc);
699 sound_set(SOUND_MDB_STRENGTH, global_settings.mdb_strength);
700 sound_set(SOUND_MDB_HARMONICS, global_settings.mdb_harmonics);
701 sound_set(SOUND_MDB_CENTER, global_settings.mdb_center);
702 sound_set(SOUND_MDB_SHAPE, global_settings.mdb_shape);
703 sound_set(SOUND_MDB_ENABLE, global_settings.mdb_enable);
704 sound_set(SOUND_SUPERBASS, global_settings.superbass);
705 #endif
707 #ifdef HAVE_WM8758
708 sound_set(SOUND_BASS_CUTOFF, global_settings.bass_cutoff);
709 sound_set(SOUND_TREBLE_CUTOFF, global_settings.treble_cutoff);
710 #endif
712 #ifdef HAVE_USB_POWER
713 #if CONFIG_CHARGING
714 usb_charging_enable(global_settings.usb_charging);
715 #endif
716 #endif
719 void settings_apply(bool read_disk)
721 char buf[64];
722 #if CONFIG_CODEC == SWCODEC
723 int i;
724 #endif
726 DEBUGF( "settings_apply()\n" );
727 sound_settings_apply();
729 #ifndef HAVE_FLASH_STORAGE
730 audio_set_buffer_margin(global_settings.buffer_margin);
731 #endif
733 #ifdef HAVE_LCD_CONTRAST
734 lcd_set_contrast(global_settings.contrast);
735 #endif
736 lcd_scroll_speed(global_settings.scroll_speed);
737 #ifdef HAVE_REMOTE_LCD
738 lcd_remote_set_contrast(global_settings.remote_contrast);
739 lcd_remote_set_invert_display(global_settings.remote_invert);
740 lcd_remote_set_flip(global_settings.remote_flip_display);
741 lcd_remote_scroll_speed(global_settings.remote_scroll_speed);
742 lcd_remote_scroll_step(global_settings.remote_scroll_step);
743 lcd_remote_scroll_delay(global_settings.remote_scroll_delay);
744 lcd_remote_bidir_scroll(global_settings.remote_bidir_limit);
745 #ifdef HAVE_REMOTE_LCD_TICKING
746 lcd_remote_emireduce(global_settings.remote_reduce_ticking);
747 #endif
748 remote_backlight_set_timeout(global_settings.remote_backlight_timeout);
749 #if CONFIG_CHARGING
750 remote_backlight_set_timeout_plugged(global_settings.remote_backlight_timeout_plugged);
751 #endif
752 #ifdef HAS_REMOTE_BUTTON_HOLD
753 remote_backlight_set_on_button_hold(global_settings.remote_backlight_on_button_hold);
754 #endif
755 #endif /* HAVE_REMOTE_LCD */
756 #ifdef HAVE_BACKLIGHT_BRIGHTNESS
757 backlight_set_brightness(global_settings.brightness);
758 #endif
759 #ifdef HAVE_BACKLIGHT
760 backlight_set_timeout(global_settings.backlight_timeout);
761 #if CONFIG_CHARGING
762 backlight_set_timeout_plugged(global_settings.backlight_timeout_plugged);
763 #endif
764 #if defined(HAVE_BACKLIGHT_PWM_FADING) && !defined(SIMULATOR)
765 backlight_set_fade_in(global_settings.backlight_fade_in);
766 backlight_set_fade_out(global_settings.backlight_fade_out);
767 #endif
768 #endif
769 #ifdef HAVE_BUTTONLIGHT_BRIGHTNESS
770 buttonlight_set_brightness(global_settings.buttonlight_brightness);
771 #endif
772 #ifdef HAVE_BUTTON_LIGHT
773 buttonlight_set_timeout(global_settings.buttonlight_timeout);
774 #endif
775 #ifndef HAVE_FLASH_STORAGE
776 ata_spindown(global_settings.disk_spindown);
777 #endif
778 #if (CONFIG_CODEC == MAS3507D) && !defined(SIMULATOR)
779 dac_line_in(global_settings.line_in);
780 #endif
781 set_poweroff_timeout(global_settings.poweroff);
783 set_battery_capacity(global_settings.battery_capacity);
784 #if BATTERY_TYPES_COUNT > 1
785 set_battery_type(global_settings.battery_type);
786 #endif
788 #ifdef HAVE_LCD_BITMAP
789 lcd_set_invert_display(global_settings.invert);
790 lcd_set_flip(global_settings.flip_display);
791 button_set_flip(global_settings.flip_display);
792 lcd_update(); /* refresh after flipping the screen */
793 settings_apply_pm_range();
794 peak_meter_init_times(
795 global_settings.peak_meter_release, global_settings.peak_meter_hold,
796 global_settings.peak_meter_clip_hold);
797 #endif
799 if (read_disk)
801 #if LCD_DEPTH > 1
802 unload_wps_backdrop();
803 #endif
804 #if defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1
805 unload_remote_wps_backdrop();
806 #endif
807 if ( global_settings.wps_file[0] &&
808 global_settings.wps_file[0] != 0xff ) {
809 snprintf(buf, sizeof buf, WPS_DIR "/%s.wps",
810 global_settings.wps_file);
811 wps_data_load(gui_wps[0].data, &screens[0], buf, true);
813 else
815 wps_data_init(gui_wps[0].data);
816 #ifdef HAVE_REMOTE_LCD
817 gui_wps[0].data->remote_wps = false;
818 #endif
821 #if LCD_DEPTH > 1
822 if ( global_settings.backdrop_file[0] &&
823 global_settings.backdrop_file[0] != 0xff ) {
824 snprintf(buf, sizeof buf, BACKDROP_DIR "/%s.bmp",
825 global_settings.backdrop_file);
826 load_main_backdrop(buf);
827 } else {
828 unload_main_backdrop();
830 show_main_backdrop();
831 #endif
832 #if defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1
833 show_remote_main_backdrop();
834 #endif
836 #if defined(HAVE_REMOTE_LCD) && (NB_SCREENS > 1)
837 if ( global_settings.rwps_file[0]) {
838 snprintf(buf, sizeof buf, WPS_DIR "/%s.rwps",
839 global_settings.rwps_file);
840 wps_data_load(gui_wps[1].data, &screens[1], buf, true);
842 else
844 wps_data_init(gui_wps[1].data);
845 gui_wps[1].data->remote_wps = true;
847 #endif
849 #ifdef HAVE_LCD_BITMAP
850 if ( global_settings.font_file[0]) {
851 snprintf(buf, sizeof buf, FONT_DIR "/%s.fnt",
852 global_settings.font_file);
853 font_load(buf);
855 else
856 font_reset();
858 if ( global_settings.kbd_file[0]) {
859 snprintf(buf, sizeof buf, ROCKBOX_DIR "/%s.kbd",
860 global_settings.kbd_file);
861 load_kbd(buf);
863 else
864 load_kbd(NULL);
865 #endif
866 if ( global_settings.lang_file[0]) {
867 snprintf(buf, sizeof buf, LANG_DIR "/%s.lng",
868 global_settings.lang_file);
869 lang_load(buf);
870 talk_init(); /* use voice of same language */
872 /* load the icon set */
873 icons_init();
875 #ifdef HAVE_LCD_COLOR
876 if (global_settings.colors_file[0])
877 read_color_theme_file();
878 #endif
881 #ifdef HAVE_LCD_COLOR
882 screens[SCREEN_MAIN].set_foreground(global_settings.fg_color);
883 screens[SCREEN_MAIN].set_background(global_settings.bg_color);
884 screens[SCREEN_MAIN].set_selector_start(global_settings.lss_color);
885 screens[SCREEN_MAIN].set_selector_end(global_settings.lse_color);
886 screens[SCREEN_MAIN].set_selector_text(global_settings.lst_color);
887 #endif
889 #ifdef HAVE_LCD_BITMAP
890 lcd_scroll_step(global_settings.scroll_step);
891 gui_list_screen_scroll_step(global_settings.screen_scroll_step);
892 gui_list_screen_scroll_out_of_view(global_settings.offset_out_of_view);
893 #else
894 lcd_jump_scroll(global_settings.jump_scroll);
895 lcd_jump_scroll_delay(global_settings.jump_scroll_delay);
896 #endif
897 lcd_bidir_scroll(global_settings.bidir_limit);
898 lcd_scroll_delay(global_settings.scroll_delay);
901 set_codepage(global_settings.default_codepage);
903 #if CONFIG_CODEC == SWCODEC
904 audio_set_crossfade(global_settings.crossfade);
905 dsp_set_replaygain();
906 dsp_set_crossfeed(global_settings.crossfeed);
907 dsp_set_crossfeed_direct_gain(global_settings.crossfeed_direct_gain);
908 dsp_set_crossfeed_cross_params(global_settings.crossfeed_cross_gain,
909 global_settings.crossfeed_hf_attenuation,
910 global_settings.crossfeed_hf_cutoff);
912 /* Configure software equalizer, hardware eq is handled in audio_init() */
913 dsp_set_eq(global_settings.eq_enabled);
914 dsp_set_eq_precut(global_settings.eq_precut);
915 for(i = 0; i < 5; i++) {
916 dsp_set_eq_coefs(i);
919 dsp_dither_enable(global_settings.dithering_enabled);
920 #endif
922 #ifdef HAVE_SPDIF_POWER
923 spdif_power_enable(global_settings.spdif_enable);
924 #endif
926 #ifdef HAVE_BACKLIGHT
927 set_backlight_filter_keypress(global_settings.bl_filter_first_keypress);
928 #ifdef HAVE_REMOTE_LCD
929 set_remote_backlight_filter_keypress(global_settings.remote_bl_filter_first_keypress);
930 #endif
931 #ifdef HAS_BUTTON_HOLD
932 backlight_set_on_button_hold(global_settings.backlight_on_button_hold);
933 #endif
934 #ifdef HAVE_LCD_SLEEP
935 lcd_set_sleep_after_backlight_off(global_settings.lcd_sleep_after_backlight_off);
936 #endif
937 #endif /* HAVE_BACKLIGHT */
939 /* This should stay last */
940 #if defined(HAVE_RECORDING) && CONFIG_CODEC == SWCODEC
941 enc_global_settings_apply();
942 #endif
943 list_init_viewports(NULL);
948 * reset all settings to their default value
950 void settings_reset(void)
952 int i;
953 DEBUGF( "settings_reset()\n" );
955 for(i=0; i<nb_settings; i++)
957 switch (settings[i].flags&F_T_MASK)
959 case F_T_INT:
960 case F_T_UINT:
961 if (settings[i].flags&F_DEF_ISFUNC)
962 *(int*)settings[i].setting = settings[i].default_val.func();
963 else if (settings[i].flags&F_T_SOUND)
964 *(int*)settings[i].setting =
965 sound_default(settings[i].sound_setting->setting);
966 else *(int*)settings[i].setting = settings[i].default_val.int_;
967 break;
968 case F_T_BOOL:
969 *(bool*)settings[i].setting = settings[i].default_val.bool_;
970 break;
971 case F_T_CHARPTR:
972 case F_T_UCHARPTR:
973 strncpy((char*)settings[i].setting,
974 settings[i].default_val.charptr,MAX_FILENAME);
975 break;
977 } /* for(...) */
978 #if defined (HAVE_RECORDING) && CONFIG_CODEC == SWCODEC
979 enc_global_settings_reset();
980 #endif
983 /** Changing setting values **/
984 const struct settings_list* find_setting(const void* variable, int *id)
986 int i;
987 for(i=0;i<nb_settings;i++)
989 if (settings[i].setting == variable)
991 if (id)
992 *id = i;
993 return &settings[i];
996 return NULL;
999 bool set_bool(const char* string, const bool* variable )
1001 return set_bool_options(string, variable,
1002 (char *)STR(LANG_SET_BOOL_YES),
1003 (char *)STR(LANG_SET_BOOL_NO),
1004 NULL);
1008 bool set_bool_options(const char* string, const bool* variable,
1009 const char* yes_str, int yes_voice,
1010 const char* no_str, int no_voice,
1011 void (*function)(bool))
1013 struct opt_items names[] = {
1014 {(unsigned const char *)no_str, no_voice},
1015 {(unsigned const char *)yes_str, yes_voice}
1017 bool result;
1019 result = set_option(string, variable, BOOL, names, 2,
1020 (void (*)(int))function);
1021 return result;
1024 bool set_int(const unsigned char* string,
1025 const char* unit,
1026 int voice_unit,
1027 const int* variable,
1028 void (*function)(int),
1029 int step,
1030 int min,
1031 int max,
1032 void (*formatter)(char*, size_t, int, const char*) )
1034 return set_int_ex(string, unit, voice_unit, variable, function,
1035 step, min, max, formatter, NULL);
1038 bool set_int_ex(const unsigned char* string,
1039 const char* unit,
1040 int voice_unit,
1041 const int* variable,
1042 void (*function)(int),
1043 int step,
1044 int min,
1045 int max,
1046 void (*formatter)(char*, size_t, int, const char*),
1047 int32_t (*get_talk_id)(int, int))
1049 (void)unit;
1050 struct settings_list item;
1051 struct int_setting data = {
1052 function, voice_unit, min, max, step,
1053 formatter, get_talk_id
1055 item.int_setting = &data;
1056 item.flags = F_INT_SETTING|F_T_INT;
1057 item.lang_id = -1;
1058 item.cfg_vals = (char*)string;
1059 item.setting = (void *)variable;
1060 return option_screen(&item, false, NULL);
1064 static const struct opt_items *set_option_options;
1065 static void set_option_formatter(char* buf, size_t size, int item, const char* unit)
1067 (void)unit;
1068 const unsigned char *text = set_option_options[item].string;
1069 snprintf(buf, size, "%s", P2STR(text));
1071 static int32_t set_option_get_talk_id(int value, int unit)
1073 (void)unit;
1074 return set_option_options[value].voice_id;
1076 bool set_option(const char* string, const void* variable, enum optiontype type,
1077 const struct opt_items* options,
1078 int numoptions, void (*function)(int))
1080 int temp;
1081 struct settings_list item;
1082 struct int_setting data = {
1083 function, UNIT_INT, 0, numoptions-1, 1,
1084 set_option_formatter, set_option_get_talk_id
1086 set_option_options = options;
1087 item.int_setting = &data;
1088 item.flags = F_INT_SETTING|F_T_INT;
1089 item.lang_id = -1;
1090 item.cfg_vals = (char*)string;
1091 item.setting = &temp;
1092 if (type == BOOL)
1093 temp = *(bool*)variable? 1: 0;
1094 else
1095 temp = *(int*)variable;
1096 if (!option_screen(&item, false, NULL))
1098 if (type == BOOL)
1099 *(bool*)variable = (temp == 1? true: false);
1100 else
1101 *(int*)variable = temp;
1102 return false;
1104 return true;
1108 void set_file(const char* filename, char* setting, int maxlen)
1110 char* fptr = strrchr(filename,'/');
1111 int len;
1112 int extlen = 0;
1113 char* ptr;
1115 if (!fptr)
1116 return;
1118 *fptr = 0;
1119 fptr++;
1121 len = strlen(fptr);
1122 ptr = fptr + len;
1123 while ((*ptr != '.') && (ptr != fptr)) {
1124 extlen++;
1125 ptr--;
1127 if(ptr == fptr) extlen = 0;
1129 if (strncasecmp(ROCKBOX_DIR, filename ,strlen(ROCKBOX_DIR)) ||
1130 (len-extlen > maxlen))
1131 return;
1133 strncpy(setting, fptr, len-extlen);
1134 setting[len-extlen]=0;
1136 settings_save();