1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2002 Bj�n Stenberg
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 ****************************************************************************/
23 #include "backlight.h"
26 #ifdef HAVE_REMOTE_LCD
27 #include "lcd-remote.h"
33 #include "mp3_playback.h"
42 #include "powermgmt.h"
52 #include "gwps-common.h"
54 #include "statusbar.h"
55 #include "screen_access.h"
56 #include "quickscreen.h"
60 #ifdef HAVE_LCD_BITMAP
61 #include <bitmaps/usblogo.h>
64 #ifdef HAVE_REMOTE_LCD
65 #include <bitmaps/remote_usblogo.h>
68 #if defined(HAVE_LCD_BITMAP)
74 #if CONFIG_CODEC == SWCODEC
82 #ifdef HAVE_LCD_BITMAP
83 #define SCROLLBAR_WIDTH 6
97 screens
[i
].backlight_on();
99 #ifdef HAVE_REMOTE_LCD
100 lcd_remote_clear_display();
101 lcd_remote_bitmap(remote_usblogo
,
102 (LCD_REMOTE_WIDTH
-BMPWIDTH_remote_usblogo
)/2,
103 (LCD_REMOTE_HEIGHT
-BMPHEIGHT_remote_usblogo
)/2,
104 BMPWIDTH_remote_usblogo
, BMPHEIGHT_remote_usblogo
);
109 #ifdef HAVE_LCD_BITMAP
110 lcd_bitmap(usblogo
, (LCD_WIDTH
-BMPWIDTH_usblogo
)/2,
111 (LCD_HEIGHT
-BMPHEIGHT_usblogo
)/2,
112 BMPWIDTH_usblogo
, BMPHEIGHT_usblogo
);
115 lcd_double_height(false);
116 lcd_puts_scroll(0, 0, "[USB Mode]");
117 status_set_param(false);
118 status_set_audio(false);
119 status_set_usb(true);
120 #endif /* HAVE_LCD_BITMAP */
122 gui_syncstatusbar_draw(&statusbars
, true);
124 while (button_get(true) & BUTTON_REL
);
126 usb_acknowledge(SYS_USB_CONNECTED_ACK
);
127 while(usb_wait_for_disconnect_w_tmo(&button_queue
, HZ
)) {
129 #ifdef HAVE_MMC /* USB-MMC bridge can report activity */
130 led(mmc_usb_active(HZ
));
131 #endif /* HAVE_MMC */
132 gui_syncstatusbar_draw(&statusbars
, false);
135 #endif /* SIMULATOR */
136 #ifdef HAVE_LCD_CHARCELLS
137 status_set_usb(false);
138 #endif /* HAVE_LCD_CHARCELLS */
140 screens
[i
].backlight_on();
141 #endif /* USB_NONE */
145 int mmc_remove_request(void)
150 screens
[i
].clear_display();
151 gui_syncsplash(1, true, str(LANG_REMOVE_MMC
));
152 if (global_settings
.talk_menu
)
153 talk_id(LANG_REMOVE_MMC
, false);
157 queue_wait_w_tmo(&button_queue
, &ev
, HZ
/2);
160 case SYS_MMC_EXTRACTED
:
161 return SYS_MMC_EXTRACTED
;
163 case SYS_USB_DISCONNECTED
:
164 return SYS_USB_DISCONNECTED
;
170 #if defined(CONFIG_CHARGING) && !defined(HAVE_POWEROFF_WHILE_CHARGING)
172 #ifdef HAVE_LCD_BITMAP
173 void charging_display_info(bool animate
)
175 unsigned char charging_logo
[36];
176 const int pox_x
= (LCD_WIDTH
- sizeof(charging_logo
)) / 2;
177 const int pox_y
= 32;
178 static unsigned phase
= 3;
183 #ifdef NEED_ATA_POWER_BATT_MEASURE
184 if (ide_powered()) /* FM and V2 can only measure when ATA power is on */
187 int battv
= battery_voltage();
188 snprintf(buf
, 32, " Batt: %d.%02dV %d%% ", battv
/ 100,
189 battv
% 100, battery_level());
193 #if CONFIG_CHARGING == CHARGING_CONTROL
195 snprintf(buf
, 32, "Charge mode:");
198 if (charge_state
== CHARGING
)
199 snprintf(buf
, 32, str(LANG_BATTERY_CHARGE
));
200 else if (charge_state
== TOPOFF
)
201 snprintf(buf
, 32, str(LANG_BATTERY_TOPOFF_CHARGE
));
202 else if (charge_state
== TRICKLE
)
203 snprintf(buf
, 32, str(LANG_BATTERY_TRICKLE_CHARGE
));
205 snprintf(buf
, 32, "not charging");
208 if (!charger_enabled
)
210 #endif /* CONFIG_CHARGING == CHARGING_CONTROL */
214 memset(charging_logo
+3, 0x00, 32);
215 charging_logo
[0] = 0x3C;
216 charging_logo
[1] = 0x24;
217 charging_logo
[2] = charging_logo
[35] = 0xFF;
220 { /* draw the outline */
222 lcd_mono_bitmap(charging_logo
, pox_x
, pox_y
+ 8, sizeof(charging_logo
), 8);
223 lcd_set_drawmode(DRMODE_FG
);
225 charging_logo
[0] = charging_logo
[1] = 0x00;
226 memset(charging_logo
+2, 0x80, 34);
227 lcd_mono_bitmap(charging_logo
, pox_x
, pox_y
, sizeof(charging_logo
), 8);
229 memset(charging_logo
+2, 0x01, 34);
230 lcd_mono_bitmap(charging_logo
, pox_x
, pox_y
+ 16, sizeof(charging_logo
), 8);
231 lcd_set_drawmode(DRMODE_SOLID
);
234 { /* animate the middle part */
235 for (i
= 3; i
<MIN(sizeof(charging_logo
)-1, phase
); i
++)
237 if ((i
-phase
) % 8 == 0)
238 { /* draw a "bubble" here */
240 bitpos
= (phase
+ i
/8) % 15; /* "bounce" effect */
242 bitpos
= 14 - bitpos
;
243 charging_logo
[i
] = 0x01 << bitpos
;
246 lcd_mono_bitmap(charging_logo
, pox_x
, pox_y
+ 8, sizeof(charging_logo
), 8);
251 #else /* not HAVE_LCD_BITMAP */
253 static unsigned char logo_chars
[5];
254 static const unsigned char logo_pattern
[] = {
255 0x07, 0x04, 0x1c, 0x14, 0x1c, 0x04, 0x07, /* char 1 */
256 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, /* char 2 */
257 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, /* char 3 */
258 0x1f, 0x01, 0x01, 0x01, 0x01, 0x01, 0x1f, /* char 4 */
261 static void logo_lock_patterns(bool on
)
267 for (i
= 0; i
< 4; i
++)
268 logo_chars
[i
] = lcd_get_locked_pattern();
269 logo_chars
[4] = '\0';
273 for (i
= 0; i
< 4; i
++)
274 lcd_unlock_pattern(logo_chars
[i
]);
278 void charging_display_info(bool animate
)
282 static unsigned phase
= 3;
285 battv
= battery_voltage();
286 snprintf(buf
, sizeof(buf
), "%s %d.%02dV", logo_chars
,
287 battv
/ 100, battv
% 100);
290 memcpy(buf
, logo_pattern
, 28); /* copy logo patterns */
292 if (!animate
) /* build the screen */
294 lcd_double_height(false);
295 lcd_puts(0, 0, "[Charging]");
297 else /* animate the logo */
299 for (i
= 3; i
< MIN(19, phase
); i
++)
301 if ((i
- phase
) % 5 == 0)
302 { /* draw a "bubble" here */
303 ypos
= (phase
+ i
/5) % 9; /* "bounce" effect */
306 buf
[5 - ypos
+ 7 * (i
/5)] |= 0x10 >> (i
%5);
312 for (i
= 0; i
< 4; i
++)
313 lcd_define_pattern(logo_chars
[i
], buf
+ 7 * i
);
315 #endif /* (not) HAVE_LCD_BITMAP */
317 /* blocks while charging, returns on event:
318 1 if charger cable was removed
319 2 if Off/Stop key was pressed
320 3 if On key was pressed
321 4 if USB was connected */
323 int charging_screen(void)
328 ide_power_enable(false); /* power down the disk, else would be spinning */
331 backlight_set_timeout(global_settings
.backlight_timeout
);
332 #ifdef HAVE_REMOTE_LCD
333 remote_backlight_set_timeout(global_settings
.remote_backlight_timeout
);
335 backlight_set_timeout_plugged(global_settings
.backlight_timeout_plugged
);
336 gui_syncstatusbar_draw(&statusbars
, true);
338 #ifdef HAVE_LCD_CHARCELLS
339 logo_lock_patterns(true);
341 charging_display_info(false);
345 gui_syncstatusbar_draw(&statusbars
, false);
346 charging_display_info(true);
347 button
= get_action(CONTEXT_STD
,HZ
/3);
348 if (button
== ACTION_STD_OK
)
350 else if (usb_detect())
352 else if (!charger_inserted())
356 #ifdef HAVE_LCD_CHARCELLS
357 logo_lock_patterns(false);
359 action_signalscreenchange();
362 #endif /* CONFIG_CHARGING && !HAVE_POWEROFF_WHILE_CHARGING */
364 #ifdef HAVE_PITCHSCREEN
366 0 if no key was pressed
367 1 if USB was connected */
369 void pitch_screen_draw(struct screen
*display
, int pitch
)
372 unsigned char buf
[32];
375 display
->clear_display();
377 if (display
->nb_lines
< 4) /* very small screen, just show the pitch value */
379 w
= snprintf((char *)buf
, sizeof(buf
), "%s: %d.%d%%",str(LANG_SYSFONT_PITCH
),
380 pitch
/ 10, pitch
% 10 );
381 display
->putsxy((display
->width
-(w
*display
->char_width
))/2,
382 display
->nb_lines
/2,buf
);
384 else /* bigger screen, show everything... */
388 ptr
= str(LANG_SYSFONT_PITCH_UP
);
389 display
->getstringsize(ptr
,&w
,&h
);
390 display
->putsxy((display
->width
-w
)/2, 0, ptr
);
391 display
->mono_bitmap(bitmap_icons_7x8
[Icon_UpArrow
],
392 display
->width
/2 - 3, h
, 7, 8);
394 /* DOWN: Pitch Down */
395 ptr
= str(LANG_SYSFONT_PITCH_DOWN
);
396 display
->getstringsize(ptr
,&w
,&h
);
397 display
->putsxy((display
->width
-w
)/2, display
->height
- h
, ptr
);
398 display
->mono_bitmap(bitmap_icons_7x8
[Icon_DownArrow
],
399 display
->width
/2 - 3, display
->height
- h
*2, 7, 8);
403 display
->getstringsize(ptr
,&w
,&h
);
404 display
->putsxy(display
->width
-w
, (display
->height
-h
)/2, ptr
);
405 display
->mono_bitmap(bitmap_icons_7x8
[Icon_FastForward
],
406 display
->width
-w
-8, (display
->height
-h
)/2, 7, 8);
410 display
->getstringsize(ptr
,&w
,&h
);
411 display
->putsxy(0, (display
->height
-h
)/2, ptr
);
412 display
->mono_bitmap(bitmap_icons_7x8
[Icon_FastBackward
],
413 w
+1, (display
->height
-h
)/2, 7, 8);
416 snprintf((char *)buf
, sizeof(buf
), str(LANG_SYSFONT_PITCH
));
417 display
->getstringsize(buf
,&w
,&h
);
418 display
->putsxy((display
->width
-w
)/2, (display
->height
/2)-h
, buf
);
420 snprintf((char *)buf
, sizeof(buf
), "%d.%d%%",
421 pitch
/ 10, pitch
% 10 );
422 display
->getstringsize(buf
,&w
,&h
);
423 display
->putsxy((display
->width
-w
)/2, display
->height
/2, buf
);
429 bool pitch_screen(void)
432 int pitch
= sound_get_pitch();
436 #if CONFIG_CODEC == SWCODEC
437 pcmbuf_set_low_latency(true);
440 action_signalscreenchange();
444 pitch_screen_draw(&screens
[i
],pitch
);
446 button
= get_action(CONTEXT_PITCHSCREEN
,TIMEOUT_BLOCK
);
448 case ACTION_PS_INC_SMALL
:
451 sound_set_pitch(pitch
);
454 case ACTION_PS_INC_BIG
:
459 sound_set_pitch(pitch
);
462 case ACTION_PS_DEC_SMALL
:
465 sound_set_pitch(pitch
);
468 case ACTION_PS_DEC_BIG
:
473 sound_set_pitch(pitch
);
476 case ACTION_PS_NUDGE_RIGHT
:
480 sound_set_pitch(pitch
);
482 pitch_screen_draw(&screens
[i
],pitch
);
485 case ACTION_PS_NUDGE_RIGHTOFF
:
487 sound_set_pitch(pitch
);
490 case ACTION_PS_NUDGE_LEFT
:
494 sound_set_pitch(pitch
);
496 pitch_screen_draw(&screens
[i
],pitch
);
499 case ACTION_PS_NUDGE_LEFTOFF
:
501 sound_set_pitch(pitch
);
504 case ACTION_PS_RESET
:
506 sound_set_pitch( pitch
);
514 if(default_event_handler(button
) == SYS_USB_CONNECTED
)
519 #if CONFIG_CODEC == SWCODEC
520 pcmbuf_set_low_latency(false);
522 lcd_setfont(FONT_UI
);
523 action_signalscreenchange();
526 #endif /* HAVE_PITCHSCREEN */
528 #ifdef HAVE_QUICKSCREEN
530 #define bool_to_int(b)\
532 #define int_to_bool(i)\
535 void quick_screen_quick_apply(struct gui_quickscreen
*qs
)
537 global_settings
.playlist_shuffle
=int_to_bool(qs
->left_option
->option
);
538 global_settings
.dirfilter
=qs
->bottom_option
->option
;
539 global_settings
.repeat_mode
=qs
->right_option
->option
;
542 bool quick_screen_quick(int button_enter
)
544 bool res
, oldshuffle
;
545 struct option_select left_option
;
546 struct option_select bottom_option
;
547 struct option_select right_option
;
548 int oldrepeat
, old_x_margin
, old_y_margin
;
550 static const struct opt_items left_items
[] = {
551 [0]={ STR(LANG_SYSFONT_OFF
) },
552 [1]={ STR(LANG_SYSFONT_ON
) }
554 static const struct opt_items bottom_items
[] = {
555 [SHOW_ALL
]={ STR(LANG_SYSFONT_FILTER_ALL
) },
556 [SHOW_SUPPORTED
]={ STR(LANG_SYSFONT_FILTER_SUPPORTED
) },
557 [SHOW_MUSIC
]={ STR(LANG_SYSFONT_FILTER_MUSIC
) },
558 [SHOW_PLAYLIST
]={ STR(LANG_SYSFONT_FILTER_PLAYLIST
) },
560 [SHOW_ID3DB
]={ STR(LANG_SYSFONT_FILTER_ID3DB
) }
563 static const struct opt_items right_items
[] = {
564 [REPEAT_OFF
]={ STR(LANG_SYSFONT_OFF
) },
565 [REPEAT_ALL
]={ STR(LANG_SYSFONT_REPEAT_ALL
) },
566 [REPEAT_ONE
]={ STR(LANG_SYSFONT_REPEAT_ONE
) },
567 [REPEAT_SHUFFLE
]={ STR(LANG_SYSFONT_SHUFFLE
) },
568 #if (AB_REPEAT_ENABLE == 1)
569 [REPEAT_AB
]={ STR(LANG_SYSFONT_REPEAT_AB
) }
572 struct gui_quickscreen qs
;
574 old_x_margin
= lcd_getxmargin();
575 old_y_margin
= lcd_getymargin();
576 lcd_setmargins(0, 0);
578 option_select_init_items(&left_option
,
579 (char *)str(LANG_SYSFONT_SHUFFLE
),
580 bool_to_int(global_settings
.playlist_shuffle
),
583 option_select_init_items(&bottom_option
,
584 (char *)str(LANG_SYSFONT_FILTER
),
585 global_settings
.dirfilter
,
587 sizeof(bottom_items
)/sizeof(struct opt_items
));
588 option_select_init_items(&right_option
,
589 (char *)str(LANG_SYSFONT_REPEAT
),
590 global_settings
.repeat_mode
,
592 sizeof(right_items
)/sizeof(struct opt_items
));
594 gui_quickscreen_init(&qs
, &left_option
, &bottom_option
, &right_option
,
595 &quick_screen_quick_apply
);
596 oldrepeat
=global_settings
.repeat_mode
;
597 oldshuffle
=global_settings
.playlist_shuffle
;
598 res
=gui_syncquickscreen_run(&qs
, button_enter
);
601 if ( oldrepeat
!= global_settings
.repeat_mode
&&
602 (audio_status() & AUDIO_STATUS_PLAY
) )
603 audio_flush_and_reload_tracks();
604 if(oldshuffle
!= global_settings
.playlist_shuffle
605 && audio_status() & AUDIO_STATUS_PLAY
)
607 #if CONFIG_CODEC == SWCODEC
608 dsp_set_replaygain(true);
610 if (global_settings
.playlist_shuffle
)
611 playlist_randomise(NULL
, current_tick
, true);
613 playlist_sort(NULL
, true);
617 lcd_setmargins(old_x_margin
, old_y_margin
);
622 void quick_screen_f3_apply(struct gui_quickscreen
*qs
)
624 global_settings
.scrollbar
=int_to_bool(qs
->left_option
->option
);
626 global_settings
.flip_display
=int_to_bool(qs
->bottom_option
->option
);
627 button_set_flip(global_settings
.flip_display
);
628 lcd_set_flip(global_settings
.flip_display
);
630 global_settings
.statusbar
=int_to_bool(qs
->right_option
->option
);
631 gui_syncstatusbar_draw(&statusbars
, true);
634 bool quick_screen_f3(int button_enter
)
637 struct option_select left_option
;
638 struct option_select bottom_option
;
639 struct option_select right_option
;
640 int old_x_margin
, old_y_margin
;
642 static const struct opt_items onoff_items
[] = {
643 [0]={ STR(LANG_SYSFONT_OFF
) },
644 [1]={ STR(LANG_SYSFONT_ON
) }
646 static const struct opt_items yesno_items
[] = {
647 [0]={ STR(LANG_SYSFONT_SET_BOOL_NO
) },
648 [1]={ STR(LANG_SYSFONT_SET_BOOL_YES
) }
651 struct gui_quickscreen qs
;
653 old_x_margin
= lcd_getxmargin();
654 old_y_margin
= lcd_getymargin();
655 lcd_setmargins(0, 0);
657 option_select_init_items(&left_option
,
658 str(LANG_SYSFONT_SCROLL_BAR
),
659 bool_to_int(global_settings
.scrollbar
),
662 option_select_init_items(&bottom_option
,
663 str(LANG_SYSFONT_FLIP_DISPLAY
),
664 bool_to_int(global_settings
.flip_display
),
667 option_select_init_items(&right_option
,
668 str(LANG_SYSFONT_STATUS_BAR
),
669 bool_to_int(global_settings
.statusbar
),
672 gui_quickscreen_init(&qs
, &left_option
, &bottom_option
, &right_option
,
673 &quick_screen_f3_apply
);
674 res
=gui_syncquickscreen_run(&qs
, button_enter
);
677 lcd_setmargins(old_x_margin
, old_y_margin
);
680 #endif /* BUTTON_F3 */
681 #endif /* CONFIG_KEYPAD in (RECORDER_PAD |IRIVER_H100_PAD | IRIVER_H300_PAD) */
683 #if defined(CONFIG_CHARGING) || defined(SIMULATOR)
684 void charging_splash(void)
686 gui_syncsplash(2*HZ
, true, (unsigned char *)str(LANG_BATTERY_CHARGE
));
687 button_clear_queue();
692 #if defined(HAVE_LCD_BITMAP) && defined (CONFIG_RTC)
694 const int dayname
[] = {
697 LANG_WEEKDAY_TUESDAY
,
698 LANG_WEEKDAY_WEDNESDAY
,
699 LANG_WEEKDAY_THURSDAY
,
701 LANG_WEEKDAY_SATURDAY
704 const int monthname
[] = {
713 LANG_MONTH_SEPTEMBER
,
719 /* little helper function for voice output */
720 static void say_time(int cursorpos
, const struct tm
*tm
)
722 static const int unit
[] = { UNIT_HOUR
, UNIT_MIN
, UNIT_SEC
, 0, 0, 0 };
725 if (!global_settings
.talk_menu
)
740 value
= tm
->tm_year
+ 1900;
747 if (cursorpos
== 4) /* month */
748 talk_id(LANG_MONTH_JANUARY
+ tm
->tm_mon
, false);
750 talk_value(value
, unit
[cursorpos
], false);
756 #define INDEX_WIDTH 2
757 bool set_time_screen(const char* string
, struct tm
*tm
)
761 int min
= 0, steps
= 0;
763 int lastcursorpos
= !cursorpos
;
764 unsigned char buffer
[19];
768 unsigned char reffub
[5];
769 unsigned int width
, height
;
770 unsigned int separator_width
, weekday_width
;
771 unsigned int line_height
, prev_line_height
;
772 int lastmode
= lcd_get_drawmode();
774 char cursor
[][3] = {{ 0, 8, 12}, {18, 8, 12}, {36, 8, 12},
775 {24, 16, 24}, {54, 16, 18}, {78, 16, 12}};
776 char daysinmonth
[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
778 int monthname_len
= 0, dayname_len
= 0;
782 #ifdef HAVE_LCD_BITMAP
783 if(global_settings
.statusbar
)
784 lcd_setmargins(0, STATUSBAR_HEIGHT
);
786 lcd_setmargins(0, 0);
789 lcd_puts_scroll(0, 0, string
);
792 /* calculate the number of days in febuary */
793 realyear
= tm
->tm_year
+ 1900;
794 if((realyear
% 4 == 0 && !(realyear
% 100 == 0)) || realyear
% 400 == 0)
799 /* fix day if month or year changed */
800 if (tm
->tm_mday
> daysinmonth
[tm
->tm_mon
])
801 tm
->tm_mday
= daysinmonth
[tm
->tm_mon
];
803 /* calculate day of week */
805 for(i
= 0; i
< tm
->tm_mon
; i
++) {
806 julianday
+= daysinmonth
[i
];
808 julianday
+= tm
->tm_mday
;
809 tm
->tm_wday
= (realyear
+ julianday
+ (realyear
- 1) / 4 -
810 (realyear
- 1) / 100 + (realyear
- 1) / 400 + 7 - 1) % 7;
812 snprintf(buffer
, sizeof(buffer
), "%02d:%02d:%02d ",
813 tm
->tm_hour
, tm
->tm_min
, tm
->tm_sec
);
814 lcd_puts(0, 1, buffer
);
816 /* recalculate the positions and offsets */
817 lcd_getstringsize(string
, &width
, &prev_line_height
);
818 lcd_getstringsize(buffer
, &width
, &line_height
);
819 lcd_getstringsize(":", &separator_width
, &height
);
822 strncpy(reffub
, buffer
, 2);
824 lcd_getstringsize(reffub
, &width
, &height
);
825 cursor
[0][INDEX_X
] = 0;
826 cursor
[0][INDEX_Y
] = prev_line_height
;
827 cursor
[0][INDEX_WIDTH
] = width
;
830 strncpy(reffub
, buffer
+ 3, 2);
832 lcd_getstringsize(reffub
, &width
, &height
);
833 cursor
[1][INDEX_X
] = cursor
[0][INDEX_WIDTH
] + separator_width
;
834 cursor
[1][INDEX_Y
] = prev_line_height
;
835 cursor
[1][INDEX_WIDTH
] = width
;
838 strncpy(reffub
, buffer
+ 6, 2);
840 lcd_getstringsize(reffub
, &width
, &height
);
841 cursor
[2][INDEX_X
] = cursor
[0][INDEX_WIDTH
] + separator_width
+
842 cursor
[1][INDEX_WIDTH
] + separator_width
;
843 cursor
[2][INDEX_Y
] = prev_line_height
;
844 cursor
[2][INDEX_WIDTH
] = width
;
846 lcd_getstringsize(buffer
, &width
, &prev_line_height
);
848 snprintf(buffer
, sizeof(buffer
), "%s %04d %s %02d ",
849 str(dayname
[tm
->tm_wday
]), tm
->tm_year
+1900,
850 str(monthname
[tm
->tm_mon
]), tm
->tm_mday
);
851 lcd_puts(0, 2, buffer
);
853 /* recalculate the positions and offsets */
854 lcd_getstringsize(buffer
, &width
, &line_height
);
856 /* store these 2 to prevent _repeated_ strlen calls */
857 monthname_len
= strlen(str(monthname
[tm
->tm_mon
]));
858 dayname_len
= strlen(str(dayname
[tm
->tm_wday
]));
861 strncpy(reffub
, buffer
, dayname_len
);
862 reffub
[dayname_len
] = '\0';
863 lcd_getstringsize(reffub
, &weekday_width
, &height
);
864 lcd_getstringsize(" ", &separator_width
, &height
);
867 strncpy(reffub
, buffer
+ dayname_len
+ 1, 4);
869 lcd_getstringsize(reffub
, &width
, &height
);
870 cursor
[3][INDEX_X
] = weekday_width
+ separator_width
;
871 cursor
[3][INDEX_Y
] = cursor
[0][INDEX_Y
] + prev_line_height
;
872 cursor
[3][INDEX_WIDTH
] = width
;
875 strncpy(reffub
, buffer
+ dayname_len
+ 6, monthname_len
);
876 reffub
[monthname_len
] = '\0';
877 lcd_getstringsize(reffub
, &width
, &height
);
878 cursor
[4][INDEX_X
] = weekday_width
+ separator_width
+
879 cursor
[3][INDEX_WIDTH
] + separator_width
;
880 cursor
[4][INDEX_Y
] = cursor
[0][INDEX_Y
] + prev_line_height
;
881 cursor
[4][INDEX_WIDTH
] = width
;
884 strncpy(reffub
, buffer
+ dayname_len
+ monthname_len
+ 7, 2);
886 lcd_getstringsize(reffub
, &width
, &height
);
887 cursor
[5][INDEX_X
] = weekday_width
+ separator_width
+
888 cursor
[3][INDEX_WIDTH
] + separator_width
+
889 cursor
[4][INDEX_WIDTH
] + separator_width
;
890 cursor
[5][INDEX_Y
] = cursor
[0][INDEX_Y
] + prev_line_height
;
891 cursor
[5][INDEX_WIDTH
] = width
;
893 lcd_set_drawmode(DRMODE_COMPLEMENT
);
894 lcd_fillrect(cursor
[cursorpos
][INDEX_X
],
895 cursor
[cursorpos
][INDEX_Y
] + lcd_getymargin(),
896 cursor
[cursorpos
][INDEX_WIDTH
],
898 lcd_set_drawmode(DRMODE_SOLID
);
900 lcd_puts(0, 4, str(LANG_TIME_SET
));
901 lcd_puts(0, 5, str(LANG_TIME_REVERT
));
902 #ifdef HAVE_LCD_BITMAP
903 gui_syncstatusbar_draw(&statusbars
, true);
907 /* calculate the minimum and maximum for the number under cursor */
908 if(cursorpos
!=lastcursorpos
) {
909 lastcursorpos
=cursorpos
;
914 valptr
= &tm
->tm_hour
;
919 valptr
= &tm
->tm_min
;
924 valptr
= &tm
->tm_sec
;
929 valptr
= &tm
->tm_year
;
934 valptr
= &tm
->tm_mon
;
938 steps
= daysinmonth
[tm
->tm_mon
];
939 valptr
= &tm
->tm_mday
;
942 say_time(cursorpos
, tm
);
945 button
= get_action(CONTEXT_SETTINGS_TIME
,HZ
/2);
947 case ACTION_STD_PREV
:
948 cursorpos
= (cursorpos
+ 6 - 1) % 6;
950 case ACTION_STD_NEXT
:
951 cursorpos
= (cursorpos
+ 6 + 1) % 6;
953 case ACTION_SETTINGS_INC
:
954 case ACTION_SETTINGS_INCREPEAT
:
955 *valptr
= (*valptr
+ steps
- min
+ 1) %
959 say_time(cursorpos
, tm
);
961 case ACTION_SETTINGS_DEC
:
962 case ACTION_SETTINGS_DECREPEAT
:
963 *valptr
= (*valptr
+ steps
- min
- 1) %
967 say_time(cursorpos
, tm
);
974 case ACTION_STD_CANCEL
:
980 if (default_event_handler(button
) == SYS_USB_CONNECTED
)
985 action_signalscreenchange();
986 lcd_set_drawmode(lastmode
);
989 #endif /* defined(HAVE_LCD_BITMAP) && defined (CONFIG_RTC) */
991 #if (CONFIG_KEYPAD == RECORDER_PAD) && !defined(HAVE_SW_POWEROFF)
992 bool shutdown_screen(void)
996 long time_entered
= current_tick
;
1000 gui_syncsplash(0, true, str(LANG_CONFIRM_SHUTDOWN
));
1002 while(!done
&& TIME_BEFORE(current_tick
,time_entered
+HZ
*2))
1004 button
= get_action(CONTEXT_STD
,HZ
);
1007 case ACTION_STD_CANCEL
:
1011 /* do nothing here, because ACTION_UNKNOWN might be caused
1012 * by timeout or button release. In case of timeout the loop
1013 * is terminated by TIME_BEFORE */
1014 case ACTION_UNKNOWN
:
1018 if(default_event_handler(button
) == SYS_USB_CONNECTED
)
1024 action_signalscreenchange();
1029 #if CONFIG_CODEC == SWCODEC
1030 #define ID3_ITEMS 13
1032 #define ID3_ITEMS 11
1035 char * id3_get_info(int selected_item
, void* data
, char *buffer
)
1037 struct mp3entry
* id3
=(struct mp3entry
*)data
;
1038 int info_no
=selected_item
/2;
1039 if(!(selected_item
%2))
1041 static const int headers
[]=
1053 #if CONFIG_CODEC == SWCODEC
1054 LANG_ID3_TRACK_GAIN
,
1055 LANG_ID3_ALBUM_GAIN
,
1059 return( str(headers
[info_no
]));
1067 case 0:/*LANG_ID3_TITLE*/
1070 case 1:/*LANG_ID3_ARTIST*/
1073 case 2:/*LANG_ID3_ALBUM*/
1076 case 3:/*LANG_ID3_TRACKNUM*/
1077 if (id3
->track_string
)
1078 info
= id3
->track_string
;
1079 else if (id3
->tracknum
)
1081 snprintf(buffer
, MAX_PATH
, "%d", id3
->tracknum
);
1085 case 4:/*LANG_ID3_GENRE*/
1086 info
= id3_get_genre(id3
);
1088 case 5:/*LANG_ID3_YEAR*/
1089 if (id3
->year_string
)
1090 info
= id3
->year_string
;
1093 snprintf(buffer
, MAX_PATH
, "%d", id3
->year
);
1097 case 6:/*LANG_ID3_LENGTH*/
1098 gui_wps_format_time(buffer
, MAX_PATH
, id3
->length
);
1101 case 7:/*LANG_ID3_PLAYLIST*/
1102 snprintf(buffer
, MAX_PATH
, "%d/%d", playlist_get_display_index(),
1106 case 8:/*LANG_ID3_BITRATE*/
1107 snprintf(buffer
, MAX_PATH
, "%d kbps%s", id3
->bitrate
,
1108 id3
->vbr
? str(LANG_ID3_VBR
) : (const unsigned char*) "");
1111 case 9:/*LANG_ID3_FRECUENCY*/
1112 snprintf(buffer
, MAX_PATH
, "%ld Hz", id3
->frequency
);
1115 #if CONFIG_CODEC == SWCODEC
1116 case 10:/*LANG_ID3_TRACK_GAIN*/
1117 info
=id3
->track_gain_string
;
1119 case 11:/*LANG_ID3_ALBUM_GAIN*/
1120 info
=id3
->album_gain_string
;
1122 case 12:/*LANG_ID3_PATH*/
1124 case 10:/*LANG_ID3_PATH*/
1130 return(str(LANG_ID3_NO_INFO
));
1135 bool browse_id3(void)
1137 struct gui_synclist id3_lists
;
1138 struct mp3entry
* id3
= audio_current_track();
1141 gui_synclist_init(&id3_lists
, &id3_get_info
, id3
, true, 2);
1142 gui_synclist_set_nb_items(&id3_lists
, ID3_ITEMS
*2);
1143 gui_synclist_draw(&id3_lists
);
1144 gui_syncstatusbar_draw(&statusbars
, true);
1145 action_signalscreenchange();
1147 gui_syncstatusbar_draw(&statusbars
, false);
1148 key
= get_action(CONTEXT_LIST
,HZ
/2);
1149 if(key
!=ACTION_NONE
&& key
!=ACTION_UNKNOWN
1150 && !gui_synclist_do_button(&id3_lists
, key
))
1152 action_signalscreenchange();
1153 return(default_event_handler(key
) == SYS_USB_CONNECTED
);
1159 bool set_rating(void)
1161 struct mp3entry
* id3
= audio_current_track();
1164 char rating_text
[20];
1166 if (!(audio_status() & AUDIO_STATUS_PLAY
)||id3
==NULL
)
1170 lcd_clear_display();
1171 lcd_puts(0, 0, str(LANG_RATING
));
1172 snprintf(rating_text
, sizeof(rating_text
), "%d", id3
->rating
);
1173 lcd_puts(0, 1, (unsigned char *)rating_text
);
1175 button
= get_action(CONTEXT_SETTINGS
,TIMEOUT_BLOCK
);
1179 case ACTION_SETTINGS_DEC
:
1180 if (id3
->rating
> 0)
1186 case ACTION_SETTINGS_INC
:
1187 if (id3
->rating
< 10)
1192 case ACTION_STD_CANCEL
:
1197 if(default_event_handler(button
) == SYS_USB_CONNECTED
)
1202 action_signalscreenchange();