make sure closing the application aborts the remaining HttpGet objects. Should fix...
[Rockbox.git] / apps / settings.c
blobc7c8772975be693ece545c9a66f6756596ac04d7
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 mpeg_id3_options(global_settings.id3_v1_first);
727 set_poweroff_timeout(global_settings.poweroff);
729 set_battery_capacity(global_settings.battery_capacity);
730 #if BATTERY_TYPES_COUNT > 1
731 set_battery_type(global_settings.battery_type);
732 #endif
734 #ifdef HAVE_LCD_BITMAP
735 lcd_set_invert_display(global_settings.invert);
736 lcd_set_flip(global_settings.flip_display);
737 button_set_flip(global_settings.flip_display);
738 lcd_update(); /* refresh after flipping the screen */
739 settings_apply_pm_range();
740 peak_meter_init_times(
741 global_settings.peak_meter_release, global_settings.peak_meter_hold,
742 global_settings.peak_meter_clip_hold);
743 #endif
745 #if LCD_DEPTH > 1
746 unload_wps_backdrop();
747 #endif
748 #if defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1
749 unload_remote_wps_backdrop();
750 #endif
751 if ( global_settings.wps_file[0] &&
752 global_settings.wps_file[0] != 0xff ) {
753 snprintf(buf, sizeof buf, WPS_DIR "/%s.wps",
754 global_settings.wps_file);
755 wps_data_load(gui_wps[0].data, buf, true);
757 else
759 wps_data_init(gui_wps[0].data);
760 #ifdef HAVE_REMOTE_LCD
761 gui_wps[0].data->remote_wps = false;
762 #endif
765 #if LCD_DEPTH > 1
766 if ( global_settings.backdrop_file[0] &&
767 global_settings.backdrop_file[0] != 0xff ) {
768 snprintf(buf, sizeof buf, BACKDROP_DIR "/%s.bmp",
769 global_settings.backdrop_file);
770 load_main_backdrop(buf);
771 } else {
772 unload_main_backdrop();
774 show_main_backdrop();
775 #endif
776 #if defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1
777 show_remote_main_backdrop();
778 #endif
780 #ifdef HAVE_LCD_COLOR
781 screens[SCREEN_MAIN].set_foreground(global_settings.fg_color);
782 screens[SCREEN_MAIN].set_background(global_settings.bg_color);
783 #endif
785 #if defined(HAVE_REMOTE_LCD) && (NB_SCREENS > 1)
786 if ( global_settings.rwps_file[0]) {
787 snprintf(buf, sizeof buf, WPS_DIR "/%s.rwps",
788 global_settings.rwps_file);
789 wps_data_load(gui_wps[1].data, buf, true);
791 else
793 wps_data_init(gui_wps[1].data);
794 gui_wps[1].data->remote_wps = true;
796 #endif
798 #ifdef HAVE_LCD_BITMAP
799 if ( global_settings.font_file[0]) {
800 snprintf(buf, sizeof buf, FONT_DIR "/%s.fnt",
801 global_settings.font_file);
802 font_load(buf);
804 else
805 font_reset();
807 if ( global_settings.kbd_file[0]) {
808 snprintf(buf, sizeof buf, ROCKBOX_DIR "/%s.kbd",
809 global_settings.kbd_file);
810 load_kbd(buf);
812 else
813 load_kbd(NULL);
815 lcd_scroll_step(global_settings.scroll_step);
816 gui_list_screen_scroll_step(global_settings.screen_scroll_step);
817 gui_list_screen_scroll_out_of_view(global_settings.offset_out_of_view);
818 #else
819 lcd_jump_scroll(global_settings.jump_scroll);
820 lcd_jump_scroll_delay(global_settings.jump_scroll_delay);
821 #endif
822 lcd_bidir_scroll(global_settings.bidir_limit);
823 lcd_scroll_delay(global_settings.scroll_delay);
825 if ( global_settings.lang_file[0]) {
826 snprintf(buf, sizeof buf, LANG_DIR "/%s.lng",
827 global_settings.lang_file);
828 lang_load(buf);
829 talk_init(); /* use voice of same language */
832 set_codepage(global_settings.default_codepage);
834 #if CONFIG_CODEC == SWCODEC
835 audio_set_crossfade(global_settings.crossfade);
836 dsp_set_replaygain();
837 dsp_set_crossfeed(global_settings.crossfeed);
838 dsp_set_crossfeed_direct_gain(global_settings.crossfeed_direct_gain);
839 dsp_set_crossfeed_cross_params(global_settings.crossfeed_cross_gain,
840 global_settings.crossfeed_hf_attenuation,
841 global_settings.crossfeed_hf_cutoff);
843 /* Configure software equalizer, hardware eq is handled in audio_init() */
844 dsp_set_eq(global_settings.eq_enabled);
845 dsp_set_eq_precut(global_settings.eq_precut);
846 for(i = 0; i < 5; i++) {
847 dsp_set_eq_coefs(i);
850 dsp_dither_enable(global_settings.dithering_enabled);
851 #endif
853 #ifdef HAVE_SPDIF_POWER
854 spdif_power_enable(global_settings.spdif_enable);
855 #endif
857 #ifdef HAVE_BACKLIGHT
858 set_backlight_filter_keypress(global_settings.bl_filter_first_keypress);
859 #ifdef HAVE_REMOTE_LCD
860 set_remote_backlight_filter_keypress(global_settings.remote_bl_filter_first_keypress);
861 #endif
862 #ifdef HAS_BUTTON_HOLD
863 backlight_set_on_button_hold(global_settings.backlight_on_button_hold);
864 #endif
865 #ifdef HAVE_LCD_SLEEP
866 lcd_set_sleep_after_backlight_off(global_settings.lcd_sleep_after_backlight_off);
867 #endif
868 #endif /* HAVE_BACKLIGHT */
870 /* This should stay last */
871 #if defined(HAVE_RECORDING) && CONFIG_CODEC == SWCODEC
872 enc_global_settings_apply();
873 #endif
874 /* load the icon set */
875 icons_init();
877 #ifdef HAVE_LCD_COLOR
878 if (global_settings.colors_file)
879 read_color_theme_file();
880 #endif
882 #ifdef HAVE_USBSTACK
883 usb_controller_select(global_settings.usb_stack_mode);
884 usb_device_driver_bind(global_settings.usb_stack_device_driver);
885 #endif
890 * reset all settings to their default value
892 void settings_reset(void) {
894 int i;
895 DEBUGF( "settings_reset()\n" );
897 for(i=0; i<nb_settings; i++)
899 switch (settings[i].flags&F_T_MASK)
901 case F_T_INT:
902 case F_T_UINT:
903 if (settings[i].flags&F_DEF_ISFUNC)
904 *(int*)settings[i].setting = settings[i].default_val.func();
905 else if (settings[i].flags&F_T_SOUND)
906 *(int*)settings[i].setting =
907 sound_default(settings[i].sound_setting->setting);
908 else *(int*)settings[i].setting = settings[i].default_val.int_;
909 break;
910 case F_T_BOOL:
911 *(bool*)settings[i].setting = settings[i].default_val.bool_;
912 break;
913 case F_T_CHARPTR:
914 case F_T_UCHARPTR:
915 strncpy((char*)settings[i].setting,
916 settings[i].default_val.charptr,MAX_FILENAME);
917 break;
919 } /* for(...) */
920 #if defined (HAVE_RECORDING) && CONFIG_CODEC == SWCODEC
921 enc_global_settings_reset();
922 #endif
925 /** Changing setting values **/
926 const struct settings_list* find_setting(void* variable, int *id)
928 int i;
929 for(i=0;i<nb_settings;i++)
931 if (settings[i].setting == variable)
933 if (id)
934 *id = i;
935 return &settings[i];
938 return NULL;
941 void talk_setting(void *global_settings_variable)
943 const struct settings_list *setting;
944 if (!talk_menus_enabled())
945 return;
946 setting = find_setting(global_settings_variable, NULL);
947 if (setting == NULL)
948 return;
949 if (setting->lang_id)
950 talk_id(setting->lang_id,false);
953 bool set_bool(const char* string, bool* variable )
955 return set_bool_options(string, variable,
956 (char *)STR(LANG_SET_BOOL_YES),
957 (char *)STR(LANG_SET_BOOL_NO),
958 NULL);
962 bool set_bool_options(const char* string, bool* variable,
963 const char* yes_str, int yes_voice,
964 const char* no_str, int no_voice,
965 void (*function)(bool))
967 struct opt_items names[] = {
968 {(unsigned char *)no_str, no_voice},
969 {(unsigned char *)yes_str, yes_voice}
971 bool result;
973 result = set_option(string, variable, BOOL, names, 2,
974 (void (*)(int))function);
975 return result;
978 bool set_int(const unsigned char* string,
979 const char* unit,
980 int voice_unit,
981 int* variable,
982 void (*function)(int),
983 int step,
984 int min,
985 int max,
986 void (*formatter)(char*, size_t, int, const char*) )
988 return set_int_ex(string, unit, voice_unit, variable, function,
989 step, min, max, formatter, NULL);
993 /** extra stuff which is probably misplaced **/
995 void set_file(char* filename, char* setting, int maxlen)
997 char* fptr = strrchr(filename,'/');
998 int len;
999 int extlen = 0;
1000 char* ptr;
1002 if (!fptr)
1003 return;
1005 *fptr = 0;
1006 fptr++;
1008 len = strlen(fptr);
1009 ptr = fptr + len;
1010 while ((*ptr != '.') && (ptr != fptr)) {
1011 extlen++;
1012 ptr--;
1014 if(ptr == fptr) extlen = 0;
1016 if (strncasecmp(ROCKBOX_DIR, filename ,strlen(ROCKBOX_DIR)) ||
1017 (len-extlen > maxlen))
1018 return;
1020 strncpy(setting, fptr, len-extlen);
1021 setting[len-extlen]=0;
1023 settings_save();