1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2002 Robert Hak
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
34 #include "settings_menu.h"
35 #include "backlight.h"
36 #include "playlist.h" /* for playlist_shuffle */
37 #include "fat.h" /* For dotfile settings */
38 #include "sleeptimer.h"
39 #include "powermgmt.h"
45 #include "timefuncs.h"
47 #ifdef HAVE_LCD_BITMAP
48 #include "peakmeter.h"
51 #if CONFIG_HWCODEC == MAS3507D
52 void dac_line_in(bool enable
);
55 #include "alarm_menu.h"
58 /* This flag is set by dirbrowse() if a new language is loaded */
59 bool language_changed
;
62 static bool car_adapter_mode(void)
64 return set_bool_options( str(LANG_CAR_ADAPTER_MODE
),
65 &global_settings
.car_adapter_mode
,
66 STR(LANG_SET_BOOL_YES
),
67 STR(LANG_SET_BOOL_NO
),
68 set_car_adapter_mode
);
72 static bool contrast(void)
74 return set_int( str(LANG_CONTRAST
), "", UNIT_INT
,
75 &global_settings
.contrast
,
76 lcd_set_contrast
, 1, MIN_CONTRAST_SETTING
,
77 MAX_CONTRAST_SETTING
);
81 static bool caption_backlight(void)
83 bool rc
= set_bool( str(LANG_CAPTION_BACKLIGHT
),
84 &global_settings
.caption_backlight
);
91 * Menu to set icon visibility
93 static bool show_icons(void)
95 return set_bool( str(LANG_SHOW_ICONS
), &global_settings
.show_icons
);
98 #ifdef HAVE_LCD_BITMAP
101 * Menu to set LCD Mode (normal/inverse)
103 static bool invert(void)
105 bool rc
= set_bool_options(str(LANG_INVERT
),
106 &global_settings
.invert
,
107 STR(LANG_INVERT_LCD_INVERSE
),
108 STR(LANG_INVERT_LCD_NORMAL
),
109 lcd_set_invert_display
);
114 * Menu to set Line Selector Type (Pointer/Bar)
116 static bool invert_cursor(void)
118 return set_bool_options(str(LANG_INVERT_CURSOR
),
119 &global_settings
.invert_cursor
,
120 STR(LANG_INVERT_CURSOR_BAR
),
121 STR(LANG_INVERT_CURSOR_POINTER
),
126 * Menu to turn the display+buttons by 180 degrees
128 static bool flip_display(void)
130 bool rc
= set_bool( str(LANG_FLIP_DISPLAY
),
131 &global_settings
.flip_display
);
133 button_set_flip(global_settings
.flip_display
);
134 lcd_set_flip(global_settings
.flip_display
);
140 * Menu to configure the battery display on status bar
142 static bool battery_type(void)
144 static const struct opt_items names
[] = {
145 { STR(LANG_DISPLAY_GRAPHIC
) },
146 { STR(LANG_DISPLAY_NUMERIC
) }
148 return set_option( str(LANG_BATTERY_DISPLAY
),
149 &global_settings
.battery_type
, INT
, names
, 2, NULL
);
153 * Menu to configure the volume display on status bar
155 static bool volume_type(void)
157 static const struct opt_items names
[] = {
158 { STR(LANG_DISPLAY_GRAPHIC
) },
159 { STR(LANG_DISPLAY_NUMERIC
) }
161 return set_option( str(LANG_VOLUME_DISPLAY
), &global_settings
.volume_type
,
162 INT
, names
, 2, NULL
);
166 static bool peak_meter_fps_menu(void) {
168 retval
= set_int( "Refresh rate", "/s", UNIT_PER_SEC
,
173 #endif /* PM_DEBUG */
176 * Menu to set the hold time of normal peaks.
178 static bool peak_meter_hold(void) {
180 static const struct opt_items names
[] = {
182 { "200 ms " , TALK_ID(200, UNIT_MS
) },
183 { "300 ms " , TALK_ID(300, UNIT_MS
) },
184 { "500 ms " , TALK_ID(500, UNIT_MS
) },
185 { "1 s" , TALK_ID(1, UNIT_SEC
) },
186 { "2 s" , TALK_ID(2, UNIT_SEC
) },
187 { "3 s" , TALK_ID(3, UNIT_SEC
) },
188 { "4 s" , TALK_ID(4, UNIT_SEC
) },
189 { "5 s" , TALK_ID(5, UNIT_SEC
) },
190 { "6 s" , TALK_ID(6, UNIT_SEC
) },
191 { "7 s" , TALK_ID(7, UNIT_SEC
) },
192 { "8 s" , TALK_ID(8, UNIT_SEC
) },
193 { "9 s" , TALK_ID(9, UNIT_SEC
) },
194 { "10 s" , TALK_ID(10, UNIT_SEC
) },
195 { "15 s" , TALK_ID(15, UNIT_SEC
) },
196 { "20 s" , TALK_ID(20, UNIT_SEC
) },
197 { "30 s" , TALK_ID(30, UNIT_SEC
) },
198 { "1 min" , TALK_ID(1, UNIT_MIN
) }
200 retval
= set_option( str(LANG_PM_PEAK_HOLD
),
201 &global_settings
.peak_meter_hold
, INT
, names
,
204 peak_meter_init_times(global_settings
.peak_meter_release
,
205 global_settings
.peak_meter_hold
,
206 global_settings
.peak_meter_clip_hold
);
212 * Menu to set the hold time of clips.
214 static bool peak_meter_clip_hold(void) {
217 static const struct opt_items names
[] = {
218 { STR(LANG_PM_ETERNAL
) },
219 { "1s " , TALK_ID(1, UNIT_SEC
) },
220 { "2s " , TALK_ID(2, UNIT_SEC
) },
221 { "3s " , TALK_ID(3, UNIT_SEC
) },
222 { "4s " , TALK_ID(4, UNIT_SEC
) },
223 { "5s " , TALK_ID(5, UNIT_SEC
) },
224 { "6s " , TALK_ID(6, UNIT_SEC
) },
225 { "7s " , TALK_ID(7, UNIT_SEC
) },
226 { "8s " , TALK_ID(8, UNIT_SEC
) },
227 { "9s " , TALK_ID(9, UNIT_SEC
) },
228 { "10s" , TALK_ID(10, UNIT_SEC
) },
229 { "15s" , TALK_ID(15, UNIT_SEC
) },
230 { "20s" , TALK_ID(20, UNIT_SEC
) },
231 { "25s" , TALK_ID(25, UNIT_SEC
) },
232 { "30s" , TALK_ID(30, UNIT_SEC
) },
233 { "45s" , TALK_ID(45, UNIT_SEC
) },
234 { "60s" , TALK_ID(60, UNIT_SEC
) },
235 { "90s" , TALK_ID(90, UNIT_SEC
) },
236 { "2min" , TALK_ID(2, UNIT_MIN
) },
237 { "3min" , TALK_ID(3, UNIT_MIN
) },
238 { "5min" , TALK_ID(5, UNIT_MIN
) },
239 { "10min" , TALK_ID(10, UNIT_MIN
) },
240 { "20min" , TALK_ID(20, UNIT_MIN
) },
241 { "45min" , TALK_ID(45, UNIT_MIN
) },
242 { "90min" , TALK_ID(90, UNIT_MIN
) }
244 retval
= set_option( str(LANG_PM_CLIP_HOLD
),
245 &global_settings
.peak_meter_clip_hold
, INT
, names
,
246 25, peak_meter_set_clip_hold
);
248 peak_meter_init_times(global_settings
.peak_meter_release
,
249 global_settings
.peak_meter_hold
,
250 global_settings
.peak_meter_clip_hold
);
256 * Menu to set the release time of the peak meter.
258 static bool peak_meter_release(void) {
261 /* The range of peak_meter_release is restricted so that it
262 fits into a 7 bit number. The 8th bit is used for storing
263 something else in the rtc ram.
264 Also, the max value is 0x7e, since the RTC value 0xff is reserved */
265 retval
= set_int( str(LANG_PM_RELEASE
), STR(LANG_PM_UNITS_PER_READ
),
266 &global_settings
.peak_meter_release
,
269 peak_meter_init_times(global_settings
.peak_meter_release
,
270 global_settings
.peak_meter_hold
,
271 global_settings
.peak_meter_clip_hold
);
277 * Menu to select wether the scale of the meter
278 * displays dBfs of linear values.
280 static bool peak_meter_scale(void) {
282 bool use_dbfs
= global_settings
.peak_meter_dbfs
;
283 retval
= set_bool_options(str(LANG_PM_SCALE
),
285 STR(LANG_PM_DBFS
), STR(LANG_PM_LINEAR
),
288 /* has the user really changed the scale? */
289 if (use_dbfs
!= global_settings
.peak_meter_dbfs
) {
291 /* store the change */
292 global_settings
.peak_meter_dbfs
= use_dbfs
;
293 peak_meter_set_use_dbfs(use_dbfs
);
295 /* If the user changed the scale mode the meaning of
296 peak_meter_min (peak_meter_max) has changed. Thus we have
297 to convert the values stored in global_settings. */
300 /* we only store -dBfs */
301 global_settings
.peak_meter_min
= -peak_meter_get_min() / 100;
302 global_settings
.peak_meter_max
= -peak_meter_get_max() / 100;
307 global_settings
.peak_meter_min
= peak_meter_get_min();
309 /* converting dBfs -> percent results in a precision loss.
310 I assume that the user doesn't bother that conversion
311 dBfs <-> percent isn't symmetrical for odd values but that
312 he wants 0 dBfs == 100%. Thus I 'correct' the percent value
313 resulting from dBfs -> percent manually here */
314 max
= peak_meter_get_max();
315 global_settings
.peak_meter_max
= max
< 99 ? max
: 100;
317 settings_apply_pm_range();
323 * Adjust the min value of the value range that
324 * the peak meter shall visualize.
326 static bool peak_meter_min(void) {
328 if (global_settings
.peak_meter_dbfs
) {
331 int range_max
= -global_settings
.peak_meter_max
;
332 int min
= -global_settings
.peak_meter_min
;
334 retval
= set_int(str(LANG_PM_MIN
), str(LANG_PM_DBFS
), UNIT_DB
,
335 &min
, NULL
, 1, -89, range_max
);
337 global_settings
.peak_meter_min
= - min
;
340 /* for linear scale */
342 int min
= global_settings
.peak_meter_min
;
344 retval
= set_int(str(LANG_PM_MIN
), "%", UNIT_PERCENT
,
346 1, 0, global_settings
.peak_meter_max
- 1);
348 global_settings
.peak_meter_min
= (unsigned char)min
;
351 settings_apply_pm_range();
357 * Adjust the max value of the value range that
358 * the peak meter shall visualize.
360 static bool peak_meter_max(void) {
362 if (global_settings
.peak_meter_dbfs
) {
365 int range_min
= -global_settings
.peak_meter_min
;
366 int max
= -global_settings
.peak_meter_max
;;
368 retval
= set_int(str(LANG_PM_MAX
), str(LANG_PM_DBFS
), UNIT_DB
,
369 &max
, NULL
, 1, range_min
, 0);
371 global_settings
.peak_meter_max
= - max
;
375 /* for linear scale */
377 int max
= global_settings
.peak_meter_max
;
379 retval
= set_int(str(LANG_PM_MAX
), "%", UNIT_PERCENT
,
381 1, global_settings
.peak_meter_min
+ 1, 100);
383 global_settings
.peak_meter_max
= (unsigned char)max
;
386 settings_apply_pm_range();
391 * Menu to select wether the meter is in
392 * precision or in energy saver mode
394 static bool peak_meter_performance(void) {
396 retval
= set_bool_options(str(LANG_PM_PERFORMANCE
),
397 &global_settings
.peak_meter_performance
,
398 STR(LANG_PM_HIGH_PERFORMANCE
), STR(LANG_PM_ENERGY_SAVER
),
401 if (global_settings
.peak_meter_performance
) {
410 * Menu to configure the peak meter
412 static bool peak_meter_menu(void)
417 static const struct menu_item items
[] = {
418 { ID2P(LANG_PM_RELEASE
) , peak_meter_release
},
419 { ID2P(LANG_PM_PEAK_HOLD
), peak_meter_hold
},
420 { ID2P(LANG_PM_CLIP_HOLD
), peak_meter_clip_hold
},
421 { ID2P(LANG_PM_PERFORMANCE
), peak_meter_performance
},
423 { "Refresh rate" , -1 , peak_meter_fps_menu
},
425 { ID2P(LANG_PM_SCALE
) , peak_meter_scale
},
426 { ID2P(LANG_PM_MIN
) , peak_meter_min
},
427 { ID2P(LANG_PM_MAX
) , peak_meter_max
},
430 m
=menu_init( items
, sizeof(items
) / sizeof(*items
), NULL
,
432 result
= menu_run(m
);
436 #endif /* HAVE_LCD_BITMAP */
438 static bool shuffle(void)
440 return set_bool( str(LANG_SHUFFLE
), &global_settings
.playlist_shuffle
);
443 static bool repeat_mode(void)
446 static const struct opt_items names
[] = {
448 { STR(LANG_REPEAT_ALL
) },
449 { STR(LANG_REPEAT_ONE
) }
451 int old_repeat
= global_settings
.repeat_mode
;
453 result
= set_option( str(LANG_REPEAT
), &global_settings
.repeat_mode
,
454 INT
, names
, 3, NULL
);
456 if (old_repeat
!= global_settings
.repeat_mode
)
457 mpeg_flush_and_reload_tracks();
462 static bool play_selected(void)
464 return set_bool( str(LANG_PLAY_SELECTED
), &global_settings
.play_selected
);
467 static bool dir_filter(void)
469 static const struct opt_items names
[] = {
470 { STR(LANG_FILTER_ALL
) },
471 { STR(LANG_FILTER_SUPPORTED
) },
472 { STR(LANG_FILTER_MUSIC
) },
473 { STR(LANG_FILTER_PLAYLIST
) }
475 return set_option( str(LANG_FILTER
), &global_settings
.dirfilter
, INT
,
479 static bool sort_case(void)
481 return set_bool( str(LANG_SORT_CASE
), &global_settings
.sort_case
);
484 static bool sort_file(void)
486 int oldval
= global_settings
.sort_file
;
488 static const struct opt_items names
[] = {
489 { STR(LANG_SORT_ALPHA
) },
490 { STR(LANG_SORT_DATE
) },
491 { STR(LANG_SORT_DATE_REVERSE
) },
492 { STR(LANG_SORT_TYPE
) }
494 ret
= set_option( str(LANG_SORT_FILE
), &global_settings
.sort_file
, INT
,
496 if (global_settings
.sort_file
!= oldval
)
497 reload_directory(); /* force reload if this has changed */
501 static bool sort_dir(void)
503 int oldval
= global_settings
.sort_dir
;
505 static const struct opt_items names
[] = {
506 { STR(LANG_SORT_ALPHA
) },
507 { STR(LANG_SORT_DATE
) },
508 { STR(LANG_SORT_DATE_REVERSE
) }
510 ret
= set_option( str(LANG_SORT_DIR
), &global_settings
.sort_dir
, INT
,
512 if (global_settings
.sort_dir
!= oldval
)
513 reload_directory(); /* force reload if this has changed */
517 static bool resume(void)
519 static const struct opt_items names
[] = {
520 { STR(LANG_SET_BOOL_NO
) },
521 { STR(LANG_RESUME_SETTING_ASK
) },
522 { STR(LANG_RESUME_SETTING_ASK_ONCE
) },
523 { STR(LANG_SET_BOOL_YES
) }
525 return set_option( str(LANG_RESUME
), &global_settings
.resume
, INT
,
529 static bool autocreatebookmark(void)
532 static const struct opt_items names
[] = {
533 { STR(LANG_SET_BOOL_NO
) },
534 { STR(LANG_SET_BOOL_YES
) },
535 { STR(LANG_RESUME_SETTING_ASK
) },
536 { STR(LANG_BOOKMARK_SETTINGS_RECENT_ONLY_YES
) },
537 { STR(LANG_BOOKMARK_SETTINGS_RECENT_ONLY_ASK
) }
540 retval
= set_option( str(LANG_BOOKMARK_SETTINGS_AUTOCREATE
),
541 &global_settings
.autocreatebookmark
, INT
,
543 if(global_settings
.autocreatebookmark
== BOOKMARK_RECENT_ONLY_YES
||
544 global_settings
.autocreatebookmark
== BOOKMARK_RECENT_ONLY_ASK
)
546 if(global_settings
.usemrb
== BOOKMARK_NO
)
547 global_settings
.usemrb
= BOOKMARK_YES
;
553 static bool autoloadbookmark(void)
555 static const struct opt_items names
[] = {
556 { STR(LANG_SET_BOOL_NO
) },
557 { STR(LANG_SET_BOOL_YES
) },
558 { STR(LANG_RESUME_SETTING_ASK
) }
560 return set_option( str(LANG_BOOKMARK_SETTINGS_AUTOLOAD
),
561 &global_settings
.autoloadbookmark
, INT
,
565 static bool useMRB(void)
567 static const struct opt_items names
[] = {
568 { STR(LANG_SET_BOOL_NO
) },
569 { STR(LANG_SET_BOOL_YES
) },
570 { STR(LANG_BOOKMARK_SETTINGS_UNIQUE_ONLY
) }
572 return set_option( str(LANG_BOOKMARK_SETTINGS_MAINTAIN_RECENT_BOOKMARKS
),
573 &global_settings
.usemrb
, INT
,
577 #ifdef HAVE_BACKLIGHT
578 static bool backlight_on_when_charging(void)
580 bool result
= set_bool(str(LANG_BACKLIGHT_ON_WHEN_CHARGING
),
581 &global_settings
.backlight_on_when_charging
);
582 backlight_set_on_when_charging(global_settings
.backlight_on_when_charging
);
586 static bool backlight_timer(void)
588 static const struct opt_items names
[] = {
591 { "1s ", TALK_ID(1, UNIT_SEC
) },
592 { "2s ", TALK_ID(2, UNIT_SEC
) },
593 { "3s ", TALK_ID(3, UNIT_SEC
) },
594 { "4s ", TALK_ID(4, UNIT_SEC
) },
595 { "5s ", TALK_ID(5, UNIT_SEC
) },
596 { "6s ", TALK_ID(6, UNIT_SEC
) },
597 { "7s ", TALK_ID(7, UNIT_SEC
) },
598 { "8s ", TALK_ID(8, UNIT_SEC
) },
599 { "9s ", TALK_ID(9, UNIT_SEC
) },
600 { "10s", TALK_ID(10, UNIT_SEC
) },
601 { "15s", TALK_ID(15, UNIT_SEC
) },
602 { "20s", TALK_ID(20, UNIT_SEC
) },
603 { "25s", TALK_ID(25, UNIT_SEC
) },
604 { "30s", TALK_ID(30, UNIT_SEC
) },
605 { "45s", TALK_ID(45, UNIT_SEC
) },
606 { "60s", TALK_ID(60, UNIT_SEC
) },
607 { "90s", TALK_ID(90, UNIT_SEC
) }
609 return set_option(str(LANG_BACKLIGHT
), &global_settings
.backlight_timeout
,
610 INT
, names
, 19, backlight_set_timeout
);
612 #endif /* HAVE_BACKLIGHT */
614 static bool poweroff_idle_timer(void)
616 static const struct opt_items names
[] = {
618 { "1m ", TALK_ID(1, UNIT_MIN
) },
619 { "2m ", TALK_ID(2, UNIT_MIN
) },
620 { "3m ", TALK_ID(3, UNIT_MIN
) },
621 { "4m ", TALK_ID(4, UNIT_MIN
) },
622 { "5m ", TALK_ID(5, UNIT_MIN
) },
623 { "6m ", TALK_ID(6, UNIT_MIN
) },
624 { "7m ", TALK_ID(7, UNIT_MIN
) },
625 { "8m ", TALK_ID(8, UNIT_MIN
) },
626 { "9m ", TALK_ID(9, UNIT_MIN
) },
627 { "10m", TALK_ID(10, UNIT_MIN
) },
628 { "15m", TALK_ID(15, UNIT_MIN
) },
629 { "30m", TALK_ID(30, UNIT_MIN
) },
630 { "45m", TALK_ID(45, UNIT_MIN
) },
631 { "60m", TALK_ID(60, UNIT_MIN
) }
633 return set_option(str(LANG_POWEROFF_IDLE
), &global_settings
.poweroff
,
634 INT
, names
, 15, set_poweroff_timeout
);
637 static bool scroll_speed(void)
639 return set_int(str(LANG_SCROLL
), "", UNIT_INT
,
640 &global_settings
.scroll_speed
,
641 &lcd_scroll_speed
, 1, 0, 15 );
645 static bool scroll_delay(void)
647 int dummy
= global_settings
.scroll_delay
* (HZ
/10);
648 int rc
= set_int(str(LANG_SCROLL_DELAY
), "ms", UNIT_MS
,
650 &lcd_scroll_delay
, 100, 0, 2500 );
651 global_settings
.scroll_delay
= dummy
/ (HZ
/10);
655 #ifdef HAVE_LCD_BITMAP
656 static bool scroll_step(void)
658 return set_int(str(LANG_SCROLL_STEP_EXAMPLE
), "pixels", UNIT_PIXEL
,
659 &global_settings
.scroll_step
,
660 &lcd_scroll_step
, 1, 1, LCD_WIDTH
);
664 static bool bidir_limit(void)
666 return set_int(str(LANG_BIDIR_SCROLL
), "%", UNIT_PERCENT
,
667 &global_settings
.bidir_limit
,
668 &lcd_bidir_scroll
, 25, 0, 200 );
671 #ifdef HAVE_LCD_CHARCELLS
672 static bool jump_scroll(void)
674 static const struct opt_items names
[] = {
676 { STR(LANG_ONE_TIME
) },
677 { "2", TALK_ID(2, UNIT_INT
) },
678 { "3", TALK_ID(3, UNIT_INT
) },
679 { "4", TALK_ID(4, UNIT_INT
) },
683 ret
=set_option(str(LANG_JUMP_SCROLL
), &global_settings
.jump_scroll
,
684 INT
, names
, 6, lcd_jump_scroll
);
687 static bool jump_scroll_delay(void)
689 int dummy
= global_settings
.jump_scroll_delay
* (HZ
/10);
690 int rc
= set_int(str(LANG_JUMP_SCROLL_DELAY
), "ms", UNIT_MS
,
692 &lcd_jump_scroll_delay
, 100, 0, 2500 );
693 global_settings
.jump_scroll_delay
= dummy
/ (HZ
/10);
700 * Menu to set the battery capacity
702 static bool battery_capacity(void)
704 return set_int(str(LANG_BATTERY_CAPACITY
), "mAh", UNIT_MAH
,
705 &global_settings
.battery_capacity
,
706 &set_battery_capacity
, 50, BATTERY_CAPACITY_MIN
,
707 BATTERY_CAPACITY_MAX
);
711 #ifdef HAVE_CHARGE_CTRL
712 static bool deep_discharge(void)
715 result
= set_bool( str(LANG_DISCHARGE
), &global_settings
.discharge
);
716 charge_restart_level
= global_settings
.discharge
?
717 CHARGE_RESTART_LO
: CHARGE_RESTART_HI
;
720 static bool trickle_charge(void)
723 result
= set_bool( str(LANG_TRICKLE_CHARGE
), &global_settings
.trickle_charge
);
724 enable_trickle_charge(global_settings
.trickle_charge
);
730 static bool timedate_set(void)
736 timedate
[0] = rtc_read(0x03); /* hour */
737 timedate
[1] = rtc_read(0x02); /* minute */
738 timedate
[2] = rtc_read(0x01); /* second */
739 timedate
[3] = rtc_read(0x07); /* year */
740 timedate
[4] = rtc_read(0x06); /* month */
741 timedate
[5] = rtc_read(0x05); /* day */
743 /* Make a local copy of the time struct */
744 memcpy(&tm
, get_time(), sizeof(struct tm
));
746 /* do some range checks */
747 /* This prevents problems with time/date setting after a power loss */
748 if (!valid_time(&tm
))
760 result
= set_time_screen(str(LANG_TIME
), &tm
);
762 if(tm
.tm_year
!= -1) {
768 static bool timeformat_set(void)
770 static const struct opt_items names
[] = {
771 { STR(LANG_24_HOUR_CLOCK
) },
772 { STR(LANG_12_HOUR_CLOCK
) }
774 return set_option(str(LANG_TIMEFORMAT
), &global_settings
.timeformat
,
775 INT
, names
, 2, NULL
);
780 static bool spindown(void)
782 return set_int(str(LANG_SPINDOWN
), "s", UNIT_SEC
,
783 &global_settings
.disk_spindown
,
784 ata_spindown
, 1, 3, 254 );
787 #ifdef HAVE_ATA_POWER_OFF
788 static bool poweroff(void)
790 bool rc
= set_bool(str(LANG_POWEROFF
), &global_settings
.disk_poweroff
);
791 ata_poweroff(global_settings
.disk_poweroff
);
794 #endif /* HAVE_ATA_POWEROFF */
795 #endif /* !HAVE_MMC */
797 #if CONFIG_HWCODEC == MAS3507D
798 static bool line_in(void)
800 bool rc
= set_bool(str(LANG_LINE_IN
), &global_settings
.line_in
);
801 dac_line_in(global_settings
.line_in
);
806 static bool max_files_in_dir(void)
808 return set_int(str(LANG_MAX_FILES_IN_DIR
), "", UNIT_INT
,
809 &global_settings
.max_files_in_dir
,
810 NULL
, 50, 50, 10000 );
813 static bool max_files_in_playlist(void)
815 return set_int(str(LANG_MAX_FILES_IN_PLAYLIST
), "", UNIT_INT
,
816 &global_settings
.max_files_in_playlist
,
817 NULL
, 1000, 1000, 20000 );
820 static bool buffer_margin(void)
822 return set_int(str(LANG_MP3BUFFER_MARGIN
), "s", UNIT_SEC
,
823 &global_settings
.buffer_margin
,
824 mpeg_set_buffer_margin
, 1, 0, 7 );
827 static bool ff_rewind_min_step(void)
829 static const struct opt_items names
[] = {
830 { "1s", TALK_ID(1, UNIT_SEC
) },
831 { "2s", TALK_ID(2, UNIT_SEC
) },
832 { "3s", TALK_ID(3, UNIT_SEC
) },
833 { "4s", TALK_ID(4, UNIT_SEC
) },
834 { "5s", TALK_ID(5, UNIT_SEC
) },
835 { "6s", TALK_ID(6, UNIT_SEC
) },
836 { "8s", TALK_ID(8, UNIT_SEC
) },
837 { "10s", TALK_ID(10, UNIT_SEC
) },
838 { "15s", TALK_ID(15, UNIT_SEC
) },
839 { "20s", TALK_ID(20, UNIT_SEC
) },
840 { "25s", TALK_ID(25, UNIT_SEC
) },
841 { "30s", TALK_ID(30, UNIT_SEC
) },
842 { "45s", TALK_ID(45, UNIT_SEC
) },
843 { "60s", TALK_ID(60, UNIT_SEC
) }
845 return set_option(str(LANG_FFRW_STEP
), &global_settings
.ff_rewind_min_step
,
846 INT
, names
, 14, NULL
);
849 static bool set_fade_on_stop(void)
851 return set_bool( str(LANG_FADE_ON_STOP
), &global_settings
.fade_on_stop
);
855 static bool ff_rewind_accel(void)
857 static const struct opt_items names
[] = {
859 { "2x/1s", TALK_ID(1, UNIT_SEC
) },
860 { "2x/2s", TALK_ID(2, UNIT_SEC
) },
861 { "2x/3s", TALK_ID(3, UNIT_SEC
) },
862 { "2x/4s", TALK_ID(4, UNIT_SEC
) },
863 { "2x/5s", TALK_ID(5, UNIT_SEC
) },
864 { "2x/6s", TALK_ID(6, UNIT_SEC
) },
865 { "2x/7s", TALK_ID(7, UNIT_SEC
) },
866 { "2x/8s", TALK_ID(8, UNIT_SEC
) },
867 { "2x/9s", TALK_ID(9, UNIT_SEC
) },
868 { "2x/10s", TALK_ID(10, UNIT_SEC
) },
869 { "2x/11s", TALK_ID(11, UNIT_SEC
) },
870 { "2x/12s", TALK_ID(12, UNIT_SEC
) },
871 { "2x/13s", TALK_ID(13, UNIT_SEC
) },
872 { "2x/14s", TALK_ID(14, UNIT_SEC
) },
873 { "2x/15s", TALK_ID(15, UNIT_SEC
) }
875 return set_option(str(LANG_FFRW_ACCEL
), &global_settings
.ff_rewind_accel
,
876 INT
, names
, 16, NULL
);
879 static bool browse_current(void)
881 return set_bool( str(LANG_FOLLOW
), &global_settings
.browse_current
);
884 static bool custom_wps_browse(void)
886 return rockbox_browse(ROCKBOX_DIR
, SHOW_WPS
);
889 static bool custom_cfg_browse(void)
891 return rockbox_browse(ROCKBOX_DIR
, SHOW_CFG
);
894 static bool language_browse(void)
896 language_changed
= false;
897 rockbox_browse(ROCKBOX_DIR LANG_DIR
, SHOW_LNG
);
898 return language_changed
;
901 static bool voice_menus(void)
904 bool temp
= global_settings
.talk_menu
;
905 /* work on a temp variable first, avoid "life" disabling */
906 ret
= set_bool( str(LANG_VOICE_MENU
), &temp
);
907 global_settings
.talk_menu
= temp
;
911 /* this is used 2 times below, so it saves memory to put it in global scope */
912 static const struct opt_items voice_names
[] = {
914 { STR(LANG_VOICE_NUMBER
) },
915 { STR(LANG_VOICE_SPELL
) },
916 { STR(LANG_VOICE_DIR_HOVER
) }
919 static bool voice_dirs(void)
921 return set_option( str(LANG_VOICE_DIR
),
922 &global_settings
.talk_dir
, INT
, voice_names
, 4, NULL
);
925 static bool voice_files(void)
927 int oldval
= global_settings
.talk_file
;
929 ret
= set_option( str(LANG_VOICE_FILE
),
930 &global_settings
.talk_file
, INT
, voice_names
, 4, NULL
);
931 if (oldval
!= 3 && global_settings
.talk_file
== 3)
932 { /* force reload if newly talking thumbnails,
933 because the clip presence is cached only if enabled */
939 static bool voice_menu(void)
944 static const struct menu_item items
[] = {
945 { ID2P(LANG_VOICE_MENU
), voice_menus
},
946 { ID2P(LANG_VOICE_DIR
), voice_dirs
},
947 { ID2P(LANG_VOICE_FILE
), voice_files
}
950 m
=menu_init( items
, sizeof(items
) / sizeof(*items
), NULL
,
952 result
= menu_run(m
);
957 #ifdef HAVE_LCD_BITMAP
958 static bool font_browse(void)
960 return rockbox_browse(ROCKBOX_DIR FONT_DIR
, SHOW_FONT
);
963 static bool scroll_bar(void)
965 return set_bool( str(LANG_SCROLL_BAR
), &global_settings
.scrollbar
);
968 static bool status_bar(void)
970 return set_bool( str(LANG_STATUS_BAR
), &global_settings
.statusbar
);
973 #if CONFIG_KEYPAD == RECORDER_PAD
974 static bool button_bar(void)
976 return set_bool( str(LANG_BUTTON_BAR
), &global_settings
.buttonbar
);
978 #endif /* CONFIG_KEYPAD == RECORDER_PAD */
979 #endif /* HAVE_LCD_BITMAP */
981 static bool ff_rewind_settings_menu(void)
986 static const struct menu_item items
[] = {
987 { ID2P(LANG_FFRW_STEP
), ff_rewind_min_step
},
988 { ID2P(LANG_FFRW_ACCEL
), ff_rewind_accel
},
991 m
=menu_init( items
, sizeof(items
) / sizeof(*items
), NULL
,
993 result
= menu_run(m
);
999 static bool id3_order(void)
1001 return set_bool_options( str(LANG_ID3_ORDER
),
1002 &global_settings
.id3_v1_first
,
1003 STR(LANG_ID3_V1_FIRST
),
1004 STR(LANG_ID3_V2_FIRST
),
1008 static bool playback_settings_menu(void)
1013 static const struct menu_item items
[] = {
1014 { ID2P(LANG_SHUFFLE
), shuffle
},
1015 { ID2P(LANG_REPEAT
), repeat_mode
},
1016 { ID2P(LANG_PLAY_SELECTED
), play_selected
},
1017 { ID2P(LANG_RESUME
), resume
},
1018 { ID2P(LANG_WIND_MENU
), ff_rewind_settings_menu
},
1019 { ID2P(LANG_MP3BUFFER_MARGIN
), buffer_margin
},
1020 { ID2P(LANG_FADE_ON_STOP
), set_fade_on_stop
},
1021 { ID2P(LANG_ID3_ORDER
), id3_order
},
1024 bool old_shuffle
= global_settings
.playlist_shuffle
;
1026 m
=menu_init( items
, sizeof(items
) / sizeof(*items
), NULL
,
1028 result
= menu_run(m
);
1031 if (old_shuffle
!= global_settings
.playlist_shuffle
)
1033 if (global_settings
.playlist_shuffle
)
1035 playlist_randomise(NULL
, current_tick
, true);
1039 playlist_sort(NULL
, true);
1045 static bool bookmark_settings_menu(void)
1050 static const struct menu_item items
[] = {
1051 { ID2P(LANG_BOOKMARK_SETTINGS_AUTOCREATE
), autocreatebookmark
},
1052 { ID2P(LANG_BOOKMARK_SETTINGS_AUTOLOAD
), autoloadbookmark
},
1053 { ID2P(LANG_BOOKMARK_SETTINGS_MAINTAIN_RECENT_BOOKMARKS
), useMRB
},
1056 m
=menu_init( items
, sizeof(items
) / sizeof(*items
), NULL
,
1058 result
= menu_run(m
);
1063 static bool reset_settings(void)
1069 lcd_clear_display();
1071 #ifdef HAVE_LCD_CHARCELLS
1075 lcd_puts(0,0,str(LANG_RESET_ASK_RECORDER
));
1077 lcd_puts(0,line
,str(LANG_RESET_CONFIRM
));
1078 lcd_puts(0,line
+1,str(LANG_RESET_CANCEL
));
1083 button
= button_get(true);
1088 lcd_clear_display();
1089 lcd_puts(0,1,str(LANG_RESET_DONE_CLEAR
));
1093 case SETTINGS_CANCEL
:
1094 lcd_clear_display();
1095 lcd_puts(0,1,str(LANG_RESET_DONE_CANCEL
));
1100 if(default_event_handler(button
) == SYS_USB_CONNECTED
)
1105 lcd_puts(0,0,str(LANG_RESET_DONE_SETTING
));
1111 static bool fileview_settings_menu(void)
1116 static const struct menu_item items
[] = {
1117 { ID2P(LANG_SORT_CASE
), sort_case
},
1118 { ID2P(LANG_SORT_DIR
), sort_dir
},
1119 { ID2P(LANG_SORT_FILE
), sort_file
},
1120 { ID2P(LANG_FILTER
), dir_filter
},
1121 { ID2P(LANG_FOLLOW
), browse_current
},
1122 { ID2P(LANG_SHOW_ICONS
), show_icons
},
1125 m
=menu_init( items
, sizeof(items
) / sizeof(*items
), NULL
,
1127 result
= menu_run(m
);
1133 static bool scroll_settings_menu(void)
1138 static const struct menu_item items
[] = {
1139 { ID2P(LANG_SCROLL_SPEED
), scroll_speed
},
1140 { ID2P(LANG_SCROLL_DELAY
), scroll_delay
},
1141 #ifdef HAVE_LCD_BITMAP
1142 { ID2P(LANG_SCROLL_STEP
), scroll_step
},
1144 { ID2P(LANG_BIDIR_SCROLL
), bidir_limit
},
1145 #ifdef HAVE_LCD_CHARCELLS
1146 { ID2P(LANG_JUMP_SCROLL
), jump_scroll
},
1147 { ID2P(LANG_JUMP_SCROLL_DELAY
), jump_scroll_delay
},
1151 m
=menu_init( items
, sizeof(items
) / sizeof(*items
), NULL
,
1153 result
= menu_run(m
);
1158 static bool lcd_settings_menu(void)
1163 static const struct menu_item items
[] = {
1164 #ifdef HAVE_BACKLIGHT
1165 { ID2P(LANG_BACKLIGHT
), backlight_timer
},
1166 { ID2P(LANG_BACKLIGHT_ON_WHEN_CHARGING
), backlight_on_when_charging
},
1167 { ID2P(LANG_CAPTION_BACKLIGHT
), caption_backlight
},
1169 { ID2P(LANG_CONTRAST
), contrast
},
1170 #ifdef HAVE_LCD_BITMAP
1171 { ID2P(LANG_INVERT
), invert
},
1172 { ID2P(LANG_FLIP_DISPLAY
), flip_display
},
1173 { ID2P(LANG_INVERT_CURSOR
), invert_cursor
},
1177 m
=menu_init( items
, sizeof(items
) / sizeof(*items
), NULL
,
1179 result
= menu_run(m
);
1184 #ifdef HAVE_LCD_BITMAP
1185 static bool bars_settings_menu(void)
1190 static const struct menu_item items
[] = {
1191 { ID2P(LANG_SCROLL_BAR
), scroll_bar
},
1192 { ID2P(LANG_STATUS_BAR
), status_bar
},
1193 #if CONFIG_KEYPAD == RECORDER_PAD
1194 { ID2P(LANG_BUTTON_BAR
), button_bar
},
1196 { ID2P(LANG_VOLUME_DISPLAY
), volume_type
},
1197 { ID2P(LANG_BATTERY_DISPLAY
), battery_type
},
1200 m
=menu_init( items
, sizeof(items
) / sizeof(*items
), NULL
,
1202 result
= menu_run(m
);
1209 static bool display_settings_menu(void)
1214 static const struct menu_item items
[] = {
1215 #ifdef HAVE_LCD_BITMAP
1216 { ID2P(LANG_CUSTOM_FONT
), font_browse
},
1218 { ID2P(LANG_WHILE_PLAYING
), custom_wps_browse
},
1219 { ID2P(LANG_LCD_MENU
), lcd_settings_menu
},
1220 { ID2P(LANG_SCROLL_MENU
), scroll_settings_menu
},
1221 #ifdef HAVE_LCD_BITMAP
1222 { ID2P(LANG_BARS_MENU
), bars_settings_menu
},
1223 { ID2P(LANG_PM_MENU
), peak_meter_menu
},
1227 m
=menu_init( items
, sizeof(items
) / sizeof(*items
), NULL
,
1229 result
= menu_run(m
);
1235 static bool firmware_browse(void)
1237 return rockbox_browse(ROCKBOX_DIR
, SHOW_MOD
);
1240 static bool battery_settings_menu(void)
1245 static const struct menu_item items
[] = {
1246 #ifdef HAVE_CHARGE_CTRL
1247 { ID2P(LANG_DISCHARGE
), deep_discharge
},
1248 { ID2P(LANG_TRICKLE_CHARGE
), trickle_charge
},
1251 { ID2P(LANG_BATTERY_CAPACITY
), battery_capacity
},
1253 #ifndef HAVE_CHARGE_CTRL
1254 { "Dummy", NULL
}, /* to have an entry at all, in the simulator */
1259 m
=menu_init( items
, sizeof(items
) / sizeof(*items
), NULL
,
1261 result
= menu_run(m
);
1267 static bool disk_settings_menu(void)
1272 static const struct menu_item items
[] = {
1273 { ID2P(LANG_SPINDOWN
), spindown
},
1274 #ifdef HAVE_ATA_POWER_OFF
1275 { ID2P(LANG_POWEROFF
), poweroff
},
1279 m
=menu_init( items
, sizeof(items
) / sizeof(*items
), NULL
,
1281 result
= menu_run(m
);
1285 #endif /* !HAVE_MMC */
1288 static bool time_settings_menu(void)
1293 static const struct menu_item items
[] = {
1294 { ID2P(LANG_TIME
), timedate_set
},
1295 { ID2P(LANG_TIMEFORMAT
), timeformat_set
},
1298 m
=menu_init( items
, sizeof(items
) / sizeof(*items
), NULL
,
1300 result
= menu_run(m
);
1306 static bool manage_settings_menu(void)
1311 static const struct menu_item items
[] = {
1312 { ID2P(LANG_CUSTOM_CFG
), custom_cfg_browse
},
1313 { ID2P(LANG_FIRMWARE
), firmware_browse
},
1314 { ID2P(LANG_RESET
), reset_settings
},
1315 { ID2P(LANG_SAVE_SETTINGS
), settings_save_config
},
1318 m
=menu_init( items
, sizeof(items
) / sizeof(*items
), NULL
,
1320 result
= menu_run(m
);
1325 static bool limits_settings_menu(void)
1330 static const struct menu_item items
[] = {
1331 { ID2P(LANG_MAX_FILES_IN_DIR
), max_files_in_dir
},
1332 { ID2P(LANG_MAX_FILES_IN_PLAYLIST
), max_files_in_playlist
},
1335 m
=menu_init( items
, sizeof(items
) / sizeof(*items
), NULL
,
1337 result
= menu_run(m
);
1343 static bool system_settings_menu(void)
1348 static const struct menu_item items
[] = {
1349 { ID2P(LANG_BATTERY_MENU
), battery_settings_menu
},
1351 { ID2P(LANG_DISK_MENU
), disk_settings_menu
},
1354 { ID2P(LANG_TIME_MENU
), time_settings_menu
},
1356 { ID2P(LANG_POWEROFF_IDLE
), poweroff_idle_timer
},
1357 { ID2P(LANG_SLEEP_TIMER
), sleeptimer_screen
},
1358 #ifdef HAVE_ALARM_MOD
1359 { ID2P(LANG_ALARM_MOD_ALARM_MENU
), alarm_screen
},
1361 { ID2P(LANG_LIMITS_MENU
), limits_settings_menu
},
1362 #if CONFIG_HWCODEC == MAS3507D
1363 { ID2P(LANG_LINE_IN
), line_in
},
1365 #ifdef HAVE_CHARGING
1366 { ID2P(LANG_CAR_ADAPTER_MODE
), car_adapter_mode
},
1368 { ID2P(LANG_MANAGE_MENU
), manage_settings_menu
},
1371 m
=menu_init( items
, sizeof(items
) / sizeof(*items
), NULL
,
1373 result
= menu_run(m
);
1378 bool settings_menu(void)
1383 static const struct menu_item items
[] = {
1384 { ID2P(LANG_PLAYBACK
), playback_settings_menu
},
1385 { ID2P(LANG_FILE
), fileview_settings_menu
},
1386 { ID2P(LANG_DISPLAY
), display_settings_menu
},
1387 { ID2P(LANG_SYSTEM
), system_settings_menu
},
1388 { ID2P(LANG_BOOKMARK_SETTINGS
),bookmark_settings_menu
},
1389 { ID2P(LANG_LANGUAGE
), language_browse
},
1390 { ID2P(LANG_VOICE
), voice_menu
},
1393 m
=menu_init( items
, sizeof(items
) / sizeof(*items
), NULL
,
1395 result
= menu_run(m
);