PP502x: Make RAM physical addresses uncached. Cache the flash ROM on targets with...
[Rockbox.git] / apps / settings.c
blobcacf3e58545fa0e4ddeaa505077a9bb750494723
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2002 by wavey@wavey.org
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"
66 #if (LCD_DEPTH > 1) || (defined(HAVE_LCD_REMOTE) && (LCD_REMOTE_DEPTH > 1))
67 #include "backdrop.h"
68 #endif
70 #if CONFIG_TUNER
71 #include "radio.h"
72 #endif
74 #if CONFIG_CODEC == MAS3507D
75 void dac_line_in(bool enable);
76 #endif
77 struct user_settings global_settings;
78 struct system_status global_status;
80 #if CONFIG_CODEC == SWCODEC
81 #include "pcmbuf.h"
82 #include "pcm_playback.h"
83 #include "dsp.h"
84 #ifdef HAVE_RECORDING
85 #include "enc_config.h"
86 #endif
87 #endif /* CONFIG_CODEC == SWCODEC */
89 #define NVRAM_BLOCK_SIZE 44
91 #ifdef HAVE_LCD_BITMAP
92 #define MAX_LINES 10
93 #else
94 #define MAX_LINES 2
95 #endif
97 #ifdef HAVE_REMOTE_LCD
98 #include "lcd-remote.h"
99 #endif
101 #ifdef HAVE_USBSTACK
102 #include "usbstack.h"
103 #endif
105 long lasttime = 0;
107 /** NVRAM stuff, if the target doesnt have NVRAM it is saved in ROCKBOX_DIR /nvram.bin **/
108 /* NVRAM is set out as
109 [0] 'R'
110 [1] 'b'
111 [2] version
112 [3] stored variable count
113 [4-7] crc32 checksum
114 [8-NVRAM_BLOCK_SIZE] data
116 #define NVRAM_DATA_START 8
117 #define NVRAM_FILE ROCKBOX_DIR "/nvram.bin"
118 static char nvram_buffer[NVRAM_BLOCK_SIZE];
120 static bool read_nvram_data(char* buf, int max_len)
122 unsigned crc32 = 0xffffffff;
123 int var_count = 0, i = 0, buf_pos = 0;
124 #ifndef HAVE_RTC_RAM
125 int fd = open(NVRAM_FILE,O_RDONLY);
126 if (fd < 0)
127 return false;
128 memset(buf,0,max_len);
129 if (read(fd,buf,max_len) < 8) /* min is 8 bytes,magic, ver, vars, crc32 */
130 return false;
131 close(fd);
132 #else
133 memset(buf,0,max_len);
134 /* read rtc block */
135 for (i=0; i < max_len; i++ )
136 buf[i] = rtc_read(0x14+i);
137 #endif
138 /* check magic, version */
139 if ((buf[0] != 'R') || (buf[1] != 'b')
140 || (buf[2] != NVRAM_CONFIG_VERSION))
141 return false;
142 /* check crc32 */
143 crc32 = crc_32(&buf[NVRAM_DATA_START],
144 max_len-NVRAM_DATA_START-1,0xffffffff);
145 if (memcmp(&crc32,&buf[4],4))
146 return false;
147 /* all good, so read in the settings */
148 var_count = buf[3];
149 buf_pos = NVRAM_DATA_START;
150 for(i=0; i<nb_settings; i++)
152 int nvram_bytes = (settings[i].flags&F_NVRAM_BYTES_MASK)
153 >>F_NVRAM_MASK_SHIFT;
154 if (nvram_bytes)
156 if ((var_count>0) && (buf_pos<max_len))
158 memcpy(settings[i].setting,&buf[buf_pos],nvram_bytes);
159 buf_pos += nvram_bytes;
160 var_count--;
162 else /* should only happen when new items are added to the end */
164 memcpy(settings[i].setting, &settings[i].default_val, nvram_bytes);
168 return true;
170 static bool write_nvram_data(char* buf, int max_len)
172 unsigned crc32 = 0xffffffff;
173 int i = 0, buf_pos = 0;
174 char var_count = 0;
175 #ifndef HAVE_RTC_RAM
176 int fd;
177 #endif
178 memset(buf,0,max_len);
179 /* magic, version */
180 buf[0] = 'R'; buf[1] = 'b';
181 buf[2] = NVRAM_CONFIG_VERSION;
182 buf_pos = NVRAM_DATA_START;
183 for(i=0; (i<nb_settings) && (buf_pos<max_len); i++)
185 int nvram_bytes = (settings[i].flags&F_NVRAM_BYTES_MASK)
186 >>F_NVRAM_MASK_SHIFT;
187 if (nvram_bytes)
189 memcpy(&buf[buf_pos],settings[i].setting,nvram_bytes);
190 buf_pos += nvram_bytes;
191 var_count++;
194 /* count and crc32 */
195 buf[3] = var_count;
196 crc32 = crc_32(&buf[NVRAM_DATA_START],
197 max_len-NVRAM_DATA_START-1,0xffffffff);
198 memcpy(&buf[4],&crc32,4);
199 #ifndef HAVE_RTC_RAM
200 fd = open(NVRAM_FILE,O_CREAT|O_TRUNC|O_WRONLY);
201 if (fd >= 0)
203 int len = write(fd,buf,max_len);
204 close(fd);
205 if (len < 8)
206 return false;
208 #else
209 /* FIXME: okay, it _would_ be cleaner and faster to implement rtc_write so
210 that it would write a number of bytes at a time since the RTC chip
211 supports that, but this will have to do for now 8-) */
212 for (i=0; i < NVRAM_BLOCK_SIZE; i++ ) {
213 int r = rtc_write(0x14+i, buf[i]);
214 if (r) {
215 DEBUGF( "save_config_buffer: rtc_write failed at addr 0x%02x: %d\n",
216 14+i, r );
217 return false;
220 #endif
221 return true;
224 /** Reading from a config file **/
226 * load settings from disk or RTC RAM
228 void settings_load(int which)
230 DEBUGF( "reload_all_settings()\n" );
231 if (which&SETTINGS_RTC)
232 read_nvram_data(nvram_buffer,NVRAM_BLOCK_SIZE);
233 if (which&SETTINGS_HD)
235 settings_load_config(CONFIGFILE,false);
236 settings_load_config(FIXEDSETTINGSFILE,false);
240 static bool cfg_string_to_int(int setting_id, int* out, char* str)
242 const char* start = settings[setting_id].cfg_vals;
243 char* end = NULL;
244 char temp[MAX_PATH];
245 int count = 0;
246 while (1)
248 end = strchr(start, ',');
249 if (!end)
251 if (!strcmp(str, start))
253 *out = count;
254 return true;
256 else return false;
258 strncpy(temp, start, end-start);
259 temp[end-start] = '\0';
260 if (!strcmp(str, temp))
262 *out = count;
263 return true;
265 start = end +1;
266 count++;
268 return false;
271 bool settings_load_config(const char* file, bool apply)
273 int fd;
274 char line[128];
275 char* name;
276 char* value;
277 int i;
278 fd = open(file, O_RDONLY);
279 if (fd < 0)
280 return false;
282 while (read_line(fd, line, sizeof line) > 0)
284 if (!settings_parseline(line, &name, &value))
285 continue;
286 for(i=0; i<nb_settings; i++)
288 if (settings[i].cfg_name == NULL)
289 continue;
290 if (!strcasecmp(name,settings[i].cfg_name))
292 switch (settings[i].flags&F_T_MASK)
294 case F_T_INT:
295 case F_T_UINT:
296 #ifdef HAVE_LCD_COLOR
297 if (settings[i].flags&F_RGB)
298 *(int*)settings[i].setting = hex_to_rgb(value);
299 else
300 #endif
301 if (settings[i].cfg_vals == NULL)
303 *(int*)settings[i].setting = atoi(value);
305 else
307 cfg_string_to_int(i,(int*)settings[i].setting,value);
309 break;
310 case F_T_BOOL:
312 int temp;
313 if (cfg_string_to_int(i,&temp,value))
314 *(bool*)settings[i].setting = (temp==0?false:true);
315 break;
317 case F_T_CHARPTR:
318 case F_T_UCHARPTR:
320 char storage[MAX_PATH];
321 if (settings[i].filename_setting->prefix)
323 int len = strlen(settings[i].filename_setting->prefix);
324 if (!strncasecmp(value,
325 settings[i].filename_setting->prefix,
326 len))
328 strncpy(storage,&value[len],MAX_PATH);
330 else strncpy(storage,value,MAX_PATH);
332 else strncpy(storage,value,MAX_PATH);
333 if (settings[i].filename_setting->suffix)
335 char *s = strcasestr(storage,settings[i].filename_setting->suffix);
336 if (s) *s = '\0';
338 strncpy((char*)settings[i].setting,storage,
339 settings[i].filename_setting->max_len);
340 ((char*)settings[i].setting)
341 [settings[i].filename_setting->max_len-1] = '\0';
342 break;
345 break;
346 } /* if (!strcmp(name,settings[i].cfg_name)) */
347 } /* for(...) */
348 } /* while(...) */
350 close(fd);
351 settings_save();
352 if (apply)
353 settings_apply();
354 return true;
357 /** Writing to a config file and saving settings **/
359 bool cfg_int_to_string(int setting_id, int val, char* buf, int buf_len)
361 const char* start = settings[setting_id].cfg_vals;
362 char* end = NULL;
363 int count = 0;
364 while (count < val)
366 start = strchr(start,',');
367 if (!start)
368 return false;
369 count++;
370 start++;
372 end = strchr(start,',');
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 static bool is_changed(int setting_id)
385 const struct settings_list *setting = &settings[setting_id];
386 switch (setting->flags&F_T_MASK)
388 case F_T_INT:
389 case F_T_UINT:
390 if (setting->flags&F_DEF_ISFUNC)
392 if (*(int*)setting->setting == setting->default_val.func())
393 return false;
395 else if (setting->flags&F_T_SOUND)
397 if (*(int*)setting->setting ==
398 sound_default(setting->sound_setting->setting))
399 return false;
401 else if (*(int*)setting->setting == setting->default_val.int_)
402 return false;
403 break;
404 case F_T_BOOL:
405 if (*(bool*)setting->setting == setting->default_val.bool_)
406 return false;
407 break;
408 case F_T_CHARPTR:
409 case F_T_UCHARPTR:
410 if (!strcmp((char*)setting->setting, setting->default_val.charptr))
411 return false;
412 break;
414 return true;
417 static bool settings_write_config(char* filename, int options)
419 int i;
420 int fd;
421 char value[MAX_PATH];
422 fd = open(filename,O_CREAT|O_TRUNC|O_WRONLY);
423 if (fd < 0)
424 return false;
425 fdprintf(fd, "# .cfg file created by rockbox %s - "
426 "http://www.rockbox.org\r\n\r\n", appsversion);
427 for(i=0; i<nb_settings; i++)
429 if (settings[i].cfg_name == NULL)
430 continue;
431 value[0] = '\0';
433 if ((options == SETTINGS_SAVE_CHANGED) &&
434 !is_changed(i))
435 continue;
436 else if ((options == SETTINGS_SAVE_THEME) &&
437 ((settings[i].flags&F_THEMESETTING) == 0))
438 continue;
439 #ifdef HAVE_RECORDING
440 else if ((options == SETTINGS_SAVE_RECPRESETS) &&
441 ((settings[i].flags&F_RECSETTING) == 0))
442 continue;
443 #endif
444 switch (settings[i].flags&F_T_MASK)
446 case F_T_INT:
447 case F_T_UINT:
448 #ifdef HAVE_LCD_COLOR
449 if (settings[i].flags&F_RGB)
451 int colour = *(int*)settings[i].setting;
452 snprintf(value,MAX_PATH,"%02x%02x%02x",
453 (int)RGB_UNPACK_RED(colour),
454 (int)RGB_UNPACK_GREEN(colour),
455 (int)RGB_UNPACK_BLUE(colour));
457 else
458 #endif
459 if (settings[i].cfg_vals == NULL)
461 snprintf(value,MAX_PATH,"%d",*(int*)settings[i].setting);
463 else
465 cfg_int_to_string(i, *(int*)settings[i].setting,
466 value, MAX_PATH);
468 break;
469 case F_T_BOOL:
470 cfg_int_to_string(i,
471 *(bool*)settings[i].setting==false?0:1, value, MAX_PATH);
472 break;
473 case F_T_CHARPTR:
474 case F_T_UCHARPTR:
475 if (((char*)settings[i].setting)[0] == '\0')
476 break;
477 if (settings[i].filename_setting->prefix)
479 snprintf(value,MAX_PATH,"%s%s%s",
480 settings[i].filename_setting->prefix,
481 (char*)settings[i].setting,
482 settings[i].filename_setting->suffix);
484 else strncpy(value,(char*)settings[i].setting,
485 settings[i].filename_setting->max_len);
486 break;
487 } /* switch () */
488 if (value[0])
489 fdprintf(fd,"%s: %s\r\n",settings[i].cfg_name,value);
490 } /* for(...) */
491 close(fd);
492 return true;
494 #ifndef HAVE_RTC_RAM
495 static bool flush_global_status_callback(void)
497 return write_nvram_data(nvram_buffer,NVRAM_BLOCK_SIZE);
499 #endif
500 static bool flush_config_block_callback(void)
502 bool r1, r2;
503 r1 = write_nvram_data(nvram_buffer,NVRAM_BLOCK_SIZE);
504 r2 = settings_write_config(CONFIGFILE, SETTINGS_SAVE_CHANGED);
505 return r1 || r2;
509 * persist all runtime user settings to disk or RTC RAM
511 static void update_runtime(void)
513 int elapsed_secs;
515 elapsed_secs = (current_tick - lasttime) / HZ;
516 global_status.runtime += elapsed_secs;
517 lasttime += (elapsed_secs * HZ);
519 if ( global_status.runtime > global_status.topruntime )
520 global_status.topruntime = global_status.runtime;
523 void status_save( void )
525 update_runtime();
526 #ifdef HAVE_RTC_RAM
527 /* this will be done in the ata_callback if
528 target doesnt have rtc ram */
529 write_nvram_data(nvram_buffer,NVRAM_BLOCK_SIZE);
530 #else
531 register_ata_idle_func(flush_global_status_callback);
532 #endif
535 int settings_save( void )
537 update_runtime();
538 #ifdef HAVE_RTC_RAM
539 /* this will be done in the ata_callback if
540 target doesnt have rtc ram */
541 write_nvram_data(nvram_buffer,NVRAM_BLOCK_SIZE);
542 #endif
543 if(!register_ata_idle_func(flush_config_block_callback))
545 int i;
546 FOR_NB_SCREENS(i)
548 screens[i].clear_display();
549 #ifdef HAVE_LCD_CHARCELLS
550 screens[i].puts(0, 0, str(LANG_SETTINGS_SAVE_FAILED));
551 screens[i].puts(0, 1, str(LANG_SETTINGS_PARTITION));
552 #else
553 screens[i].puts(4, 2, str(LANG_SETTINGS_SAVE_FAILED));
554 screens[i].puts(2, 4, str(LANG_SETTINGS_PARTITION));
555 screens[i].update();
556 #endif
558 cond_talk_ids_fq(LANG_SETTINGS_SAVE_FAILED);
559 sleep(HZ*2);
560 return -1;
562 return 0;
564 bool settings_save_config(int options)
566 char filename[MAX_PATH];
567 char *folder;
568 switch (options)
570 case SETTINGS_SAVE_THEME:
571 folder = THEME_DIR;
572 break;
573 #ifdef HAVE_RECORDING
574 case SETTINGS_SAVE_RECPRESETS:
575 folder = RECPRESETS_DIR;
576 break;
577 #endif
578 default:
579 folder = ROCKBOX_DIR;
581 create_numbered_filename(filename, folder, "config", ".cfg", 2
582 IF_CNFN_NUM_(, NULL));
584 /* allow user to modify filename */
585 while (true) {
586 if (!kbd_input(filename, sizeof filename)) {
587 break;
589 else {
590 gui_syncsplash(HZ, ID2P(LANG_CANCEL));
591 return false;
595 if (settings_write_config(filename, options))
596 gui_syncsplash(HZ, ID2P(LANG_SETTINGS_SAVED));
597 else
598 gui_syncsplash(HZ, ID2P(LANG_FAILED));
599 return true;
602 /** Apply and Reset settings **/
605 #ifdef HAVE_LCD_BITMAP
607 * Applies the range infos stored in global_settings to
608 * the peak meter.
610 void settings_apply_pm_range(void)
612 int pm_min, pm_max;
614 /* depending on the scale mode (dBfs or percent) the values
615 of global_settings.peak_meter_dbfs have different meanings */
616 if (global_settings.peak_meter_dbfs)
618 /* convert to dBfs * 100 */
619 pm_min = -(((int)global_settings.peak_meter_min) * 100);
620 pm_max = -(((int)global_settings.peak_meter_max) * 100);
622 else
624 /* percent is stored directly -> no conversion */
625 pm_min = global_settings.peak_meter_min;
626 pm_max = global_settings.peak_meter_max;
629 /* apply the range */
630 peak_meter_init_range(global_settings.peak_meter_dbfs, pm_min, pm_max);
632 #endif /* HAVE_LCD_BITMAP */
634 void sound_settings_apply(void)
636 #if CONFIG_CODEC == SWCODEC
637 sound_set_dsp_callback(dsp_callback);
638 #endif
639 sound_set(SOUND_BASS, global_settings.bass);
640 sound_set(SOUND_TREBLE, global_settings.treble);
641 sound_set(SOUND_BALANCE, global_settings.balance);
642 sound_set(SOUND_VOLUME, global_settings.volume);
643 sound_set(SOUND_CHANNELS, global_settings.channel_config);
644 sound_set(SOUND_STEREO_WIDTH, global_settings.stereo_width);
645 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
646 sound_set(SOUND_LOUDNESS, global_settings.loudness);
647 sound_set(SOUND_AVC, global_settings.avc);
648 sound_set(SOUND_MDB_STRENGTH, global_settings.mdb_strength);
649 sound_set(SOUND_MDB_HARMONICS, global_settings.mdb_harmonics);
650 sound_set(SOUND_MDB_CENTER, global_settings.mdb_center);
651 sound_set(SOUND_MDB_SHAPE, global_settings.mdb_shape);
652 sound_set(SOUND_MDB_ENABLE, global_settings.mdb_enable);
653 sound_set(SOUND_SUPERBASS, global_settings.superbass);
654 #endif
656 #ifdef HAVE_USB_POWER
657 #if CONFIG_CHARGING
658 usb_charging_enable(global_settings.usb_charging);
659 #endif
660 #endif
663 void settings_apply(void)
665 char buf[64];
666 #if CONFIG_CODEC == SWCODEC
667 int i;
668 #endif
670 DEBUGF( "settings_apply()\n" );
671 sound_settings_apply();
673 #ifndef HAVE_FLASH_STORAGE
674 audio_set_buffer_margin(global_settings.buffer_margin);
675 #endif
677 #ifdef HAVE_LCD_CONTRAST
678 lcd_set_contrast(global_settings.contrast);
679 #endif
680 lcd_scroll_speed(global_settings.scroll_speed);
681 #ifdef HAVE_REMOTE_LCD
682 lcd_remote_set_contrast(global_settings.remote_contrast);
683 lcd_remote_set_invert_display(global_settings.remote_invert);
684 lcd_remote_set_flip(global_settings.remote_flip_display);
685 lcd_remote_scroll_speed(global_settings.remote_scroll_speed);
686 lcd_remote_scroll_step(global_settings.remote_scroll_step);
687 lcd_remote_scroll_delay(global_settings.remote_scroll_delay);
688 lcd_remote_bidir_scroll(global_settings.remote_bidir_limit);
689 #ifdef HAVE_REMOTE_LCD_TICKING
690 lcd_remote_emireduce(global_settings.remote_reduce_ticking);
691 #endif
692 remote_backlight_set_timeout(global_settings.remote_backlight_timeout);
693 #if CONFIG_CHARGING
694 remote_backlight_set_timeout_plugged(global_settings.remote_backlight_timeout_plugged);
695 #endif
696 #ifdef HAS_REMOTE_BUTTON_HOLD
697 remote_backlight_set_on_button_hold(global_settings.remote_backlight_on_button_hold);
698 #endif
699 #endif /* HAVE_REMOTE_LCD */
700 #ifdef HAVE_BACKLIGHT_BRIGHTNESS
701 backlight_set_brightness(global_settings.brightness);
702 #endif
703 #ifdef HAVE_BACKLIGHT
704 backlight_set_timeout(global_settings.backlight_timeout);
705 #if CONFIG_CHARGING
706 backlight_set_timeout_plugged(global_settings.backlight_timeout_plugged);
707 #endif
708 #if defined(HAVE_BACKLIGHT_PWM_FADING) && !defined(SIMULATOR)
709 backlight_set_fade_in(global_settings.backlight_fade_in);
710 backlight_set_fade_out(global_settings.backlight_fade_out);
711 #endif
712 #endif
713 #ifdef HAVE_BUTTONLIGHT_BRIGHTNESS
714 buttonlight_set_brightness(global_settings.buttonlight_brightness);
715 #endif
716 #ifdef HAVE_BUTTON_LIGHT
717 button_backlight_set_timeout(global_settings.button_light_timeout);
718 #endif
719 #ifndef HAVE_FLASH_STORAGE
720 ata_spindown(global_settings.disk_spindown);
721 #endif
722 #if (CONFIG_CODEC == MAS3507D) && !defined(SIMULATOR)
723 dac_line_in(global_settings.line_in);
724 #endif
725 set_poweroff_timeout(global_settings.poweroff);
727 set_battery_capacity(global_settings.battery_capacity);
728 #if BATTERY_TYPES_COUNT > 1
729 set_battery_type(global_settings.battery_type);
730 #endif
732 #ifdef HAVE_LCD_BITMAP
733 lcd_set_invert_display(global_settings.invert);
734 lcd_set_flip(global_settings.flip_display);
735 button_set_flip(global_settings.flip_display);
736 lcd_update(); /* refresh after flipping the screen */
737 settings_apply_pm_range();
738 peak_meter_init_times(
739 global_settings.peak_meter_release, global_settings.peak_meter_hold,
740 global_settings.peak_meter_clip_hold);
741 #endif
743 #if LCD_DEPTH > 1
744 unload_wps_backdrop();
745 #endif
746 #if defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1
747 unload_remote_wps_backdrop();
748 #endif
749 if ( global_settings.wps_file[0] &&
750 global_settings.wps_file[0] != 0xff ) {
751 snprintf(buf, sizeof buf, WPS_DIR "/%s.wps",
752 global_settings.wps_file);
753 wps_data_load(gui_wps[0].data, buf, true);
755 else
757 wps_data_init(gui_wps[0].data);
758 #ifdef HAVE_REMOTE_LCD
759 gui_wps[0].data->remote_wps = false;
760 #endif
763 #if LCD_DEPTH > 1
764 if ( global_settings.backdrop_file[0] &&
765 global_settings.backdrop_file[0] != 0xff ) {
766 snprintf(buf, sizeof buf, BACKDROP_DIR "/%s.bmp",
767 global_settings.backdrop_file);
768 load_main_backdrop(buf);
769 } else {
770 unload_main_backdrop();
772 show_main_backdrop();
773 #endif
774 #if defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1
775 show_remote_main_backdrop();
776 #endif
778 #ifdef HAVE_LCD_COLOR
779 screens[SCREEN_MAIN].set_foreground(global_settings.fg_color);
780 screens[SCREEN_MAIN].set_background(global_settings.bg_color);
781 screens[SCREEN_MAIN].set_selector_start(global_settings.lss_color);
782 screens[SCREEN_MAIN].set_selector_end(global_settings.lse_color);
783 screens[SCREEN_MAIN].set_selector_text(global_settings.lst_color);
784 #endif
786 #if defined(HAVE_REMOTE_LCD) && (NB_SCREENS > 1)
787 if ( global_settings.rwps_file[0]) {
788 snprintf(buf, sizeof buf, WPS_DIR "/%s.rwps",
789 global_settings.rwps_file);
790 wps_data_load(gui_wps[1].data, buf, true);
792 else
794 wps_data_init(gui_wps[1].data);
795 gui_wps[1].data->remote_wps = true;
797 #endif
799 #ifdef HAVE_LCD_BITMAP
800 if ( global_settings.font_file[0]) {
801 snprintf(buf, sizeof buf, FONT_DIR "/%s.fnt",
802 global_settings.font_file);
803 font_load(buf);
805 else
806 font_reset();
808 if ( global_settings.kbd_file[0]) {
809 snprintf(buf, sizeof buf, ROCKBOX_DIR "/%s.kbd",
810 global_settings.kbd_file);
811 load_kbd(buf);
813 else
814 load_kbd(NULL);
816 lcd_scroll_step(global_settings.scroll_step);
817 gui_list_screen_scroll_step(global_settings.screen_scroll_step);
818 gui_list_screen_scroll_out_of_view(global_settings.offset_out_of_view);
819 #else
820 lcd_jump_scroll(global_settings.jump_scroll);
821 lcd_jump_scroll_delay(global_settings.jump_scroll_delay);
822 #endif
823 lcd_bidir_scroll(global_settings.bidir_limit);
824 lcd_scroll_delay(global_settings.scroll_delay);
826 if ( global_settings.lang_file[0]) {
827 snprintf(buf, sizeof buf, LANG_DIR "/%s.lng",
828 global_settings.lang_file);
829 lang_load(buf);
830 talk_init(); /* use voice of same language */
833 set_codepage(global_settings.default_codepage);
835 #if CONFIG_CODEC == SWCODEC
836 audio_set_crossfade(global_settings.crossfade);
837 dsp_set_replaygain();
838 dsp_set_crossfeed(global_settings.crossfeed);
839 dsp_set_crossfeed_direct_gain(global_settings.crossfeed_direct_gain);
840 dsp_set_crossfeed_cross_params(global_settings.crossfeed_cross_gain,
841 global_settings.crossfeed_hf_attenuation,
842 global_settings.crossfeed_hf_cutoff);
844 /* Configure software equalizer, hardware eq is handled in audio_init() */
845 dsp_set_eq(global_settings.eq_enabled);
846 dsp_set_eq_precut(global_settings.eq_precut);
847 for(i = 0; i < 5; i++) {
848 dsp_set_eq_coefs(i);
851 dsp_dither_enable(global_settings.dithering_enabled);
852 #endif
854 #ifdef HAVE_SPDIF_POWER
855 spdif_power_enable(global_settings.spdif_enable);
856 #endif
858 #ifdef HAVE_BACKLIGHT
859 set_backlight_filter_keypress(global_settings.bl_filter_first_keypress);
860 #ifdef HAVE_REMOTE_LCD
861 set_remote_backlight_filter_keypress(global_settings.remote_bl_filter_first_keypress);
862 #endif
863 #ifdef HAS_BUTTON_HOLD
864 backlight_set_on_button_hold(global_settings.backlight_on_button_hold);
865 #endif
866 #ifdef HAVE_LCD_SLEEP
867 lcd_set_sleep_after_backlight_off(global_settings.lcd_sleep_after_backlight_off);
868 #endif
869 #endif /* HAVE_BACKLIGHT */
871 /* This should stay last */
872 #if defined(HAVE_RECORDING) && CONFIG_CODEC == SWCODEC
873 enc_global_settings_apply();
874 #endif
875 /* load the icon set */
876 icons_init();
878 #ifdef HAVE_LCD_COLOR
879 if (global_settings.colors_file)
880 read_color_theme_file();
881 #endif
883 #ifdef HAVE_USBSTACK
885 #if USBSTACK_CAPS == (CONTROLLER_DEVICE|CONTROLLER_HOST)
886 usb_controller_select(global_settings.usb_stack_mode);
887 #elif USBSTACK_CAPS == (CONTROLLER_DEVICE)
888 usb_controller_select(DEVICE);
889 #elif USBSTACK_CAPS == (CONTROLLER_HOST)
890 usb_controller_select(HOST);
891 #endif
893 usb_device_driver_bind(global_settings.usb_stack_device_driver);
894 #endif
899 * reset all settings to their default value
901 void settings_reset(void) {
903 int i;
904 DEBUGF( "settings_reset()\n" );
906 for(i=0; i<nb_settings; i++)
908 switch (settings[i].flags&F_T_MASK)
910 case F_T_INT:
911 case F_T_UINT:
912 if (settings[i].flags&F_DEF_ISFUNC)
913 *(int*)settings[i].setting = settings[i].default_val.func();
914 else if (settings[i].flags&F_T_SOUND)
915 *(int*)settings[i].setting =
916 sound_default(settings[i].sound_setting->setting);
917 else *(int*)settings[i].setting = settings[i].default_val.int_;
918 break;
919 case F_T_BOOL:
920 *(bool*)settings[i].setting = settings[i].default_val.bool_;
921 break;
922 case F_T_CHARPTR:
923 case F_T_UCHARPTR:
924 strncpy((char*)settings[i].setting,
925 settings[i].default_val.charptr,MAX_FILENAME);
926 break;
928 } /* for(...) */
929 #if defined (HAVE_RECORDING) && CONFIG_CODEC == SWCODEC
930 enc_global_settings_reset();
931 #endif
934 /** Changing setting values **/
935 const struct settings_list* find_setting(void* variable, int *id)
937 int i;
938 for(i=0;i<nb_settings;i++)
940 if (settings[i].setting == variable)
942 if (id)
943 *id = i;
944 return &settings[i];
947 return NULL;
950 void talk_setting(void *global_settings_variable)
952 const struct settings_list *setting;
953 if (!talk_menus_enabled())
954 return;
955 setting = find_setting(global_settings_variable, NULL);
956 if (setting == NULL)
957 return;
958 if (setting->lang_id)
959 talk_id(setting->lang_id,false);
962 bool set_bool(const char* string, bool* variable )
964 return set_bool_options(string, variable,
965 (char *)STR(LANG_SET_BOOL_YES),
966 (char *)STR(LANG_SET_BOOL_NO),
967 NULL);
971 bool set_bool_options(const char* string, bool* variable,
972 const char* yes_str, int yes_voice,
973 const char* no_str, int no_voice,
974 void (*function)(bool))
976 struct opt_items names[] = {
977 {(unsigned char *)no_str, no_voice},
978 {(unsigned char *)yes_str, yes_voice}
980 bool result;
982 result = set_option(string, variable, BOOL, names, 2,
983 (void (*)(int))function);
984 return result;
987 bool set_int(const unsigned char* string,
988 const char* unit,
989 int voice_unit,
990 int* variable,
991 void (*function)(int),
992 int step,
993 int min,
994 int max,
995 void (*formatter)(char*, size_t, int, const char*) )
997 return set_int_ex(string, unit, voice_unit, variable, function,
998 step, min, max, formatter, NULL);
1002 /** extra stuff which is probably misplaced **/
1004 void set_file(char* filename, char* setting, int maxlen)
1006 char* fptr = strrchr(filename,'/');
1007 int len;
1008 int extlen = 0;
1009 char* ptr;
1011 if (!fptr)
1012 return;
1014 *fptr = 0;
1015 fptr++;
1017 len = strlen(fptr);
1018 ptr = fptr + len;
1019 while ((*ptr != '.') && (ptr != fptr)) {
1020 extlen++;
1021 ptr--;
1023 if(ptr == fptr) extlen = 0;
1025 if (strncasecmp(ROCKBOX_DIR, filename ,strlen(ROCKBOX_DIR)) ||
1026 (len-extlen > maxlen))
1027 return;
1029 strncpy(setting, fptr, len-extlen);
1030 setting[len-extlen]=0;
1032 settings_save();