bump version to m1.0.5 release
[Rockbox.git] / apps / settings.c
blob58d9220dc308c74ae1a672ff468c8ccd23744ea4
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 "dsp.h"
80 #include "playback.h"
81 #ifdef HAVE_RECORDING
82 #include "enc_config.h"
83 #endif
84 #endif /* CONFIG_CODEC == SWCODEC */
86 #define NVRAM_BLOCK_SIZE 44
88 #ifdef HAVE_LCD_BITMAP
89 #define MAX_LINES 10
90 #else
91 #define MAX_LINES 2
92 #endif
94 #ifdef HAVE_REMOTE_LCD
95 #include "lcd-remote.h"
96 #endif
98 long lasttime = 0;
100 /** NVRAM stuff, if the target doesnt have NVRAM it is saved in ROCKBOX_DIR /nvram.bin **/
101 /* NVRAM is set out as
102 [0] 'R'
103 [1] 'b'
104 [2] version
105 [3] stored variable count
106 [4-7] crc32 checksum
107 [8-NVRAM_BLOCK_SIZE] data
109 #define NVRAM_DATA_START 8
110 #define NVRAM_FILE ROCKBOX_DIR "/nvram.bin"
111 static char nvram_buffer[NVRAM_BLOCK_SIZE];
113 static bool read_nvram_data(char* buf, int max_len)
115 unsigned crc32 = 0xffffffff;
116 int var_count = 0, i = 0, buf_pos = 0;
117 #ifndef HAVE_RTC_RAM
118 int fd = open(NVRAM_FILE,O_RDONLY);
119 if (fd < 0)
120 return false;
121 memset(buf,0,max_len);
122 if (read(fd,buf,max_len) < 8) /* min is 8 bytes,magic, ver, vars, crc32 */
123 return false;
124 close(fd);
125 #else
126 memset(buf,0,max_len);
127 /* read rtc block */
128 for (i=0; i < max_len; i++ )
129 buf[i] = rtc_read(0x14+i);
130 #endif
131 /* check magic, version */
132 if ((buf[0] != 'R') || (buf[1] != 'b')
133 || (buf[2] != NVRAM_CONFIG_VERSION))
134 return false;
135 /* check crc32 */
136 crc32 = crc_32(&buf[NVRAM_DATA_START],
137 max_len-NVRAM_DATA_START-1,0xffffffff);
138 if (memcmp(&crc32,&buf[4],4))
139 return false;
140 /* all good, so read in the settings */
141 var_count = buf[3];
142 buf_pos = NVRAM_DATA_START;
143 for(i=0; i<nb_settings; i++)
145 int nvram_bytes = (settings[i].flags&F_NVRAM_BYTES_MASK)
146 >>F_NVRAM_MASK_SHIFT;
147 if (nvram_bytes)
149 if ((var_count>0) && (buf_pos<max_len))
151 memcpy(settings[i].setting,&buf[buf_pos],nvram_bytes);
152 buf_pos += nvram_bytes;
153 var_count--;
155 else /* should only happen when new items are added to the end */
157 memcpy(settings[i].setting, &settings[i].default_val, nvram_bytes);
161 return true;
163 static bool write_nvram_data(char* buf, int max_len)
165 unsigned crc32 = 0xffffffff;
166 int i = 0, buf_pos = 0;
167 char var_count = 0;
168 #ifndef HAVE_RTC_RAM
169 int fd;
170 #endif
171 memset(buf,0,max_len);
172 /* magic, version */
173 buf[0] = 'R'; buf[1] = 'b';
174 buf[2] = NVRAM_CONFIG_VERSION;
175 buf_pos = NVRAM_DATA_START;
176 for(i=0; (i<nb_settings) && (buf_pos<max_len); i++)
178 int nvram_bytes = (settings[i].flags&F_NVRAM_BYTES_MASK)
179 >>F_NVRAM_MASK_SHIFT;
180 if (nvram_bytes)
182 memcpy(&buf[buf_pos],settings[i].setting,nvram_bytes);
183 buf_pos += nvram_bytes;
184 var_count++;
187 /* count and crc32 */
188 buf[3] = var_count;
189 crc32 = crc_32(&buf[NVRAM_DATA_START],
190 max_len-NVRAM_DATA_START-1,0xffffffff);
191 memcpy(&buf[4],&crc32,4);
192 #ifndef HAVE_RTC_RAM
193 fd = open(NVRAM_FILE,O_CREAT|O_TRUNC|O_WRONLY);
194 if (fd >= 0)
196 int len = write(fd,buf,max_len);
197 close(fd);
198 if (len < 8)
199 return false;
201 #else
202 /* FIXME: okay, it _would_ be cleaner and faster to implement rtc_write so
203 that it would write a number of bytes at a time since the RTC chip
204 supports that, but this will have to do for now 8-) */
205 for (i=0; i < NVRAM_BLOCK_SIZE; i++ ) {
206 int r = rtc_write(0x14+i, buf[i]);
207 if (r)
208 return false;
210 #endif
211 return true;
214 /** Reading from a config file **/
216 * load settings from disk or RTC RAM
218 void settings_load(int which)
220 if (which&SETTINGS_RTC)
221 read_nvram_data(nvram_buffer,NVRAM_BLOCK_SIZE);
222 if (which&SETTINGS_HD)
224 settings_load_config(CONFIGFILE,false);
225 settings_load_config(FIXEDSETTINGSFILE,false);
229 static bool cfg_string_to_int(int setting_id, int* out, const char* str)
231 const char* start = settings[setting_id].cfg_vals;
232 char* end = NULL;
233 char temp[MAX_PATH];
234 int count = 0;
235 while (1)
237 end = strchr(start, ',');
238 if (!end)
240 if (!strcmp(str, start))
242 *out = count;
243 return true;
245 else return false;
247 strncpy(temp, start, end-start);
248 temp[end-start] = '\0';
249 if (!strcmp(str, temp))
251 *out = count;
252 return true;
254 start = end +1;
255 count++;
257 return false;
260 bool settings_load_config(const char* file, bool apply)
262 int fd;
263 char line[128];
264 char* name;
265 char* value;
266 int i;
267 fd = open(file, O_RDONLY);
268 if (fd < 0)
269 return false;
271 while (read_line(fd, line, sizeof line) > 0)
273 if (!settings_parseline(line, &name, &value))
274 continue;
275 for(i=0; i<nb_settings; i++)
277 if (settings[i].cfg_name == NULL)
278 continue;
279 if (!strcasecmp(name,settings[i].cfg_name))
281 switch (settings[i].flags&F_T_MASK)
283 case F_T_INT:
284 case F_T_UINT:
285 #ifdef HAVE_LCD_COLOR
286 if (settings[i].flags&F_RGB)
287 hex_to_rgb(value, (int*)settings[i].setting);
288 else
289 #endif
290 if (settings[i].cfg_vals == NULL)
292 *(int*)settings[i].setting = atoi(value);
294 else
296 int temp, *v = (int*)settings[i].setting;
297 bool found = cfg_string_to_int(i, &temp, value);
298 if (found)
300 if (settings[i].flags&F_TABLE_SETTING)
301 *v = settings[i].table_setting->values[temp];
302 else
303 *v = temp;
305 else
306 *v = atoi(value);
308 break;
309 case F_T_BOOL:
311 int temp;
312 if (cfg_string_to_int(i,&temp,value))
313 *(bool*)settings[i].setting = (temp==0?false:true);
314 break;
316 case F_T_CHARPTR:
317 case F_T_UCHARPTR:
319 char storage[MAX_PATH];
320 if (settings[i].filename_setting->prefix)
322 int len = strlen(settings[i].filename_setting->prefix);
323 if (!strncasecmp(value,
324 settings[i].filename_setting->prefix,
325 len))
327 strncpy(storage,&value[len],MAX_PATH);
329 else strncpy(storage,value,MAX_PATH);
331 else strncpy(storage,value,MAX_PATH);
332 if (settings[i].filename_setting->suffix)
334 char *s = strcasestr(storage,settings[i].filename_setting->suffix);
335 if (s) *s = '\0';
337 strncpy((char*)settings[i].setting,storage,
338 settings[i].filename_setting->max_len);
339 ((char*)settings[i].setting)
340 [settings[i].filename_setting->max_len-1] = '\0';
341 break;
344 break;
345 } /* if (!strcmp(name,settings[i].cfg_name)) */
346 } /* for(...) */
347 } /* while(...) */
349 close(fd);
350 settings_save();
351 if (apply)
352 settings_apply(true);
353 return true;
356 /** Writing to a config file and saving settings **/
358 bool cfg_int_to_string(int setting_id, int val, char* buf, int buf_len)
360 int flags = settings[setting_id].flags;
361 const char* start = settings[setting_id].cfg_vals;
362 char* end = NULL;
363 int count = 0;
365 if ((flags&F_T_MASK)==F_T_INT &&
366 flags&F_TABLE_SETTING)
368 const int *value = settings[setting_id].table_setting->values;
369 while (start)
371 end = strchr(start,',');
372 if (value[count] == val)
374 if (end == NULL)
375 strncpy(buf, start, buf_len);
376 else
378 int len = (buf_len > (end-start))? end-start: buf_len;
379 strncpy(buf, start, len);
380 buf[len] = '\0';
382 return true;
384 count++;
386 if (end)
387 start = end+1;
388 else
389 break;
391 return false;
394 while (count < val)
396 start = strchr(start,',');
397 if (!start)
398 return false;
399 count++;
400 start++;
402 end = strchr(start,',');
403 if (end == NULL)
404 strncpy(buf, start, buf_len);
405 else
407 int len = (buf_len > (end-start))? end-start: buf_len;
408 strncpy(buf, start, len);
409 buf[len] = '\0';
411 return true;
415 static bool is_changed(int setting_id)
417 const struct settings_list *setting = &settings[setting_id];
418 switch (setting->flags&F_T_MASK)
420 case F_T_INT:
421 case F_T_UINT:
422 if (setting->flags&F_DEF_ISFUNC)
424 if (*(int*)setting->setting == setting->default_val.func())
425 return false;
427 else if (setting->flags&F_T_SOUND)
429 if (*(int*)setting->setting ==
430 sound_default(setting->sound_setting->setting))
431 return false;
433 else if (*(int*)setting->setting == setting->default_val.int_)
434 return false;
435 break;
436 case F_T_BOOL:
437 if (*(bool*)setting->setting == setting->default_val.bool_)
438 return false;
439 break;
440 case F_T_CHARPTR:
441 case F_T_UCHARPTR:
442 if (!strcmp((char*)setting->setting, setting->default_val.charptr))
443 return false;
444 break;
446 return true;
449 static bool settings_write_config(const char* filename, int options)
451 int i;
452 int fd;
453 char value[MAX_PATH];
454 fd = open(filename,O_CREAT|O_TRUNC|O_WRONLY);
455 if (fd < 0)
456 return false;
457 #if CONFIG_TUNER
458 bool statusbar = global_settings.statusbar;
459 if (global_status.statusbar_forced != 0 && statusbar)
460 global_settings.statusbar = false;
461 #endif
462 fdprintf(fd, "# .cfg file created by rockbox %s - "
463 "http://www.rockbox.org\r\n\r\n", appsversion);
464 for(i=0; i<nb_settings; i++)
466 if (settings[i].cfg_name == NULL)
467 continue;
468 value[0] = '\0';
470 switch (options)
472 case SETTINGS_SAVE_CHANGED:
473 if (!is_changed(i))
474 continue;
475 break;
476 case SETTINGS_SAVE_SOUND:
477 if ((settings[i].flags&F_SOUNDSETTING) == 0)
478 continue;
479 break;
480 case SETTINGS_SAVE_THEME:
481 if ((settings[i].flags&F_THEMESETTING) == 0)
482 continue;
483 break;
484 #ifdef HAVE_RECORDING
485 case SETTINGS_SAVE_RECPRESETS:
486 if ((settings[i].flags&F_RECSETTING) == 0)
487 continue;
488 break;
489 #endif
490 #if CONFIG_CODEC == SWCODEC
491 case SETTINGS_SAVE_EQPRESET:
492 if ((settings[i].flags&F_EQSETTING) == 0)
493 continue;
494 break;
495 #endif
497 switch (settings[i].flags&F_T_MASK)
499 case F_T_INT:
500 case F_T_UINT:
501 #ifdef HAVE_LCD_COLOR
502 if (settings[i].flags&F_RGB)
504 int colour = *(int*)settings[i].setting;
505 snprintf(value,MAX_PATH,"%02x%02x%02x",
506 (int)RGB_UNPACK_RED(colour),
507 (int)RGB_UNPACK_GREEN(colour),
508 (int)RGB_UNPACK_BLUE(colour));
510 else
511 #endif
512 if (settings[i].cfg_vals == NULL)
514 snprintf(value,MAX_PATH,"%d",*(int*)settings[i].setting);
516 else
518 if (cfg_int_to_string(i, *(int*)settings[i].setting,
519 value, MAX_PATH) == false)
521 snprintf(value,MAX_PATH,"%d",*(int*)settings[i].setting);
524 break;
525 case F_T_BOOL:
526 cfg_int_to_string(i,
527 *(bool*)settings[i].setting==false?0:1, value, MAX_PATH);
528 break;
529 case F_T_CHARPTR:
530 case F_T_UCHARPTR:
531 if (((char*)settings[i].setting)[0]
532 && settings[i].filename_setting->prefix)
534 snprintf(value,MAX_PATH,"%s%s%s",
535 settings[i].filename_setting->prefix,
536 (char*)settings[i].setting,
537 settings[i].filename_setting->suffix);
539 else strncpy(value,(char*)settings[i].setting,
540 settings[i].filename_setting->max_len);
541 break;
542 } /* switch () */
543 fdprintf(fd,"%s: %s\r\n",settings[i].cfg_name,value);
544 } /* for(...) */
545 close(fd);
546 #if CONFIG_TUNER
547 global_settings.statusbar = statusbar;
548 #endif
549 return true;
551 #ifndef HAVE_RTC_RAM
552 static bool flush_global_status_callback(void)
554 return write_nvram_data(nvram_buffer,NVRAM_BLOCK_SIZE);
556 #endif
557 static bool flush_config_block_callback(void)
559 bool r1, r2;
560 r1 = write_nvram_data(nvram_buffer,NVRAM_BLOCK_SIZE);
561 r2 = settings_write_config(CONFIGFILE, SETTINGS_SAVE_CHANGED);
562 return r1 || r2;
566 * persist all runtime user settings to disk or RTC RAM
568 static void update_runtime(void)
570 int elapsed_secs;
572 elapsed_secs = (current_tick - lasttime) / HZ;
573 global_status.runtime += elapsed_secs;
574 lasttime += (elapsed_secs * HZ);
576 if ( global_status.runtime > global_status.topruntime )
577 global_status.topruntime = global_status.runtime;
580 void status_save(void)
582 update_runtime();
583 #ifdef HAVE_RTC_RAM
584 /* this will be done in the ata_callback if
585 target doesnt have rtc ram */
586 write_nvram_data(nvram_buffer,NVRAM_BLOCK_SIZE);
587 #else
588 register_ata_idle_func(flush_global_status_callback);
589 #endif
592 int settings_save(void)
594 update_runtime();
595 #ifdef HAVE_RTC_RAM
596 /* this will be done in the ata_callback if
597 target doesnt have rtc ram */
598 write_nvram_data(nvram_buffer,NVRAM_BLOCK_SIZE);
599 #endif
600 register_ata_idle_func(flush_config_block_callback);
601 return 0;
604 bool settings_save_config(int options)
606 char filename[MAX_PATH];
607 char *folder;
608 switch (options)
610 case SETTINGS_SAVE_THEME:
611 folder = THEME_DIR;
612 break;
613 #ifdef HAVE_RECORDING
614 case SETTINGS_SAVE_RECPRESETS:
615 folder = RECPRESETS_DIR;
616 break;
617 #endif
618 #if CONFIG_CODEC == SWCODEC
619 case SETTINGS_SAVE_EQPRESET:
620 folder = EQS_DIR;
621 break;
622 #endif
623 case SETTINGS_SAVE_SOUND:
624 default:
625 folder = ROCKBOX_DIR;
627 create_numbered_filename(filename, folder, "config", ".cfg", 2
628 IF_CNFN_NUM_(, NULL));
630 /* allow user to modify filename */
631 while (true) {
632 if (!kbd_input(filename, sizeof filename)) {
633 break;
635 else {
636 gui_syncsplash(HZ, ID2P(LANG_CANCEL));
637 return false;
641 if (settings_write_config(filename, options))
642 gui_syncsplash(HZ, ID2P(LANG_SETTINGS_SAVED));
643 else
644 gui_syncsplash(HZ, ID2P(LANG_FAILED));
645 return true;
648 /** Apply and Reset settings **/
651 #ifdef HAVE_LCD_BITMAP
653 * Applies the range infos stored in global_settings to
654 * the peak meter.
656 void settings_apply_pm_range(void)
658 int pm_min, pm_max;
660 /* depending on the scale mode (dBfs or percent) the values
661 of global_settings.peak_meter_dbfs have different meanings */
662 if (global_settings.peak_meter_dbfs)
664 /* convert to dBfs * 100 */
665 pm_min = -(((int)global_settings.peak_meter_min) * 100);
666 pm_max = -(((int)global_settings.peak_meter_max) * 100);
668 else
670 /* percent is stored directly -> no conversion */
671 pm_min = global_settings.peak_meter_min;
672 pm_max = global_settings.peak_meter_max;
675 /* apply the range */
676 peak_meter_init_range(global_settings.peak_meter_dbfs, pm_min, pm_max);
678 #endif /* HAVE_LCD_BITMAP */
680 void sound_settings_apply(void)
682 #if CONFIG_CODEC == SWCODEC
683 sound_set_dsp_callback(dsp_callback);
684 #endif
685 sound_set(SOUND_BASS, global_settings.bass);
686 sound_set(SOUND_TREBLE, global_settings.treble);
687 sound_set(SOUND_BALANCE, global_settings.balance);
688 sound_set(SOUND_VOLUME, global_settings.volume);
689 sound_set(SOUND_CHANNELS, global_settings.channel_config);
690 sound_set(SOUND_STEREO_WIDTH, global_settings.stereo_width);
691 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
692 sound_set(SOUND_LOUDNESS, global_settings.loudness);
693 sound_set(SOUND_AVC, global_settings.avc);
694 sound_set(SOUND_MDB_STRENGTH, global_settings.mdb_strength);
695 sound_set(SOUND_MDB_HARMONICS, global_settings.mdb_harmonics);
696 sound_set(SOUND_MDB_CENTER, global_settings.mdb_center);
697 sound_set(SOUND_MDB_SHAPE, global_settings.mdb_shape);
698 sound_set(SOUND_MDB_ENABLE, global_settings.mdb_enable);
699 sound_set(SOUND_SUPERBASS, global_settings.superbass);
700 #endif
702 #ifdef HAVE_WM8758
703 sound_set(SOUND_BASS_CUTOFF, global_settings.bass_cutoff);
704 sound_set(SOUND_TREBLE_CUTOFF, global_settings.treble_cutoff);
705 #endif
707 #ifdef HAVE_USB_POWER
708 #if CONFIG_CHARGING
709 usb_charging_enable(global_settings.usb_charging);
710 #endif
711 #endif
714 void settings_apply(bool read_disk)
716 char buf[64];
717 #if CONFIG_CODEC == SWCODEC
718 int i;
719 #endif
721 sound_settings_apply();
723 #ifndef HAVE_FLASH_STORAGE
724 audio_set_buffer_margin(global_settings.buffer_margin);
725 #endif
727 #ifdef HAVE_LCD_CONTRAST
728 lcd_set_contrast(global_settings.contrast);
729 #endif
730 lcd_scroll_speed(global_settings.scroll_speed);
731 #ifdef HAVE_REMOTE_LCD
732 lcd_remote_set_contrast(global_settings.remote_contrast);
733 lcd_remote_set_invert_display(global_settings.remote_invert);
734 lcd_remote_set_flip(global_settings.remote_flip_display);
735 lcd_remote_scroll_speed(global_settings.remote_scroll_speed);
736 lcd_remote_scroll_step(global_settings.remote_scroll_step);
737 lcd_remote_scroll_delay(global_settings.remote_scroll_delay);
738 lcd_remote_bidir_scroll(global_settings.remote_bidir_limit);
739 #ifdef HAVE_REMOTE_LCD_TICKING
740 lcd_remote_emireduce(global_settings.remote_reduce_ticking);
741 #endif
742 remote_backlight_set_timeout(global_settings.remote_backlight_timeout);
743 #if CONFIG_CHARGING
744 remote_backlight_set_timeout_plugged(global_settings.remote_backlight_timeout_plugged);
745 #endif
746 #ifdef HAS_REMOTE_BUTTON_HOLD
747 remote_backlight_set_on_button_hold(global_settings.remote_backlight_on_button_hold);
748 #endif
749 #endif /* HAVE_REMOTE_LCD */
750 #ifdef HAVE_BACKLIGHT_BRIGHTNESS
751 backlight_set_brightness(global_settings.brightness);
752 #endif
753 #ifdef HAVE_BACKLIGHT
754 backlight_set_timeout(global_settings.backlight_timeout);
755 #if CONFIG_CHARGING
756 backlight_set_timeout_plugged(global_settings.backlight_timeout_plugged);
757 #endif
758 #if defined(HAVE_BACKLIGHT_PWM_FADING) && !defined(SIMULATOR)
759 backlight_set_fade_in(global_settings.backlight_fade_in);
760 backlight_set_fade_out(global_settings.backlight_fade_out);
761 #endif
762 #endif
763 #ifdef HAVE_BUTTONLIGHT_BRIGHTNESS
764 buttonlight_set_brightness(global_settings.buttonlight_brightness);
765 #endif
766 #ifdef HAVE_BUTTON_LIGHT
767 buttonlight_set_timeout(global_settings.buttonlight_timeout);
768 #endif
769 #ifndef HAVE_FLASH_STORAGE
770 ata_spindown(global_settings.disk_spindown);
771 #endif
772 #if (CONFIG_CODEC == MAS3507D) && !defined(SIMULATOR)
773 dac_line_in(global_settings.line_in);
774 #endif
775 set_poweroff_timeout(global_settings.poweroff);
777 set_battery_capacity(global_settings.battery_capacity);
778 #if BATTERY_TYPES_COUNT > 1
779 set_battery_type(global_settings.battery_type);
780 #endif
782 #ifdef HAVE_LCD_BITMAP
783 lcd_set_invert_display(global_settings.invert);
784 lcd_set_flip(global_settings.flip_display);
785 button_set_flip(global_settings.flip_display);
786 lcd_update(); /* refresh after flipping the screen */
787 settings_apply_pm_range();
788 peak_meter_init_times(
789 global_settings.peak_meter_release, global_settings.peak_meter_hold,
790 global_settings.peak_meter_clip_hold);
791 #endif
793 if (read_disk)
795 #if LCD_DEPTH > 1
796 unload_wps_backdrop();
797 #endif
798 #if defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1
799 unload_remote_wps_backdrop();
800 #endif
801 if ( global_settings.wps_file[0] &&
802 global_settings.wps_file[0] != 0xff ) {
803 snprintf(buf, sizeof buf, WPS_DIR "/%s.wps",
804 global_settings.wps_file);
805 wps_data_load(gui_wps[0].data, &screens[0], buf, true);
807 else
809 wps_data_init(gui_wps[0].data);
810 #ifdef HAVE_REMOTE_LCD
811 gui_wps[0].data->remote_wps = false;
812 #endif
815 #if LCD_DEPTH > 1
816 if ( global_settings.backdrop_file[0] &&
817 global_settings.backdrop_file[0] != 0xff ) {
818 snprintf(buf, sizeof buf, BACKDROP_DIR "/%s.bmp",
819 global_settings.backdrop_file);
820 load_main_backdrop(buf);
821 } else {
822 unload_main_backdrop();
824 show_main_backdrop();
825 #endif
826 #if defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1
827 show_remote_main_backdrop();
828 #endif
830 #if defined(HAVE_REMOTE_LCD) && (NB_SCREENS > 1)
831 if ( global_settings.rwps_file[0]) {
832 snprintf(buf, sizeof buf, WPS_DIR "/%s.rwps",
833 global_settings.rwps_file);
834 wps_data_load(gui_wps[1].data, &screens[1], buf, true);
836 else
838 wps_data_init(gui_wps[1].data);
839 gui_wps[1].data->remote_wps = true;
841 #endif
843 #ifdef HAVE_LCD_BITMAP
844 if ( global_settings.font_file[0]) {
845 snprintf(buf, sizeof buf, FONT_DIR "/%s.fnt",
846 global_settings.font_file);
847 font_load(buf);
849 else
850 font_reset();
852 if ( global_settings.kbd_file[0]) {
853 snprintf(buf, sizeof buf, ROCKBOX_DIR "/%s.kbd",
854 global_settings.kbd_file);
855 load_kbd(buf);
857 else
858 load_kbd(NULL);
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
929 lcd_set_sleep_after_backlight_off(global_settings.lcd_sleep_after_backlight_off);
930 #endif
931 #endif /* HAVE_BACKLIGHT */
933 /* This should stay last */
934 #if defined(HAVE_RECORDING) && CONFIG_CODEC == SWCODEC
935 enc_global_settings_apply();
936 #endif
937 list_init_viewports(NULL);
942 * reset all settings to their default value
944 void reset_setting(const struct settings_list *setting, void *var)
946 switch (setting->flags&F_T_MASK)
948 case F_T_INT:
949 case F_T_UINT:
950 if (setting->flags&F_DEF_ISFUNC)
951 *(int*)var = setting->default_val.func();
952 else if (setting->flags&F_T_SOUND)
953 *(int*)var = sound_default(setting->sound_setting->setting);
954 else *(int*)var = setting->default_val.int_;
955 break;
956 case F_T_BOOL:
957 *(bool*)var = setting->default_val.bool_;
958 break;
959 case F_T_CHARPTR:
960 case F_T_UCHARPTR:
961 strncpy((char*)var, setting->default_val.charptr,
962 setting->filename_setting->max_len);
963 break;
967 void settings_reset(void)
969 int i;
971 for(i=0; i<nb_settings; i++)
972 reset_setting(&settings[i], settings[i].setting);
973 #if defined (HAVE_RECORDING) && CONFIG_CODEC == SWCODEC
974 enc_global_settings_reset();
975 #endif
978 /** Changing setting values **/
979 const struct settings_list* find_setting(const void* variable, int *id)
981 int i;
982 for(i=0;i<nb_settings;i++)
984 if (settings[i].setting == variable)
986 if (id)
987 *id = i;
988 return &settings[i];
991 return NULL;
994 bool set_bool(const char* string, const bool* variable )
996 return set_bool_options(string, variable,
997 (char *)STR(LANG_SET_BOOL_YES),
998 (char *)STR(LANG_SET_BOOL_NO),
999 NULL);
1003 bool set_bool_options(const char* string, const bool* variable,
1004 const char* yes_str, int yes_voice,
1005 const char* no_str, int no_voice,
1006 void (*function)(bool))
1008 struct opt_items names[] = {
1009 {(unsigned const char *)no_str, no_voice},
1010 {(unsigned const char *)yes_str, yes_voice}
1012 bool result;
1014 result = set_option(string, variable, BOOL, names, 2,
1015 (void (*)(int))function);
1016 return result;
1019 bool set_int(const unsigned char* string,
1020 const char* unit,
1021 int voice_unit,
1022 const int* variable,
1023 void (*function)(int),
1024 int step,
1025 int min,
1026 int max,
1027 void (*formatter)(char*, size_t, int, const char*) )
1029 return set_int_ex(string, unit, voice_unit, variable, function,
1030 step, min, max, formatter, NULL);
1033 bool set_int_ex(const unsigned char* string,
1034 const char* unit,
1035 int voice_unit,
1036 const int* variable,
1037 void (*function)(int),
1038 int step,
1039 int min,
1040 int max,
1041 void (*formatter)(char*, size_t, int, const char*),
1042 int32_t (*get_talk_id)(int, int))
1044 (void)unit;
1045 struct settings_list item;
1046 struct int_setting data = {
1047 function, voice_unit, min, max, step,
1048 formatter, get_talk_id
1050 item.int_setting = &data;
1051 item.flags = F_INT_SETTING|F_T_INT;
1052 item.lang_id = -1;
1053 item.cfg_vals = (char*)string;
1054 item.setting = (void *)variable;
1055 return option_screen(&item, false, NULL);
1059 static const struct opt_items *set_option_options;
1060 static void set_option_formatter(char* buf, size_t size, int item, const char* unit)
1062 (void)unit;
1063 const unsigned char *text = set_option_options[item].string;
1064 snprintf(buf, size, "%s", P2STR(text));
1066 static int32_t set_option_get_talk_id(int value, int unit)
1068 (void)unit;
1069 return set_option_options[value].voice_id;
1071 bool set_option(const char* string, const void* variable, enum optiontype type,
1072 const struct opt_items* options,
1073 int numoptions, void (*function)(int))
1075 int temp;
1076 struct settings_list item;
1077 struct int_setting data = {
1078 function, UNIT_INT, 0, numoptions-1, 1,
1079 set_option_formatter, set_option_get_talk_id
1081 set_option_options = options;
1082 item.int_setting = &data;
1083 item.flags = F_INT_SETTING|F_T_INT;
1084 item.lang_id = -1;
1085 item.cfg_vals = (char*)string;
1086 item.setting = &temp;
1087 if (type == BOOL)
1088 temp = *(bool*)variable? 1: 0;
1089 else
1090 temp = *(int*)variable;
1091 if (!option_screen(&item, false, NULL))
1093 if (type == BOOL)
1094 *(bool*)variable = (temp == 1? true: false);
1095 else
1096 *(int*)variable = temp;
1097 return false;
1099 return true;
1103 void set_file(const char* filename, char* setting, int maxlen)
1105 char* fptr = strrchr(filename,'/');
1106 int len;
1107 int extlen = 0;
1108 char* ptr;
1110 if (!fptr)
1111 return;
1113 *fptr = 0;
1114 fptr++;
1116 len = strlen(fptr);
1117 ptr = fptr + len;
1118 while ((*ptr != '.') && (ptr != fptr)) {
1119 extlen++;
1120 ptr--;
1122 if(ptr == fptr) extlen = 0;
1124 if (strncasecmp(ROCKBOX_DIR, filename ,strlen(ROCKBOX_DIR)) ||
1125 (len-extlen > maxlen))
1126 return;
1128 strncpy(setting, fptr, len-extlen);
1129 setting[len-extlen]=0;
1131 settings_save();