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"
65 #if (LCD_DEPTH > 1) || (defined(HAVE_LCD_REMOTE) && (LCD_REMOTE_DEPTH > 1))
73 #if CONFIG_CODEC == MAS3507D
74 void dac_line_in(bool enable
);
76 struct user_settings global_settings
;
77 struct system_status global_status
;
80 const char rec_base_directory
[] = REC_BASE_DIR
;
82 #if CONFIG_CODEC == SWCODEC
84 #include "pcm_playback.h"
87 #include "enc_config.h"
89 #endif /* CONFIG_CODEC == SWCODEC */
91 #define NVRAM_BLOCK_SIZE 44
93 #ifdef HAVE_LCD_BITMAP
99 #ifdef HAVE_REMOTE_LCD
100 #include "lcd-remote.h"
105 /** NVRAM stuff, if the target doesnt have NVRAM it is saved in ROCKBOX_DIR /nvram.bin **/
106 /* NVRAM is set out as
110 [3] stored variable count
112 [8-NVRAM_BLOCK_SIZE] data
114 #define NVRAM_DATA_START 8
115 #define NVRAM_FILE ROCKBOX_DIR "/nvram.bin"
116 static char nvram_buffer
[NVRAM_BLOCK_SIZE
];
118 static bool read_nvram_data(char* buf
, int max_len
)
120 unsigned crc32
= 0xffffffff;
121 int var_count
= 0, i
= 0, buf_pos
= 0;
123 int fd
= open(NVRAM_FILE
,O_RDONLY
);
126 memset(buf
,0,max_len
);
127 if (read(fd
,buf
,max_len
) < 8) /* min is 8 bytes,magic, ver, vars, crc32 */
131 memset(buf
,0,max_len
);
133 for (i
=0; i
< max_len
; i
++ )
134 buf
[i
] = rtc_read(0x14+i
);
136 /* check magic, version */
137 if ((buf
[0] != 'R') || (buf
[1] != 'b')
138 || (buf
[2] != NVRAM_CONFIG_VERSION
))
141 crc32
= crc_32(&buf
[NVRAM_DATA_START
],
142 max_len
-NVRAM_DATA_START
-1,0xffffffff);
143 if (memcmp(&crc32
,&buf
[4],4))
145 /* all good, so read in the settings */
147 buf_pos
= NVRAM_DATA_START
;
148 for(i
=0; (i
<nb_settings
) && (var_count
>0) && (buf_pos
<max_len
); i
++)
150 int nvram_bytes
= (settings
[i
].flags
&F_NVRAM_BYTES_MASK
)
151 >>F_NVRAM_MASK_SHIFT
;
154 memcpy(settings
[i
].setting
,&buf
[buf_pos
],nvram_bytes
);
155 buf_pos
+= nvram_bytes
;
161 static bool write_nvram_data(char* buf
, int max_len
)
163 unsigned crc32
= 0xffffffff;
164 int i
= 0, buf_pos
= 0;
169 memset(buf
,0,max_len
);
171 buf
[0] = 'R'; buf
[1] = 'b';
172 buf
[2] = NVRAM_CONFIG_VERSION
;
173 buf_pos
= NVRAM_DATA_START
;
174 for(i
=0; (i
<nb_settings
) && (buf_pos
<max_len
); i
++)
176 int nvram_bytes
= (settings
[i
].flags
&F_NVRAM_BYTES_MASK
)
177 >>F_NVRAM_MASK_SHIFT
;
180 memcpy(&buf
[buf_pos
],settings
[i
].setting
,nvram_bytes
);
181 buf_pos
+= nvram_bytes
;
185 /* count and crc32 */
187 crc32
= crc_32(&buf
[NVRAM_DATA_START
],
188 max_len
-NVRAM_DATA_START
-1,0xffffffff);
189 memcpy(&buf
[4],&crc32
,4);
191 fd
= open(NVRAM_FILE
,O_CREAT
|O_TRUNC
|O_WRONLY
);
194 int len
= write(fd
,buf
,max_len
);
200 /* FIXME: okay, it _would_ be cleaner and faster to implement rtc_write so
201 that it would write a number of bytes at a time since the RTC chip
202 supports that, but this will have to do for now 8-) */
203 for (i
=0; i
< NVRAM_BLOCK_SIZE
; i
++ ) {
204 int r
= rtc_write(0x14+i
, buf
[i
]);
206 DEBUGF( "save_config_buffer: rtc_write failed at addr 0x%02x: %d\n",
215 /** Reading from a config file **/
217 * load settings from disk or RTC RAM
219 void settings_load(int which
)
221 DEBUGF( "reload_all_settings()\n" );
222 if (which
&SETTINGS_RTC
)
223 read_nvram_data(nvram_buffer
,NVRAM_BLOCK_SIZE
);
224 if (which
&SETTINGS_HD
)
226 settings_load_config(CONFIGFILE
,false);
227 settings_load_config(FIXEDSETTINGSFILE
,false);
230 #ifdef HAVE_LCD_COLOR
232 * Helper function to convert a string of 6 hex digits to a native colour
235 #define hex2dec(c) (((c) >= '0' && ((c) <= '9')) ? (toupper(c)) - '0' : \
236 (toupper(c)) - 'A' + 10)
238 static int hex_to_rgb(const char* hex
)
241 int red
, green
, blue
;
243 if (strlen(hex
) == 6) {
244 for (i
=0; i
< 6; i
++ ) {
245 if (!isxdigit(hex
[i
])) {
252 red
= (hex2dec(hex
[0]) << 4) | hex2dec(hex
[1]);
253 green
= (hex2dec(hex
[2]) << 4) | hex2dec(hex
[3]);
254 blue
= (hex2dec(hex
[4]) << 4) | hex2dec(hex
[5]);
255 return LCD_RGBPACK(red
,green
,blue
);
261 #endif /* HAVE_LCD_COLOR */
263 static bool cfg_string_to_int(int setting_id
, int* out
, char* str
)
265 const char* start
= settings
[setting_id
].cfg_vals
;
271 end
= strchr(start
, ',');
274 if (!strcmp(str
, start
))
281 strncpy(temp
, start
, end
-start
);
282 temp
[end
-start
] = '\0';
283 if (!strcmp(str
, temp
))
294 bool settings_load_config(const char* file
, bool apply
)
301 fd
= open(file
, O_RDONLY
);
305 while (read_line(fd
, line
, sizeof line
) > 0)
307 if (!settings_parseline(line
, &name
, &value
))
309 for(i
=0; i
<nb_settings
; i
++)
311 if (settings
[i
].cfg_name
== NULL
)
313 if (!strcasecmp(name
,settings
[i
].cfg_name
))
315 switch (settings
[i
].flags
&F_T_MASK
)
319 #ifdef HAVE_LCD_COLOR
320 if (settings
[i
].flags
&F_RGB
)
321 *(int*)settings
[i
].setting
= hex_to_rgb(value
);
324 if (settings
[i
].cfg_vals
== NULL
)
326 *(int*)settings
[i
].setting
= atoi(value
);
330 cfg_string_to_int(i
,(int*)settings
[i
].setting
,value
);
336 if (cfg_string_to_int(i
,&temp
,value
))
337 *(bool*)settings
[i
].setting
= (temp
==0?false:true);
343 char storage
[MAX_PATH
];
344 if (settings
[i
].filename_setting
->prefix
)
346 int len
= strlen(settings
[i
].filename_setting
->prefix
);
347 if (!strncasecmp(value
,
348 settings
[i
].filename_setting
->prefix
,
351 strncpy(storage
,&value
[len
],MAX_PATH
);
353 else strncpy(storage
,value
,MAX_PATH
);
355 else strncpy(storage
,value
,MAX_PATH
);
356 if (settings
[i
].filename_setting
->suffix
)
358 char *s
= strcasestr(storage
,settings
[i
].filename_setting
->suffix
);
361 strncpy((char*)settings
[i
].setting
,storage
,
362 settings
[i
].filename_setting
->max_len
);
363 ((char*)settings
[i
].setting
)
364 [settings
[i
].filename_setting
->max_len
-1] = '\0';
369 } /* if (!strcmp(name,settings[i].cfg_name)) */
380 /** Writing to a config file and saving settings **/
382 bool cfg_int_to_string(int setting_id
, int val
, char* buf
, int buf_len
)
384 const char* start
= settings
[setting_id
].cfg_vals
;
389 start
= strchr(start
,',');
395 end
= strchr(start
,',');
397 strncpy(buf
, start
, buf_len
);
400 int len
= (buf_len
> (end
-start
))? end
-start
: buf_len
;
401 strncpy(buf
, start
, len
);
406 static bool is_changed(int setting_id
)
408 const struct settings_list
*setting
= &settings
[setting_id
];
409 switch (setting
->flags
&F_T_MASK
)
413 if (setting
->flags
&F_DEF_ISFUNC
)
415 if (*(int*)setting
->setting
== setting
->default_val
.func())
418 else if (setting
->flags
&F_T_SOUND
)
420 if (*(int*)setting
->setting
==
421 sound_default(setting
->sound_setting
->setting
))
424 else if (*(int*)setting
->setting
== setting
->default_val
.int_
)
428 if (*(bool*)setting
->setting
== setting
->default_val
.bool_
)
433 if (!strcmp((char*)setting
->setting
, setting
->default_val
.charptr
))
440 static bool settings_write_config(char* filename
, int options
)
444 char value
[MAX_PATH
];
445 fd
= open(filename
,O_CREAT
|O_TRUNC
|O_WRONLY
);
448 fdprintf(fd
, "# .cfg file created by rockbox %s - "
449 "http://www.rockbox.org\r\n\r\n", appsversion
);
450 for(i
=0; i
<nb_settings
; i
++)
452 if (settings
[i
].cfg_name
== NULL
)
456 if ((options
== SETTINGS_SAVE_CHANGED
) &&
459 else if ((options
== SETTINGS_SAVE_THEME
) &&
460 ((settings
[i
].flags
&F_THEMESETTING
) == 0))
462 #ifdef HAVE_RECORDING
463 else if ((options
== SETTINGS_SAVE_RECPRESETS
) &&
464 ((settings
[i
].flags
&F_RECSETTING
) == 0))
467 switch (settings
[i
].flags
&F_T_MASK
)
471 #ifdef HAVE_LCD_COLOR
472 if (settings
[i
].flags
&F_RGB
)
474 int colour
= *(int*)settings
[i
].setting
;
475 snprintf(value
,MAX_PATH
,"%02x%02x%02x",
476 (int)RGB_UNPACK_RED(colour
),
477 (int)RGB_UNPACK_GREEN(colour
),
478 (int)RGB_UNPACK_BLUE(colour
));
482 if (settings
[i
].cfg_vals
== NULL
)
484 snprintf(value
,MAX_PATH
,"%d",*(int*)settings
[i
].setting
);
488 cfg_int_to_string(i
, *(int*)settings
[i
].setting
,
494 *(bool*)settings
[i
].setting
==false?0:1, value
, MAX_PATH
);
498 if (((char*)settings
[i
].setting
)[0] == '\0')
500 if (settings
[i
].filename_setting
->prefix
)
502 snprintf(value
,MAX_PATH
,"%s%s%s",
503 settings
[i
].filename_setting
->prefix
,
504 (char*)settings
[i
].setting
,
505 settings
[i
].filename_setting
->suffix
);
507 else strncpy(value
,(char*)settings
[i
].setting
,
508 settings
[i
].filename_setting
->max_len
);
512 fdprintf(fd
,"%s: %s\r\n",settings
[i
].cfg_name
,value
);
518 static bool flush_global_status_callback(void)
520 return write_nvram_data(nvram_buffer
,NVRAM_BLOCK_SIZE
);
523 static bool flush_config_block_callback(void)
526 r1
= write_nvram_data(nvram_buffer
,NVRAM_BLOCK_SIZE
);
527 r2
= settings_write_config(CONFIGFILE
, SETTINGS_SAVE_CHANGED
);
532 * persist all runtime user settings to disk or RTC RAM
534 static void update_runtime(void)
538 elapsed_secs
= (current_tick
- lasttime
) / HZ
;
539 global_status
.runtime
+= elapsed_secs
;
540 lasttime
+= (elapsed_secs
* HZ
);
542 if ( global_status
.runtime
> global_status
.topruntime
)
543 global_status
.topruntime
= global_status
.runtime
;
546 void status_save( void )
550 /* this will be done in the ata_callback if
551 target doesnt have rtc ram */
552 write_nvram_data(nvram_buffer
,NVRAM_BLOCK_SIZE
);
554 register_ata_idle_func(flush_global_status_callback
);
558 int settings_save( void )
562 /* this will be done in the ata_callback if
563 target doesnt have rtc ram */
564 write_nvram_data(nvram_buffer
,NVRAM_BLOCK_SIZE
);
566 if(!register_ata_idle_func(flush_config_block_callback
))
571 screens
[i
].clear_display();
572 #ifdef HAVE_LCD_CHARCELLS
573 screens
[i
].puts(0, 0, str(LANG_SETTINGS_SAVE_PLAYER
));
574 screens
[i
].puts(0, 1, str(LANG_SETTINGS_BATTERY_PLAYER
));
576 screens
[i
].puts(4, 2, str(LANG_SETTINGS_SAVE_RECORDER
));
577 screens
[i
].puts(2, 4, str(LANG_SETTINGS_BATTERY_RECORDER
));
586 bool settings_save_config(int options
)
588 char filename
[MAX_PATH
];
592 case SETTINGS_SAVE_THEME
:
595 #ifdef HAVE_RECORDING
596 case SETTINGS_SAVE_RECPRESETS
:
597 folder
= RECPRESETS_DIR
;
601 folder
= ROCKBOX_DIR
;
603 create_numbered_filename(filename
, folder
, "config", ".cfg", 2
604 IF_CNFN_NUM_(, NULL
));
606 /* allow user to modify filename */
608 if (!kbd_input(filename
, sizeof filename
)) {
612 gui_syncsplash(HZ
, str(LANG_MENU_SETTING_CANCEL
));
617 if (settings_write_config(filename
, options
))
618 gui_syncsplash(HZ
, str(LANG_SETTINGS_SAVED
));
620 gui_syncsplash(HZ
, str(LANG_FAILED
));
624 /** Apply and Reset settings **/
627 #ifdef HAVE_LCD_BITMAP
629 * Applies the range infos stored in global_settings to
632 void settings_apply_pm_range(void)
636 /* depending on the scale mode (dBfs or percent) the values
637 of global_settings.peak_meter_dbfs have different meanings */
638 if (global_settings
.peak_meter_dbfs
)
640 /* convert to dBfs * 100 */
641 pm_min
= -(((int)global_settings
.peak_meter_min
) * 100);
642 pm_max
= -(((int)global_settings
.peak_meter_max
) * 100);
646 /* percent is stored directly -> no conversion */
647 pm_min
= global_settings
.peak_meter_min
;
648 pm_max
= global_settings
.peak_meter_max
;
651 /* apply the range */
652 peak_meter_init_range(global_settings
.peak_meter_dbfs
, pm_min
, pm_max
);
654 #endif /* HAVE_LCD_BITMAP */
656 void sound_settings_apply(void)
658 #if CONFIG_CODEC == SWCODEC
659 sound_set_dsp_callback(dsp_callback
);
661 sound_set(SOUND_BASS
, global_settings
.bass
);
662 sound_set(SOUND_TREBLE
, global_settings
.treble
);
663 sound_set(SOUND_BALANCE
, global_settings
.balance
);
664 sound_set(SOUND_VOLUME
, global_settings
.volume
);
665 sound_set(SOUND_CHANNELS
, global_settings
.channel_config
);
666 sound_set(SOUND_STEREO_WIDTH
, global_settings
.stereo_width
);
667 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
668 sound_set(SOUND_LOUDNESS
, global_settings
.loudness
);
669 sound_set(SOUND_AVC
, global_settings
.avc
);
670 sound_set(SOUND_MDB_STRENGTH
, global_settings
.mdb_strength
);
671 sound_set(SOUND_MDB_HARMONICS
, global_settings
.mdb_harmonics
);
672 sound_set(SOUND_MDB_CENTER
, global_settings
.mdb_center
);
673 sound_set(SOUND_MDB_SHAPE
, global_settings
.mdb_shape
);
674 sound_set(SOUND_MDB_ENABLE
, global_settings
.mdb_enable
);
675 sound_set(SOUND_SUPERBASS
, global_settings
.superbass
);
678 #ifdef HAVE_USB_POWER
680 usb_charging_enable(global_settings
.usb_charging
);
685 void settings_apply(void)
688 #if CONFIG_CODEC == SWCODEC
692 DEBUGF( "settings_apply()\n" );
693 sound_settings_apply();
695 audio_set_buffer_margin(global_settings
.buffer_margin
);
697 #ifdef HAVE_LCD_CONTRAST
698 lcd_set_contrast(global_settings
.contrast
);
700 lcd_scroll_speed(global_settings
.scroll_speed
);
701 #ifdef HAVE_REMOTE_LCD
702 lcd_remote_set_contrast(global_settings
.remote_contrast
);
703 lcd_remote_set_invert_display(global_settings
.remote_invert
);
704 lcd_remote_set_flip(global_settings
.remote_flip_display
);
705 lcd_remote_scroll_speed(global_settings
.remote_scroll_speed
);
706 lcd_remote_scroll_step(global_settings
.remote_scroll_step
);
707 lcd_remote_scroll_delay(global_settings
.remote_scroll_delay
);
708 lcd_remote_bidir_scroll(global_settings
.remote_bidir_limit
);
709 #ifdef HAVE_REMOTE_LCD_TICKING
710 lcd_remote_emireduce(global_settings
.remote_reduce_ticking
);
712 remote_backlight_set_timeout(global_settings
.remote_backlight_timeout
);
714 remote_backlight_set_timeout_plugged(global_settings
.remote_backlight_timeout_plugged
);
716 #ifdef HAS_REMOTE_BUTTON_HOLD
717 remote_backlight_set_on_button_hold(global_settings
.remote_backlight_on_button_hold
);
719 #endif /* HAVE_REMOTE_LCD */
720 #ifdef HAVE_BACKLIGHT_BRIGHTNESS
721 backlight_set_brightness(global_settings
.brightness
);
723 #ifdef HAVE_BACKLIGHT
724 backlight_set_timeout(global_settings
.backlight_timeout
);
726 backlight_set_timeout_plugged(global_settings
.backlight_timeout_plugged
);
728 #if defined(HAVE_BACKLIGHT_PWM_FADING) && !defined(SIMULATOR)
729 backlight_set_fade_in(global_settings
.backlight_fade_in
);
730 backlight_set_fade_out(global_settings
.backlight_fade_out
);
733 #ifdef HAVE_BUTTONLIGHT_BRIGHTNESS
734 buttonlight_set_brightness(global_settings
.buttonlight_brightness
);
736 #ifdef HAVE_BUTTON_LIGHT
737 button_backlight_set_timeout(global_settings
.button_light_timeout
);
739 ata_spindown(global_settings
.disk_spindown
);
740 #if (CONFIG_CODEC == MAS3507D) && !defined(SIMULATOR)
741 dac_line_in(global_settings
.line_in
);
743 mpeg_id3_options(global_settings
.id3_v1_first
);
745 set_poweroff_timeout(global_settings
.poweroff
);
747 set_battery_capacity(global_settings
.battery_capacity
);
748 #if BATTERY_TYPES_COUNT > 1
749 set_battery_type(global_settings
.battery_type
);
752 #ifdef HAVE_LCD_BITMAP
753 lcd_set_invert_display(global_settings
.invert
);
754 lcd_set_flip(global_settings
.flip_display
);
755 button_set_flip(global_settings
.flip_display
);
756 lcd_update(); /* refresh after flipping the screen */
757 settings_apply_pm_range();
758 peak_meter_init_times(
759 global_settings
.peak_meter_release
, global_settings
.peak_meter_hold
,
760 global_settings
.peak_meter_clip_hold
);
764 unload_wps_backdrop();
766 #if defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1
767 unload_remote_wps_backdrop();
769 if ( global_settings
.wps_file
[0] &&
770 global_settings
.wps_file
[0] != 0xff ) {
771 snprintf(buf
, sizeof buf
, WPS_DIR
"/%s.wps",
772 global_settings
.wps_file
);
773 wps_data_load(gui_wps
[0].data
, buf
, true);
777 wps_data_init(gui_wps
[0].data
);
778 #ifdef HAVE_REMOTE_LCD
779 gui_wps
[0].data
->remote_wps
= false;
784 if ( global_settings
.backdrop_file
[0] &&
785 global_settings
.backdrop_file
[0] != 0xff ) {
786 snprintf(buf
, sizeof buf
, BACKDROP_DIR
"/%s.bmp",
787 global_settings
.backdrop_file
);
788 load_main_backdrop(buf
);
790 unload_main_backdrop();
792 show_main_backdrop();
794 #if defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1
795 show_remote_main_backdrop();
798 #ifdef HAVE_LCD_COLOR
799 screens
[SCREEN_MAIN
].set_foreground(global_settings
.fg_color
);
800 screens
[SCREEN_MAIN
].set_background(global_settings
.bg_color
);
803 #if defined(HAVE_REMOTE_LCD) && (NB_SCREENS > 1)
804 if ( global_settings
.rwps_file
[0]) {
805 snprintf(buf
, sizeof buf
, WPS_DIR
"/%s.rwps",
806 global_settings
.rwps_file
);
807 wps_data_load(gui_wps
[1].data
, buf
, true);
811 wps_data_init(gui_wps
[1].data
);
812 gui_wps
[1].data
->remote_wps
= true;
816 #ifdef HAVE_LCD_BITMAP
817 if ( global_settings
.font_file
[0]) {
818 snprintf(buf
, sizeof buf
, FONT_DIR
"/%s.fnt",
819 global_settings
.font_file
);
825 if ( global_settings
.kbd_file
[0]) {
826 snprintf(buf
, sizeof buf
, ROCKBOX_DIR
"/%s.kbd",
827 global_settings
.kbd_file
);
833 lcd_scroll_step(global_settings
.scroll_step
);
834 gui_list_screen_scroll_step(global_settings
.screen_scroll_step
);
835 gui_list_screen_scroll_out_of_view(global_settings
.offset_out_of_view
);
837 lcd_jump_scroll(global_settings
.jump_scroll
);
838 lcd_jump_scroll_delay(global_settings
.jump_scroll_delay
);
840 lcd_bidir_scroll(global_settings
.bidir_limit
);
841 lcd_scroll_delay(global_settings
.scroll_delay
);
843 if ( global_settings
.lang_file
[0]) {
844 snprintf(buf
, sizeof buf
, LANG_DIR
"/%s.lng",
845 global_settings
.lang_file
);
847 talk_init(); /* use voice of same language */
850 set_codepage(global_settings
.default_codepage
);
852 #if CONFIG_CODEC == SWCODEC
853 audio_set_crossfade(global_settings
.crossfade
);
854 dsp_set_replaygain();
855 dsp_set_crossfeed(global_settings
.crossfeed
);
856 dsp_set_crossfeed_direct_gain(global_settings
.crossfeed_direct_gain
);
857 dsp_set_crossfeed_cross_params(global_settings
.crossfeed_cross_gain
,
858 global_settings
.crossfeed_hf_attenuation
,
859 global_settings
.crossfeed_hf_cutoff
);
861 /* Configure software equalizer, hardware eq is handled in audio_init() */
862 dsp_set_eq(global_settings
.eq_enabled
);
863 dsp_set_eq_precut(global_settings
.eq_precut
);
864 for(i
= 0; i
< 5; i
++) {
868 dsp_dither_enable(global_settings
.dithering_enabled
);
871 #ifdef HAVE_SPDIF_POWER
872 spdif_power_enable(global_settings
.spdif_enable
);
875 #ifdef HAVE_BACKLIGHT
876 set_backlight_filter_keypress(global_settings
.bl_filter_first_keypress
);
877 #ifdef HAVE_REMOTE_LCD
878 set_remote_backlight_filter_keypress(global_settings
.remote_bl_filter_first_keypress
);
880 #ifdef HAS_BUTTON_HOLD
881 backlight_set_on_button_hold(global_settings
.backlight_on_button_hold
);
883 #ifdef HAVE_LCD_SLEEP
884 lcd_set_sleep_after_backlight_off(global_settings
.lcd_sleep_after_backlight_off
);
886 #endif /* HAVE_BACKLIGHT */
888 /* This should stay last */
889 #if defined(HAVE_RECORDING) && CONFIG_CODEC == SWCODEC
890 enc_global_settings_apply();
892 /* load the icon set */
901 * reset all settings to their default value
903 void settings_reset(void) {
906 DEBUGF( "settings_reset()\n" );
908 for(i
=0; i
<nb_settings
; i
++)
910 switch (settings
[i
].flags
&F_T_MASK
)
914 if (settings
[i
].flags
&F_DEF_ISFUNC
)
915 *(int*)settings
[i
].setting
= settings
[i
].default_val
.func();
916 else if (settings
[i
].flags
&F_T_SOUND
)
917 *(int*)settings
[i
].setting
=
918 sound_default(settings
[i
].sound_setting
->setting
);
919 else *(int*)settings
[i
].setting
= settings
[i
].default_val
.int_
;
922 *(bool*)settings
[i
].setting
= settings
[i
].default_val
.bool_
;
926 strncpy((char*)settings
[i
].setting
,
927 settings
[i
].default_val
.charptr
,MAX_FILENAME
);
931 #if defined (HAVE_RECORDING) && CONFIG_CODEC == SWCODEC
932 enc_global_settings_reset();
936 /** Changing setting values **/
937 const struct settings_list
* find_setting(void* variable
, int *id
)
940 for(i
=0;i
<nb_settings
;i
++)
942 if (settings
[i
].setting
== variable
)
952 void talk_setting(void *global_settings_variable
)
954 const struct settings_list
*setting
;
955 if (!talk_menus_enabled())
957 setting
= find_setting(global_settings_variable
, NULL
);
960 if (setting
->lang_id
)
961 talk_id(setting
->lang_id
,false);
964 static int selected_setting
; /* Used by the callback */
966 static void dec_sound_formatter(char *buffer
, int buffer_size
,
967 int val
, const char *unit
)
969 val
= sound_val2phys(selected_setting
, val
);
976 int integer
= val
/ 10;
978 snprintf(buffer
, buffer_size
, "%c%d.%d %s", sign
, integer
, dec
, unit
);
981 bool set_sound(const unsigned char * string
,
985 int talkunit
= UNIT_INT
;
986 const char* unit
= sound_unit(setting
);
987 int numdec
= sound_numdecimals(setting
);
988 int steps
= sound_steps(setting
);
989 int min
= sound_min(setting
);
990 int max
= sound_max(setting
);
991 sound_set_type
* sound_callback
= sound_get_fn(setting
);
992 if (*unit
== 'd') /* crude reconstruction */
994 else if (*unit
== '%')
995 talkunit
= UNIT_PERCENT
;
996 else if (*unit
== 'H')
997 talkunit
= UNIT_HERTZ
;
999 return set_int(string
, unit
, talkunit
, variable
, sound_callback
,
1000 steps
, min
, max
, NULL
);
1002 {/* Decimal number */
1003 selected_setting
=setting
;
1004 return set_int(string
, unit
, talkunit
, variable
, sound_callback
,
1005 steps
, min
, max
, &dec_sound_formatter
);
1009 bool set_bool(const char* string
, bool* variable
)
1011 return set_bool_options(string
, variable
,
1012 (char *)STR(LANG_SET_BOOL_YES
),
1013 (char *)STR(LANG_SET_BOOL_NO
),
1017 /* wrapper to convert from int param to bool param in set_option */
1018 static void (*boolfunction
)(bool);
1019 static void bool_funcwrapper(int value
)
1024 boolfunction(false);
1027 bool set_bool_options(const char* string
, bool* variable
,
1028 const char* yes_str
, int yes_voice
,
1029 const char* no_str
, int no_voice
,
1030 void (*function
)(bool))
1032 struct opt_items names
[] = {
1033 {(unsigned char *)no_str
, no_voice
},
1034 {(unsigned char *)yes_str
, yes_voice
}
1038 boolfunction
= function
;
1039 result
= set_option(string
, variable
, BOOL
, names
, 2,
1040 function
? bool_funcwrapper
: NULL
);
1044 static void talk_unit(int unit
, int value
, long (*get_talk_id
)(int value
))
1046 if (talk_menus_enabled())
1050 talk_id(get_talk_id(value
),false);
1052 else if (unit
< UNIT_LAST
)
1053 { /* use the available unit definition */
1054 talk_value(value
, unit
, false);
1057 { /* say the number, followed by an arbitrary voice ID */
1058 talk_number(value
, false);
1059 talk_id(unit
, true);
1064 struct value_setting_data
{
1065 enum optiontype type
;
1066 /* used for "value" settings.. */
1071 void (*formatter
)(char* dest
, int dest_length
,
1072 int value
, const char* unit
);
1073 long (*get_talk_id
)(int value
);
1074 /* used for BOOL and "choice" settings */
1075 struct opt_items
* options
;
1078 static char * value_setting_get_name_cb(int selected_item
,void * data
, char *buffer
)
1080 struct value_setting_data
* cb_data
=
1081 (struct value_setting_data
*)data
;
1082 if (cb_data
->type
== INT
&& !cb_data
->options
)
1084 int item
= cb_data
->max
-(selected_item
*cb_data
->step
);
1085 if (cb_data
->formatter
)
1086 cb_data
->formatter(buffer
, MAX_PATH
,item
,cb_data
->unit
);
1088 snprintf(buffer
, MAX_PATH
,"%d %s",item
,cb_data
->unit
);
1090 else strcpy(buffer
,P2STR(cb_data
->options
[selected_item
].string
));
1093 #define type_fromvoidptr(type, value) \
1095 (int)(*(int*)(value)) \
1097 (bool)(*(bool*)(value))
1098 static bool do_set_setting(const unsigned char* string
, void *variable
,
1099 int nb_items
,int selected
,
1100 struct value_setting_data
*cb_data
,
1101 void (*function
)(int))
1105 struct gui_synclist lists
;
1107 bool allow_wrap
= true;
1109 if (cb_data
->type
== INT
)
1111 oldvalue
= *(int*)variable
;
1112 if (variable
== &global_settings
.volume
)
1115 else oldvalue
= *(bool*)variable
;
1117 gui_synclist_init(&lists
,value_setting_get_name_cb
,(void*)cb_data
,false,1);
1118 gui_synclist_set_title(&lists
, (char*)string
,Icon_Questionmark
);
1119 gui_synclist_set_icon_callback(&lists
,NULL
);
1120 gui_synclist_set_nb_items(&lists
,nb_items
);
1121 gui_synclist_limit_scroll(&lists
,true);
1122 gui_synclist_select_item(&lists
, selected
);
1124 if (talk_menus_enabled())
1126 if (cb_data
->type
== INT
&& !cb_data
->options
)
1127 talk_unit(cb_data
->voice_unit
, *(int*)variable
, cb_data
->get_talk_id
);
1129 talk_id(cb_data
->options
[selected
].voice_id
, false);
1132 gui_synclist_draw(&lists
);
1133 action_signalscreenchange();
1137 action
= get_action(CONTEXT_LIST
,TIMEOUT_BLOCK
);
1138 if (action
== ACTION_NONE
)
1140 if (gui_synclist_do_button(&lists
,action
,
1141 allow_wrap
?LIST_WRAP_UNLESS_HELD
:LIST_WRAP_OFF
))
1143 if (talk_menus_enabled())
1146 if (cb_data
->type
== INT
&& !cb_data
->options
)
1148 value
= cb_data
->max
-
1149 gui_synclist_get_sel_pos(&lists
)*cb_data
->step
;
1150 talk_unit(cb_data
->voice_unit
, value
, cb_data
->get_talk_id
);
1154 value
= gui_synclist_get_sel_pos(&lists
);
1155 talk_id(cb_data
->options
[value
].voice_id
, false);
1158 if (cb_data
->type
== INT
&& !cb_data
->options
)
1159 *(int*)variable
= cb_data
->max
-
1160 gui_synclist_get_sel_pos(&lists
)*cb_data
->step
;
1161 else if (cb_data
->type
== BOOL
)
1162 *(bool*)variable
= gui_synclist_get_sel_pos(&lists
) ? true : false;
1163 else *(int*)variable
= gui_synclist_get_sel_pos(&lists
);
1165 else if (action
== ACTION_STD_CANCEL
)
1167 if (cb_data
->type
== INT
)
1169 if (*(int*)variable
!= oldvalue
)
1171 gui_syncsplash(HZ
/2, str(LANG_MENU_SETTING_CANCEL
));
1172 *(int*)variable
= oldvalue
;
1177 if (*(bool*)variable
!= (bool)oldvalue
)
1179 gui_syncsplash(HZ
/2, str(LANG_MENU_SETTING_CANCEL
));
1180 *(bool*)variable
= (bool)oldvalue
;
1185 else if (action
== ACTION_STD_OK
)
1189 else if(default_event_handler(action
) == SYS_USB_CONNECTED
)
1191 gui_syncstatusbar_draw(&statusbars
, false);
1193 function(type_fromvoidptr(cb_data
->type
,variable
));
1195 if (cb_data
->type
== INT
)
1197 if (oldvalue
!= *(int*)variable
)
1200 else if (oldvalue
!= *(bool*)variable
)
1203 action_signalscreenchange();
1206 static const char *unit_strings
[] =
1237 bool set_int_ex(const unsigned char* string
,
1241 void (*function
)(int),
1245 void (*formatter
)(char*, int, int, const char*),
1246 long (*get_talk_id
)(int))
1248 int count
= (max
-min
)/step
+ 1;
1249 #if CONFIG_KEYPAD != PLAYER_PAD
1250 struct value_setting_data data
= {
1251 INT
,max
, step
, voice_unit
,unit
,formatter
,get_talk_id
,NULL
};
1252 if (voice_unit
< UNIT_LAST
)
1253 data
.unit
= unit_strings
[voice_unit
];
1255 data
.unit
= str(voice_unit
);
1256 return do_set_setting(string
,variable
,count
,
1257 (max
-*variable
)/step
, &data
,function
);
1259 struct value_setting_data data
= {
1260 INT
,min
, -step
, voice_unit
,unit
,formatter
,get_talk_id
,NULL
};
1261 if (voice_unit
< UNIT_LAST
)
1262 data
.unit
= unit_strings
[voice_unit
];
1264 data
.unit
= str(voice_unit
);
1265 return do_set_setting(string
,variable
,count
,
1266 (*variable
-min
)/step
, &data
,function
);
1269 bool set_int(const unsigned char* string
,
1273 void (*function
)(int),
1277 void (*formatter
)(char*, int, int, const char*) )
1279 return set_int_ex(string
, unit
, voice_unit
, variable
, function
,
1280 step
, min
, max
, formatter
, NULL
);
1282 /* NOTE: the 'type' parameter specifies the actual type of the variable
1283 that 'variable' points to. not the value within. Only variables with
1284 type 'bool' should use parameter BOOL.
1286 The type separation is necessary since int and bool are fundamentally
1287 different and bit-incompatible types and can not share the same access
1289 bool set_option(const char* string
, void* variable
, enum optiontype type
,
1290 const struct opt_items
* options
, int numoptions
, void (*function
)(int))
1292 struct value_setting_data data
= {
1293 type
,0, 0, 0,NULL
,NULL
,NULL
,(struct opt_items
*)options
};
1296 selected
= *(bool*)variable
? 1 : 0;
1297 else selected
= *(int*)variable
;
1298 return do_set_setting(string
,variable
,numoptions
,
1299 selected
, &data
,function
);
1302 /** extra stuff which is probably misplaced **/
1304 void set_file(char* filename
, char* setting
, int maxlen
)
1306 char* fptr
= strrchr(filename
,'/');
1319 while ((*ptr
!= '.') && (ptr
!= fptr
)) {
1323 if(ptr
== fptr
) extlen
= 0;
1325 if (strncasecmp(ROCKBOX_DIR
, filename
,strlen(ROCKBOX_DIR
)) ||
1326 (len
-extlen
> maxlen
))
1329 strncpy(setting
, fptr
, len
-extlen
);
1330 setting
[len
-extlen
]=0;
1335 #ifdef HAVE_RECORDING
1336 /* This array holds the record timer interval lengths, in seconds */
1337 static const unsigned long rec_timer_seconds
[] =
1339 0, /* 0 means OFF */
1347 2*60*60, /* 02:00 */
1348 4*60*60, /* 04:00 */
1349 6*60*60, /* 06:00 */
1350 8*60*60, /* 08:00 */
1351 10L*60*60, /* 10:00 */
1352 12L*60*60, /* 12:00 */
1353 18L*60*60, /* 18:00 */
1354 24L*60*60 /* 24:00 */
1357 unsigned int rec_timesplit_seconds(void)
1359 return rec_timer_seconds
[global_settings
.rec_timesplit
];
1362 /* This array holds the record size interval lengths, in bytes */
1363 static const unsigned long rec_size_bytes
[] =
1365 0, /* 0 means OFF */
1366 5*1024*1024, /* 5MB */
1367 10*1024*1024, /* 10MB */
1368 15*1024*1024, /* 15MB */
1369 32*1024*1024, /* 32MB */
1370 64*1024*1024, /* 64MB */
1371 75*1024*1024, /* 75MB */
1372 100*1024*1024, /* 100MB */
1373 128*1024*1024, /* 128MB */
1374 256*1024*1024, /* 256MB */
1375 512*1024*1024, /* 512MB */
1376 650*1024*1024, /* 650MB */
1377 700*1024*1024, /* 700MB */
1378 1024*1024*1024, /* 1GB */
1379 1536*1024*1024, /* 1.5GB */
1380 1792*1024*1024, /* 1.75GB */
1383 unsigned long rec_sizesplit_bytes(void)
1385 return rec_size_bytes
[global_settings
.rec_sizesplit
];
1388 * Time strings used for the trigger durations.
1389 * Keep synchronous to trigger_times in settings_apply_trigger
1391 const char * const trig_durations
[TRIG_DURATION_COUNT
] =
1393 "0s", "1s", "2s", "5s",
1394 "10s", "15s", "20s", "25s", "30s",
1395 "1min", "2min", "5min", "10min"
1398 void settings_apply_trigger(void)
1400 /* Keep synchronous to trig_durations and trig_durations_conf*/
1401 static const long trigger_times
[TRIG_DURATION_COUNT
] = {
1403 10*HZ
, 15*HZ
, 20*HZ
, 25*HZ
, 30*HZ
,
1404 60*HZ
, 2*60*HZ
, 5*60*HZ
, 10*60*HZ
1407 peak_meter_define_trigger(
1408 global_settings
.rec_start_thres
,
1409 trigger_times
[global_settings
.rec_start_duration
],
1410 MIN(trigger_times
[global_settings
.rec_start_duration
] / 2, 2*HZ
),
1411 global_settings
.rec_stop_thres
,
1412 trigger_times
[global_settings
.rec_stop_postrec
],
1413 trigger_times
[global_settings
.rec_stop_gap
]