1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
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 ****************************************************************************/
31 #include "backlight.h"
38 #include "ata_idle_notify.h"
45 #ifdef HAVE_LCD_BITMAP
48 #include "peakmeter.h"
53 #include "powermgmt.h"
58 #include "rbunicode.h"
60 #include "statusbar.h"
63 #include "settings_list.h"
64 #include "filetypes.h"
66 #if (LCD_DEPTH > 1) || (defined(HAVE_LCD_REMOTE) && (LCD_REMOTE_DEPTH > 1))
74 #if CONFIG_CODEC == MAS3507D
75 void dac_line_in(bool enable
);
77 struct user_settings global_settings
;
78 struct system_status global_status
;
81 const char rec_base_directory
[] = REC_BASE_DIR
;
83 #if CONFIG_CODEC == SWCODEC
85 #include "pcm_playback.h"
88 #include "enc_config.h"
90 #endif /* CONFIG_CODEC == SWCODEC */
92 #define NVRAM_BLOCK_SIZE 44
94 #ifdef HAVE_LCD_BITMAP
100 #ifdef HAVE_REMOTE_LCD
101 #include "lcd-remote.h"
106 /** NVRAM stuff, if the target doesnt have NVRAM it is saved in ROCKBOX_DIR /nvram.bin **/
107 /* NVRAM is set out as
111 [3] stored variable count
113 [8-NVRAM_BLOCK_SIZE] data
115 #define NVRAM_DATA_START 8
116 #define NVRAM_FILE ROCKBOX_DIR "/nvram.bin"
117 static char nvram_buffer
[NVRAM_BLOCK_SIZE
];
119 static bool read_nvram_data(char* buf
, int max_len
)
121 unsigned crc32
= 0xffffffff;
122 int var_count
= 0, i
= 0, buf_pos
= 0;
124 int fd
= open(NVRAM_FILE
,O_RDONLY
);
127 memset(buf
,0,max_len
);
128 if (read(fd
,buf
,max_len
) < 8) /* min is 8 bytes,magic, ver, vars, crc32 */
132 memset(buf
,0,max_len
);
134 for (i
=0; i
< max_len
; i
++ )
135 buf
[i
] = rtc_read(0x14+i
);
137 /* check magic, version */
138 if ((buf
[0] != 'R') || (buf
[1] != 'b')
139 || (buf
[2] != NVRAM_CONFIG_VERSION
))
142 crc32
= crc_32(&buf
[NVRAM_DATA_START
],
143 max_len
-NVRAM_DATA_START
-1,0xffffffff);
144 if (memcmp(&crc32
,&buf
[4],4))
146 /* all good, so read in the settings */
148 buf_pos
= NVRAM_DATA_START
;
149 for(i
=0; (i
<nb_settings
) && (var_count
>0) && (buf_pos
<max_len
); i
++)
151 int nvram_bytes
= (settings
[i
].flags
&F_NVRAM_BYTES_MASK
)
152 >>F_NVRAM_MASK_SHIFT
;
155 memcpy(settings
[i
].setting
,&buf
[buf_pos
],nvram_bytes
);
156 buf_pos
+= nvram_bytes
;
162 static bool write_nvram_data(char* buf
, int max_len
)
164 unsigned crc32
= 0xffffffff;
165 int i
= 0, buf_pos
= 0;
170 memset(buf
,0,max_len
);
172 buf
[0] = 'R'; buf
[1] = 'b';
173 buf
[2] = NVRAM_CONFIG_VERSION
;
174 buf_pos
= NVRAM_DATA_START
;
175 for(i
=0; (i
<nb_settings
) && (buf_pos
<max_len
); i
++)
177 int nvram_bytes
= (settings
[i
].flags
&F_NVRAM_BYTES_MASK
)
178 >>F_NVRAM_MASK_SHIFT
;
181 memcpy(&buf
[buf_pos
],settings
[i
].setting
,nvram_bytes
);
182 buf_pos
+= nvram_bytes
;
186 /* count and crc32 */
188 crc32
= crc_32(&buf
[NVRAM_DATA_START
],
189 max_len
-NVRAM_DATA_START
-1,0xffffffff);
190 memcpy(&buf
[4],&crc32
,4);
192 fd
= open(NVRAM_FILE
,O_CREAT
|O_TRUNC
|O_WRONLY
);
195 int len
= write(fd
,buf
,max_len
);
201 /* FIXME: okay, it _would_ be cleaner and faster to implement rtc_write so
202 that it would write a number of bytes at a time since the RTC chip
203 supports that, but this will have to do for now 8-) */
204 for (i
=0; i
< NVRAM_BLOCK_SIZE
; i
++ ) {
205 int r
= rtc_write(0x14+i
, buf
[i
]);
207 DEBUGF( "save_config_buffer: rtc_write failed at addr 0x%02x: %d\n",
216 /** Reading from a config file **/
218 * load settings from disk or RTC RAM
220 void settings_load(int which
)
222 DEBUGF( "reload_all_settings()\n" );
223 if (which
&SETTINGS_RTC
)
224 read_nvram_data(nvram_buffer
,NVRAM_BLOCK_SIZE
);
225 if (which
&SETTINGS_HD
)
227 settings_load_config(CONFIGFILE
,false);
228 settings_load_config(FIXEDSETTINGSFILE
,false);
232 static bool cfg_string_to_int(int setting_id
, int* out
, char* str
)
234 const char* start
= settings
[setting_id
].cfg_vals
;
240 end
= strchr(start
, ',');
243 if (!strcmp(str
, start
))
250 strncpy(temp
, start
, end
-start
);
251 temp
[end
-start
] = '\0';
252 if (!strcmp(str
, temp
))
263 bool settings_load_config(const char* file
, bool apply
)
270 fd
= open(file
, O_RDONLY
);
274 while (read_line(fd
, line
, sizeof line
) > 0)
276 if (!settings_parseline(line
, &name
, &value
))
278 for(i
=0; i
<nb_settings
; i
++)
280 if (settings
[i
].cfg_name
== NULL
)
282 if (!strcasecmp(name
,settings
[i
].cfg_name
))
284 switch (settings
[i
].flags
&F_T_MASK
)
288 #ifdef HAVE_LCD_COLOR
289 if (settings
[i
].flags
&F_RGB
)
290 *(int*)settings
[i
].setting
= hex_to_rgb(value
);
293 if (settings
[i
].cfg_vals
== NULL
)
295 *(int*)settings
[i
].setting
= atoi(value
);
299 cfg_string_to_int(i
,(int*)settings
[i
].setting
,value
);
305 if (cfg_string_to_int(i
,&temp
,value
))
306 *(bool*)settings
[i
].setting
= (temp
==0?false:true);
312 char storage
[MAX_PATH
];
313 if (settings
[i
].filename_setting
->prefix
)
315 int len
= strlen(settings
[i
].filename_setting
->prefix
);
316 if (!strncasecmp(value
,
317 settings
[i
].filename_setting
->prefix
,
320 strncpy(storage
,&value
[len
],MAX_PATH
);
322 else strncpy(storage
,value
,MAX_PATH
);
324 else strncpy(storage
,value
,MAX_PATH
);
325 if (settings
[i
].filename_setting
->suffix
)
327 char *s
= strcasestr(storage
,settings
[i
].filename_setting
->suffix
);
330 strncpy((char*)settings
[i
].setting
,storage
,
331 settings
[i
].filename_setting
->max_len
);
332 ((char*)settings
[i
].setting
)
333 [settings
[i
].filename_setting
->max_len
-1] = '\0';
338 } /* if (!strcmp(name,settings[i].cfg_name)) */
349 /** Writing to a config file and saving settings **/
351 bool cfg_int_to_string(int setting_id
, int val
, char* buf
, int buf_len
)
353 const char* start
= settings
[setting_id
].cfg_vals
;
358 start
= strchr(start
,',');
364 end
= strchr(start
,',');
366 strncpy(buf
, start
, buf_len
);
369 int len
= (buf_len
> (end
-start
))? end
-start
: buf_len
;
370 strncpy(buf
, start
, len
);
375 static bool is_changed(int setting_id
)
377 const struct settings_list
*setting
= &settings
[setting_id
];
378 switch (setting
->flags
&F_T_MASK
)
382 if (setting
->flags
&F_DEF_ISFUNC
)
384 if (*(int*)setting
->setting
== setting
->default_val
.func())
387 else if (setting
->flags
&F_T_SOUND
)
389 if (*(int*)setting
->setting
==
390 sound_default(setting
->sound_setting
->setting
))
393 else if (*(int*)setting
->setting
== setting
->default_val
.int_
)
397 if (*(bool*)setting
->setting
== setting
->default_val
.bool_
)
402 if (!strcmp((char*)setting
->setting
, setting
->default_val
.charptr
))
409 static bool settings_write_config(char* filename
, int options
)
413 char value
[MAX_PATH
];
414 fd
= open(filename
,O_CREAT
|O_TRUNC
|O_WRONLY
);
417 fdprintf(fd
, "# .cfg file created by rockbox %s - "
418 "http://www.rockbox.org\r\n\r\n", appsversion
);
419 for(i
=0; i
<nb_settings
; i
++)
421 if (settings
[i
].cfg_name
== NULL
)
425 if ((options
== SETTINGS_SAVE_CHANGED
) &&
428 else if ((options
== SETTINGS_SAVE_THEME
) &&
429 ((settings
[i
].flags
&F_THEMESETTING
) == 0))
431 #ifdef HAVE_RECORDING
432 else if ((options
== SETTINGS_SAVE_RECPRESETS
) &&
433 ((settings
[i
].flags
&F_RECSETTING
) == 0))
436 switch (settings
[i
].flags
&F_T_MASK
)
440 #ifdef HAVE_LCD_COLOR
441 if (settings
[i
].flags
&F_RGB
)
443 int colour
= *(int*)settings
[i
].setting
;
444 snprintf(value
,MAX_PATH
,"%02x%02x%02x",
445 (int)RGB_UNPACK_RED(colour
),
446 (int)RGB_UNPACK_GREEN(colour
),
447 (int)RGB_UNPACK_BLUE(colour
));
451 if (settings
[i
].cfg_vals
== NULL
)
453 snprintf(value
,MAX_PATH
,"%d",*(int*)settings
[i
].setting
);
457 cfg_int_to_string(i
, *(int*)settings
[i
].setting
,
463 *(bool*)settings
[i
].setting
==false?0:1, value
, MAX_PATH
);
467 if (((char*)settings
[i
].setting
)[0] == '\0')
469 if (settings
[i
].filename_setting
->prefix
)
471 snprintf(value
,MAX_PATH
,"%s%s%s",
472 settings
[i
].filename_setting
->prefix
,
473 (char*)settings
[i
].setting
,
474 settings
[i
].filename_setting
->suffix
);
476 else strncpy(value
,(char*)settings
[i
].setting
,
477 settings
[i
].filename_setting
->max_len
);
481 fdprintf(fd
,"%s: %s\r\n",settings
[i
].cfg_name
,value
);
487 static bool flush_global_status_callback(void)
489 return write_nvram_data(nvram_buffer
,NVRAM_BLOCK_SIZE
);
492 static bool flush_config_block_callback(void)
495 r1
= write_nvram_data(nvram_buffer
,NVRAM_BLOCK_SIZE
);
496 r2
= settings_write_config(CONFIGFILE
, SETTINGS_SAVE_CHANGED
);
501 * persist all runtime user settings to disk or RTC RAM
503 static void update_runtime(void)
507 elapsed_secs
= (current_tick
- lasttime
) / HZ
;
508 global_status
.runtime
+= elapsed_secs
;
509 lasttime
+= (elapsed_secs
* HZ
);
511 if ( global_status
.runtime
> global_status
.topruntime
)
512 global_status
.topruntime
= global_status
.runtime
;
515 void status_save( void )
519 /* this will be done in the ata_callback if
520 target doesnt have rtc ram */
521 write_nvram_data(nvram_buffer
,NVRAM_BLOCK_SIZE
);
523 register_ata_idle_func(flush_global_status_callback
);
527 int settings_save( void )
531 /* this will be done in the ata_callback if
532 target doesnt have rtc ram */
533 write_nvram_data(nvram_buffer
,NVRAM_BLOCK_SIZE
);
535 if(!register_ata_idle_func(flush_config_block_callback
))
540 screens
[i
].clear_display();
541 #ifdef HAVE_LCD_CHARCELLS
542 screens
[i
].puts(0, 0, str(LANG_SETTINGS_SAVE_PLAYER
));
543 screens
[i
].puts(0, 1, str(LANG_SETTINGS_BATTERY_PLAYER
));
545 screens
[i
].puts(4, 2, str(LANG_SETTINGS_SAVE_RECORDER
));
546 screens
[i
].puts(2, 4, str(LANG_SETTINGS_BATTERY_RECORDER
));
555 bool settings_save_config(int options
)
557 char filename
[MAX_PATH
];
561 case SETTINGS_SAVE_THEME
:
564 #ifdef HAVE_RECORDING
565 case SETTINGS_SAVE_RECPRESETS
:
566 folder
= RECPRESETS_DIR
;
570 folder
= ROCKBOX_DIR
;
572 create_numbered_filename(filename
, folder
, "config", ".cfg", 2
573 IF_CNFN_NUM_(, NULL
));
575 /* allow user to modify filename */
577 if (!kbd_input(filename
, sizeof filename
)) {
581 gui_syncsplash(HZ
, str(LANG_MENU_SETTING_CANCEL
));
586 if (settings_write_config(filename
, options
))
587 gui_syncsplash(HZ
, str(LANG_SETTINGS_SAVED
));
589 gui_syncsplash(HZ
, str(LANG_FAILED
));
593 /** Apply and Reset settings **/
596 #ifdef HAVE_LCD_BITMAP
598 * Applies the range infos stored in global_settings to
601 void settings_apply_pm_range(void)
605 /* depending on the scale mode (dBfs or percent) the values
606 of global_settings.peak_meter_dbfs have different meanings */
607 if (global_settings
.peak_meter_dbfs
)
609 /* convert to dBfs * 100 */
610 pm_min
= -(((int)global_settings
.peak_meter_min
) * 100);
611 pm_max
= -(((int)global_settings
.peak_meter_max
) * 100);
615 /* percent is stored directly -> no conversion */
616 pm_min
= global_settings
.peak_meter_min
;
617 pm_max
= global_settings
.peak_meter_max
;
620 /* apply the range */
621 peak_meter_init_range(global_settings
.peak_meter_dbfs
, pm_min
, pm_max
);
623 #endif /* HAVE_LCD_BITMAP */
625 void sound_settings_apply(void)
627 #if CONFIG_CODEC == SWCODEC
628 sound_set_dsp_callback(dsp_callback
);
630 sound_set(SOUND_BASS
, global_settings
.bass
);
631 sound_set(SOUND_TREBLE
, global_settings
.treble
);
632 sound_set(SOUND_BALANCE
, global_settings
.balance
);
633 sound_set(SOUND_VOLUME
, global_settings
.volume
);
634 sound_set(SOUND_CHANNELS
, global_settings
.channel_config
);
635 sound_set(SOUND_STEREO_WIDTH
, global_settings
.stereo_width
);
636 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
637 sound_set(SOUND_LOUDNESS
, global_settings
.loudness
);
638 sound_set(SOUND_AVC
, global_settings
.avc
);
639 sound_set(SOUND_MDB_STRENGTH
, global_settings
.mdb_strength
);
640 sound_set(SOUND_MDB_HARMONICS
, global_settings
.mdb_harmonics
);
641 sound_set(SOUND_MDB_CENTER
, global_settings
.mdb_center
);
642 sound_set(SOUND_MDB_SHAPE
, global_settings
.mdb_shape
);
643 sound_set(SOUND_MDB_ENABLE
, global_settings
.mdb_enable
);
644 sound_set(SOUND_SUPERBASS
, global_settings
.superbass
);
647 #ifdef HAVE_USB_POWER
649 usb_charging_enable(global_settings
.usb_charging
);
654 void settings_apply(void)
657 #if CONFIG_CODEC == SWCODEC
661 DEBUGF( "settings_apply()\n" );
662 sound_settings_apply();
664 audio_set_buffer_margin(global_settings
.buffer_margin
);
666 #ifdef HAVE_LCD_CONTRAST
667 lcd_set_contrast(global_settings
.contrast
);
669 lcd_scroll_speed(global_settings
.scroll_speed
);
670 #ifdef HAVE_REMOTE_LCD
671 lcd_remote_set_contrast(global_settings
.remote_contrast
);
672 lcd_remote_set_invert_display(global_settings
.remote_invert
);
673 lcd_remote_set_flip(global_settings
.remote_flip_display
);
674 lcd_remote_scroll_speed(global_settings
.remote_scroll_speed
);
675 lcd_remote_scroll_step(global_settings
.remote_scroll_step
);
676 lcd_remote_scroll_delay(global_settings
.remote_scroll_delay
);
677 lcd_remote_bidir_scroll(global_settings
.remote_bidir_limit
);
678 #ifdef HAVE_REMOTE_LCD_TICKING
679 lcd_remote_emireduce(global_settings
.remote_reduce_ticking
);
681 remote_backlight_set_timeout(global_settings
.remote_backlight_timeout
);
683 remote_backlight_set_timeout_plugged(global_settings
.remote_backlight_timeout_plugged
);
685 #ifdef HAS_REMOTE_BUTTON_HOLD
686 remote_backlight_set_on_button_hold(global_settings
.remote_backlight_on_button_hold
);
688 #endif /* HAVE_REMOTE_LCD */
689 #ifdef HAVE_BACKLIGHT_BRIGHTNESS
690 backlight_set_brightness(global_settings
.brightness
);
692 #ifdef HAVE_BACKLIGHT
693 backlight_set_timeout(global_settings
.backlight_timeout
);
695 backlight_set_timeout_plugged(global_settings
.backlight_timeout_plugged
);
697 #if defined(HAVE_BACKLIGHT_PWM_FADING) && !defined(SIMULATOR)
698 backlight_set_fade_in(global_settings
.backlight_fade_in
);
699 backlight_set_fade_out(global_settings
.backlight_fade_out
);
702 #ifdef HAVE_BUTTONLIGHT_BRIGHTNESS
703 buttonlight_set_brightness(global_settings
.buttonlight_brightness
);
705 #ifdef HAVE_BUTTON_LIGHT
706 button_backlight_set_timeout(global_settings
.button_light_timeout
);
708 ata_spindown(global_settings
.disk_spindown
);
709 #if (CONFIG_CODEC == MAS3507D) && !defined(SIMULATOR)
710 dac_line_in(global_settings
.line_in
);
712 mpeg_id3_options(global_settings
.id3_v1_first
);
714 set_poweroff_timeout(global_settings
.poweroff
);
716 set_battery_capacity(global_settings
.battery_capacity
);
717 #if BATTERY_TYPES_COUNT > 1
718 set_battery_type(global_settings
.battery_type
);
721 #ifdef HAVE_LCD_BITMAP
722 lcd_set_invert_display(global_settings
.invert
);
723 lcd_set_flip(global_settings
.flip_display
);
724 button_set_flip(global_settings
.flip_display
);
725 lcd_update(); /* refresh after flipping the screen */
726 settings_apply_pm_range();
727 peak_meter_init_times(
728 global_settings
.peak_meter_release
, global_settings
.peak_meter_hold
,
729 global_settings
.peak_meter_clip_hold
);
733 unload_wps_backdrop();
735 #if defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1
736 unload_remote_wps_backdrop();
738 if ( global_settings
.wps_file
[0] &&
739 global_settings
.wps_file
[0] != 0xff ) {
740 snprintf(buf
, sizeof buf
, WPS_DIR
"/%s.wps",
741 global_settings
.wps_file
);
742 wps_data_load(gui_wps
[0].data
, buf
, true);
746 wps_data_init(gui_wps
[0].data
);
747 #ifdef HAVE_REMOTE_LCD
748 gui_wps
[0].data
->remote_wps
= false;
753 if ( global_settings
.backdrop_file
[0] &&
754 global_settings
.backdrop_file
[0] != 0xff ) {
755 snprintf(buf
, sizeof buf
, BACKDROP_DIR
"/%s.bmp",
756 global_settings
.backdrop_file
);
757 load_main_backdrop(buf
);
759 unload_main_backdrop();
761 show_main_backdrop();
763 #if defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1
764 show_remote_main_backdrop();
767 #ifdef HAVE_LCD_COLOR
768 screens
[SCREEN_MAIN
].set_foreground(global_settings
.fg_color
);
769 screens
[SCREEN_MAIN
].set_background(global_settings
.bg_color
);
772 #if defined(HAVE_REMOTE_LCD) && (NB_SCREENS > 1)
773 if ( global_settings
.rwps_file
[0]) {
774 snprintf(buf
, sizeof buf
, WPS_DIR
"/%s.rwps",
775 global_settings
.rwps_file
);
776 wps_data_load(gui_wps
[1].data
, buf
, true);
780 wps_data_init(gui_wps
[1].data
);
781 gui_wps
[1].data
->remote_wps
= true;
785 #ifdef HAVE_LCD_BITMAP
786 if ( global_settings
.font_file
[0]) {
787 snprintf(buf
, sizeof buf
, FONT_DIR
"/%s.fnt",
788 global_settings
.font_file
);
794 if ( global_settings
.kbd_file
[0]) {
795 snprintf(buf
, sizeof buf
, ROCKBOX_DIR
"/%s.kbd",
796 global_settings
.kbd_file
);
802 lcd_scroll_step(global_settings
.scroll_step
);
803 gui_list_screen_scroll_step(global_settings
.screen_scroll_step
);
804 gui_list_screen_scroll_out_of_view(global_settings
.offset_out_of_view
);
806 lcd_jump_scroll(global_settings
.jump_scroll
);
807 lcd_jump_scroll_delay(global_settings
.jump_scroll_delay
);
809 lcd_bidir_scroll(global_settings
.bidir_limit
);
810 lcd_scroll_delay(global_settings
.scroll_delay
);
812 if ( global_settings
.lang_file
[0]) {
813 snprintf(buf
, sizeof buf
, LANG_DIR
"/%s.lng",
814 global_settings
.lang_file
);
816 talk_init(); /* use voice of same language */
819 set_codepage(global_settings
.default_codepage
);
821 #if CONFIG_CODEC == SWCODEC
822 audio_set_crossfade(global_settings
.crossfade
);
823 dsp_set_replaygain();
824 dsp_set_crossfeed(global_settings
.crossfeed
);
825 dsp_set_crossfeed_direct_gain(global_settings
.crossfeed_direct_gain
);
826 dsp_set_crossfeed_cross_params(global_settings
.crossfeed_cross_gain
,
827 global_settings
.crossfeed_hf_attenuation
,
828 global_settings
.crossfeed_hf_cutoff
);
830 /* Configure software equalizer, hardware eq is handled in audio_init() */
831 dsp_set_eq(global_settings
.eq_enabled
);
832 dsp_set_eq_precut(global_settings
.eq_precut
);
833 for(i
= 0; i
< 5; i
++) {
837 dsp_dither_enable(global_settings
.dithering_enabled
);
840 #ifdef HAVE_SPDIF_POWER
841 spdif_power_enable(global_settings
.spdif_enable
);
844 #ifdef HAVE_BACKLIGHT
845 set_backlight_filter_keypress(global_settings
.bl_filter_first_keypress
);
846 #ifdef HAVE_REMOTE_LCD
847 set_remote_backlight_filter_keypress(global_settings
.remote_bl_filter_first_keypress
);
849 #ifdef HAS_BUTTON_HOLD
850 backlight_set_on_button_hold(global_settings
.backlight_on_button_hold
);
852 #ifdef HAVE_LCD_SLEEP
853 lcd_set_sleep_after_backlight_off(global_settings
.lcd_sleep_after_backlight_off
);
855 #endif /* HAVE_BACKLIGHT */
857 /* This should stay last */
858 #if defined(HAVE_RECORDING) && CONFIG_CODEC == SWCODEC
859 enc_global_settings_apply();
861 /* load the icon set */
864 #ifdef HAVE_LCD_COLOR
865 if (global_settings
.colors_file
)
866 read_color_theme_file();
875 * reset all settings to their default value
877 void settings_reset(void) {
880 DEBUGF( "settings_reset()\n" );
882 for(i
=0; i
<nb_settings
; i
++)
884 switch (settings
[i
].flags
&F_T_MASK
)
888 if (settings
[i
].flags
&F_DEF_ISFUNC
)
889 *(int*)settings
[i
].setting
= settings
[i
].default_val
.func();
890 else if (settings
[i
].flags
&F_T_SOUND
)
891 *(int*)settings
[i
].setting
=
892 sound_default(settings
[i
].sound_setting
->setting
);
893 else *(int*)settings
[i
].setting
= settings
[i
].default_val
.int_
;
896 *(bool*)settings
[i
].setting
= settings
[i
].default_val
.bool_
;
900 strncpy((char*)settings
[i
].setting
,
901 settings
[i
].default_val
.charptr
,MAX_FILENAME
);
905 #if defined (HAVE_RECORDING) && CONFIG_CODEC == SWCODEC
906 enc_global_settings_reset();
910 /** Changing setting values **/
911 const struct settings_list
* find_setting(void* variable
, int *id
)
914 for(i
=0;i
<nb_settings
;i
++)
916 if (settings
[i
].setting
== variable
)
926 void talk_setting(void *global_settings_variable
)
928 const struct settings_list
*setting
;
929 if (!talk_menus_enabled())
931 setting
= find_setting(global_settings_variable
, NULL
);
934 if (setting
->lang_id
)
935 talk_id(setting
->lang_id
,false);
938 static int selected_setting
; /* Used by the callback */
940 static void dec_sound_formatter(char *buffer
, int buffer_size
,
941 int val
, const char *unit
)
943 val
= sound_val2phys(selected_setting
, val
);
950 int integer
= val
/ 10;
952 snprintf(buffer
, buffer_size
, "%c%d.%d %s", sign
, integer
, dec
, unit
);
955 bool set_sound(const unsigned char * string
,
959 int talkunit
= UNIT_INT
;
960 const char* unit
= sound_unit(setting
);
961 int numdec
= sound_numdecimals(setting
);
962 int steps
= sound_steps(setting
);
963 int min
= sound_min(setting
);
964 int max
= sound_max(setting
);
965 sound_set_type
* sound_callback
= sound_get_fn(setting
);
966 if (*unit
== 'd') /* crude reconstruction */
968 else if (*unit
== '%')
969 talkunit
= UNIT_PERCENT
;
970 else if (*unit
== 'H')
971 talkunit
= UNIT_HERTZ
;
973 return set_int(string
, unit
, talkunit
, variable
, sound_callback
,
974 steps
, min
, max
, NULL
);
976 {/* Decimal number */
977 selected_setting
=setting
;
978 return set_int(string
, unit
, talkunit
, variable
, sound_callback
,
979 steps
, min
, max
, &dec_sound_formatter
);
983 bool set_bool(const char* string
, bool* variable
)
985 return set_bool_options(string
, variable
,
986 (char *)STR(LANG_SET_BOOL_YES
),
987 (char *)STR(LANG_SET_BOOL_NO
),
991 /* wrapper to convert from int param to bool param in set_option */
992 static void (*boolfunction
)(bool);
993 static void bool_funcwrapper(int value
)
1001 bool set_bool_options(const char* string
, bool* variable
,
1002 const char* yes_str
, int yes_voice
,
1003 const char* no_str
, int no_voice
,
1004 void (*function
)(bool))
1006 struct opt_items names
[] = {
1007 {(unsigned char *)no_str
, no_voice
},
1008 {(unsigned char *)yes_str
, yes_voice
}
1012 boolfunction
= function
;
1013 result
= set_option(string
, variable
, BOOL
, names
, 2,
1014 function
? bool_funcwrapper
: NULL
);
1018 static void talk_unit(int unit
, int value
, long (*get_talk_id
)(int value
))
1020 if (talk_menus_enabled())
1024 talk_id(get_talk_id(value
),false);
1026 else if (unit
< UNIT_LAST
)
1027 { /* use the available unit definition */
1028 talk_value(value
, unit
, false);
1031 { /* say the number, followed by an arbitrary voice ID */
1032 talk_number(value
, false);
1033 talk_id(unit
, true);
1038 struct value_setting_data
{
1039 enum optiontype type
;
1040 /* used for "value" settings.. */
1045 void (*formatter
)(char* dest
, int dest_length
,
1046 int value
, const char* unit
);
1047 long (*get_talk_id
)(int value
);
1048 /* used for BOOL and "choice" settings */
1049 struct opt_items
* options
;
1052 static char * value_setting_get_name_cb(int selected_item
,void * data
, char *buffer
)
1054 struct value_setting_data
* cb_data
=
1055 (struct value_setting_data
*)data
;
1056 if (cb_data
->type
== INT
&& !cb_data
->options
)
1058 int item
= cb_data
->max
-(selected_item
*cb_data
->step
);
1059 if (cb_data
->formatter
)
1060 cb_data
->formatter(buffer
, MAX_PATH
,item
,cb_data
->unit
);
1062 snprintf(buffer
, MAX_PATH
,"%d %s",item
,cb_data
->unit
);
1064 else strcpy(buffer
,P2STR(cb_data
->options
[selected_item
].string
));
1067 #define type_fromvoidptr(type, value) \
1069 (int)(*(int*)(value)) \
1071 (bool)(*(bool*)(value))
1072 static bool do_set_setting(const unsigned char* string
, void *variable
,
1073 int nb_items
,int selected
,
1074 struct value_setting_data
*cb_data
,
1075 void (*function
)(int))
1079 struct gui_synclist lists
;
1081 bool allow_wrap
= true;
1083 if (cb_data
->type
== INT
)
1085 oldvalue
= *(int*)variable
;
1086 if (variable
== &global_settings
.volume
)
1089 else oldvalue
= *(bool*)variable
;
1091 gui_synclist_init(&lists
,value_setting_get_name_cb
,(void*)cb_data
,false,1);
1092 gui_synclist_set_title(&lists
, (char*)string
,Icon_Questionmark
);
1093 gui_synclist_set_icon_callback(&lists
,NULL
);
1094 gui_synclist_set_nb_items(&lists
,nb_items
);
1095 gui_synclist_limit_scroll(&lists
,true);
1096 gui_synclist_select_item(&lists
, selected
);
1098 if (talk_menus_enabled())
1100 if (cb_data
->type
== INT
&& !cb_data
->options
)
1101 talk_unit(cb_data
->voice_unit
, *(int*)variable
, cb_data
->get_talk_id
);
1103 talk_id(cb_data
->options
[selected
].voice_id
, false);
1106 gui_synclist_draw(&lists
);
1107 action_signalscreenchange();
1111 action
= get_action(CONTEXT_LIST
,TIMEOUT_BLOCK
);
1112 if (action
== ACTION_NONE
)
1114 if (gui_synclist_do_button(&lists
,action
,
1115 allow_wrap
?LIST_WRAP_UNLESS_HELD
:LIST_WRAP_OFF
))
1117 if (talk_menus_enabled())
1120 if (cb_data
->type
== INT
&& !cb_data
->options
)
1122 value
= cb_data
->max
-
1123 gui_synclist_get_sel_pos(&lists
)*cb_data
->step
;
1124 talk_unit(cb_data
->voice_unit
, value
, cb_data
->get_talk_id
);
1128 value
= gui_synclist_get_sel_pos(&lists
);
1129 talk_id(cb_data
->options
[value
].voice_id
, false);
1132 if (cb_data
->type
== INT
&& !cb_data
->options
)
1133 *(int*)variable
= cb_data
->max
-
1134 gui_synclist_get_sel_pos(&lists
)*cb_data
->step
;
1135 else if (cb_data
->type
== BOOL
)
1136 *(bool*)variable
= gui_synclist_get_sel_pos(&lists
) ? true : false;
1137 else *(int*)variable
= gui_synclist_get_sel_pos(&lists
);
1139 else if (action
== ACTION_STD_CANCEL
)
1141 if (cb_data
->type
== INT
)
1143 if (*(int*)variable
!= oldvalue
)
1145 gui_syncsplash(HZ
/2, str(LANG_MENU_SETTING_CANCEL
));
1146 *(int*)variable
= oldvalue
;
1151 if (*(bool*)variable
!= (bool)oldvalue
)
1153 gui_syncsplash(HZ
/2, str(LANG_MENU_SETTING_CANCEL
));
1154 *(bool*)variable
= (bool)oldvalue
;
1159 else if (action
== ACTION_STD_OK
)
1163 else if(default_event_handler(action
) == SYS_USB_CONNECTED
)
1165 gui_syncstatusbar_draw(&statusbars
, false);
1167 function(type_fromvoidptr(cb_data
->type
,variable
));
1169 if (cb_data
->type
== INT
)
1171 if (oldvalue
!= *(int*)variable
)
1174 else if (oldvalue
!= *(bool*)variable
)
1177 action_signalscreenchange();
1180 static const char *unit_strings
[] =
1211 bool set_int_ex(const unsigned char* string
,
1215 void (*function
)(int),
1219 void (*formatter
)(char*, int, int, const char*),
1220 long (*get_talk_id
)(int))
1222 int count
= (max
-min
)/step
+ 1;
1223 #if CONFIG_KEYPAD != PLAYER_PAD
1224 struct value_setting_data data
= {
1225 INT
,max
, step
, voice_unit
,unit
,formatter
,get_talk_id
,NULL
};
1226 if (voice_unit
< UNIT_LAST
)
1227 data
.unit
= unit_strings
[voice_unit
];
1229 data
.unit
= str(voice_unit
);
1230 return do_set_setting(string
,variable
,count
,
1231 (max
-*variable
)/step
, &data
,function
);
1233 struct value_setting_data data
= {
1234 INT
,min
, -step
, voice_unit
,unit
,formatter
,get_talk_id
,NULL
};
1235 if (voice_unit
< UNIT_LAST
)
1236 data
.unit
= unit_strings
[voice_unit
];
1238 data
.unit
= str(voice_unit
);
1239 return do_set_setting(string
,variable
,count
,
1240 (*variable
-min
)/step
, &data
,function
);
1243 bool set_int(const unsigned char* string
,
1247 void (*function
)(int),
1251 void (*formatter
)(char*, int, int, const char*) )
1253 return set_int_ex(string
, unit
, voice_unit
, variable
, function
,
1254 step
, min
, max
, formatter
, NULL
);
1256 /* NOTE: the 'type' parameter specifies the actual type of the variable
1257 that 'variable' points to. not the value within. Only variables with
1258 type 'bool' should use parameter BOOL.
1260 The type separation is necessary since int and bool are fundamentally
1261 different and bit-incompatible types and can not share the same access
1263 bool set_option(const char* string
, void* variable
, enum optiontype type
,
1264 const struct opt_items
* options
, int numoptions
, void (*function
)(int))
1266 struct value_setting_data data
= {
1267 type
,0, 0, 0,NULL
,NULL
,NULL
,(struct opt_items
*)options
};
1270 selected
= *(bool*)variable
? 1 : 0;
1271 else selected
= *(int*)variable
;
1272 return do_set_setting(string
,variable
,numoptions
,
1273 selected
, &data
,function
);
1276 /** extra stuff which is probably misplaced **/
1278 void set_file(char* filename
, char* setting
, int maxlen
)
1280 char* fptr
= strrchr(filename
,'/');
1293 while ((*ptr
!= '.') && (ptr
!= fptr
)) {
1297 if(ptr
== fptr
) extlen
= 0;
1299 if (strncasecmp(ROCKBOX_DIR
, filename
,strlen(ROCKBOX_DIR
)) ||
1300 (len
-extlen
> maxlen
))
1303 strncpy(setting
, fptr
, len
-extlen
);
1304 setting
[len
-extlen
]=0;
1309 #ifdef HAVE_RECORDING
1310 /* This array holds the record timer interval lengths, in seconds */
1311 static const unsigned long rec_timer_seconds
[] =
1313 0, /* 0 means OFF */
1321 2*60*60, /* 02:00 */
1322 4*60*60, /* 04:00 */
1323 6*60*60, /* 06:00 */
1324 8*60*60, /* 08:00 */
1325 10L*60*60, /* 10:00 */
1326 12L*60*60, /* 12:00 */
1327 18L*60*60, /* 18:00 */
1328 24L*60*60 /* 24:00 */
1331 unsigned int rec_timesplit_seconds(void)
1333 return rec_timer_seconds
[global_settings
.rec_timesplit
];
1336 /* This array holds the record size interval lengths, in bytes */
1337 static const unsigned long rec_size_bytes
[] =
1339 0, /* 0 means OFF */
1340 5*1024*1024, /* 5MB */
1341 10*1024*1024, /* 10MB */
1342 15*1024*1024, /* 15MB */
1343 32*1024*1024, /* 32MB */
1344 64*1024*1024, /* 64MB */
1345 75*1024*1024, /* 75MB */
1346 100*1024*1024, /* 100MB */
1347 128*1024*1024, /* 128MB */
1348 256*1024*1024, /* 256MB */
1349 512*1024*1024, /* 512MB */
1350 650*1024*1024, /* 650MB */
1351 700*1024*1024, /* 700MB */
1352 1024*1024*1024, /* 1GB */
1353 1536*1024*1024, /* 1.5GB */
1354 1792*1024*1024, /* 1.75GB */
1357 unsigned long rec_sizesplit_bytes(void)
1359 return rec_size_bytes
[global_settings
.rec_sizesplit
];
1362 * Time strings used for the trigger durations.
1363 * Keep synchronous to trigger_times in settings_apply_trigger
1365 const char * const trig_durations
[TRIG_DURATION_COUNT
] =
1367 "0s", "1s", "2s", "5s",
1368 "10s", "15s", "20s", "25s", "30s",
1369 "1min", "2min", "5min", "10min"
1372 void settings_apply_trigger(void)
1374 /* Keep synchronous to trig_durations and trig_durations_conf*/
1375 static const long trigger_times
[TRIG_DURATION_COUNT
] = {
1377 10*HZ
, 15*HZ
, 20*HZ
, 25*HZ
, 30*HZ
,
1378 60*HZ
, 2*60*HZ
, 5*60*HZ
, 10*60*HZ
1381 peak_meter_define_trigger(
1382 global_settings
.rec_start_thres
,
1383 trigger_times
[global_settings
.rec_start_duration
],
1384 MIN(trigger_times
[global_settings
.rec_start_duration
] / 2, 2*HZ
),
1385 global_settings
.rec_stop_thres
,
1386 trigger_times
[global_settings
.rec_stop_postrec
],
1387 trigger_times
[global_settings
.rec_stop_gap
]