Update Beast installation instructions to use beastpatcher and remove instructions...
[kugel-rb.git] / apps / gui / statusbar.c
blobd420b963420bacbecd1a24ff34a244532a055295
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) Robert E. Hak (2002), Linus Nielsen Feltzing (2002)
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
22 #include "screen_access.h"
23 #include "font.h"
24 #include "kernel.h"
25 #include "string.h" /* for memcmp oO*/
26 #include "sprintf.h"
27 #include "sound.h"
28 #include "settings.h"
29 #include "viewport.h"
30 #if CONFIG_CODEC == SWCODEC
31 #include "metadata.h"
32 #endif
33 #include "icons.h"
34 #include "powermgmt.h"
35 #include "usb.h"
36 #include "led.h"
38 #include "status.h" /* needed for battery_state global var */
39 #include "action.h" /* for keys_locked */
40 #include "statusbar.h"
41 #ifdef HAVE_RECORDING
42 #include "audio.h"
43 #include "recording.h"
44 #include "pcm_record.h"
45 #endif
46 #include "appevents.h"
48 /* FIXME: should be removed from icon.h to avoid redefinition,
49 but still needed for compatibility with old system */
50 #define ICONS_SPACING 2
51 #define STATUSBAR_BATTERY_X_POS 0*ICONS_SPACING
52 #define STATUSBAR_BATTERY_WIDTH 18
53 #define STATUSBAR_PLUG_X_POS STATUSBAR_X_POS + \
54 STATUSBAR_BATTERY_WIDTH + \
55 ICONS_SPACING
56 #define STATUSBAR_PLUG_WIDTH 7
57 #define STATUSBAR_VOLUME_X_POS STATUSBAR_X_POS + \
58 STATUSBAR_BATTERY_WIDTH + \
59 STATUSBAR_PLUG_WIDTH + \
60 2*ICONS_SPACING
61 #define STATUSBAR_VOLUME_WIDTH 16
62 #define STATUSBAR_ENCODER_X_POS STATUSBAR_X_POS + \
63 STATUSBAR_BATTERY_WIDTH + \
64 STATUSBAR_PLUG_WIDTH + \
65 2*ICONS_SPACING - 1
66 #define STATUSBAR_ENCODER_WIDTH 18
67 #define STATUSBAR_PLAY_STATE_X_POS STATUSBAR_X_POS + \
68 STATUSBAR_BATTERY_WIDTH + \
69 STATUSBAR_PLUG_WIDTH + \
70 STATUSBAR_VOLUME_WIDTH + \
71 3*ICONS_SPACING
72 #define STATUSBAR_PLAY_STATE_WIDTH 7
73 #define STATUSBAR_PLAY_MODE_X_POS STATUSBAR_X_POS + \
74 STATUSBAR_BATTERY_WIDTH + \
75 STATUSBAR_PLUG_WIDTH + \
76 STATUSBAR_VOLUME_WIDTH + \
77 STATUSBAR_PLAY_STATE_WIDTH + \
78 4*ICONS_SPACING
79 #define STATUSBAR_PLAY_MODE_WIDTH 7
80 #define STATUSBAR_RECFREQ_X_POS STATUSBAR_X_POS + \
81 STATUSBAR_BATTERY_WIDTH + \
82 STATUSBAR_PLUG_WIDTH + \
83 STATUSBAR_VOLUME_WIDTH + \
84 STATUSBAR_PLAY_STATE_WIDTH + \
85 3*ICONS_SPACING
86 #define STATUSBAR_RECFREQ_WIDTH 12
87 #define STATUSBAR_RECCHANNELS_X_POS STATUSBAR_X_POS + \
88 STATUSBAR_BATTERY_WIDTH + \
89 STATUSBAR_PLUG_WIDTH + \
90 STATUSBAR_VOLUME_WIDTH + \
91 STATUSBAR_PLAY_STATE_WIDTH + \
92 STATUSBAR_RECFREQ_WIDTH + \
93 4*ICONS_SPACING
94 #define STATUSBAR_RECCHANNELS_WIDTH 5
95 #define STATUSBAR_SHUFFLE_X_POS STATUSBAR_X_POS + \
96 STATUSBAR_BATTERY_WIDTH + \
97 STATUSBAR_PLUG_WIDTH + \
98 STATUSBAR_VOLUME_WIDTH + \
99 STATUSBAR_PLAY_STATE_WIDTH + \
100 STATUSBAR_PLAY_MODE_WIDTH + \
101 5*ICONS_SPACING
102 #define STATUSBAR_SHUFFLE_WIDTH 7
103 #define STATUSBAR_LOCKM_X_POS STATUSBAR_X_POS + \
104 STATUSBAR_BATTERY_WIDTH + \
105 STATUSBAR_PLUG_WIDTH + \
106 STATUSBAR_VOLUME_WIDTH + \
107 STATUSBAR_PLAY_STATE_WIDTH + \
108 STATUSBAR_PLAY_MODE_WIDTH + \
109 STATUSBAR_SHUFFLE_WIDTH + \
110 6*ICONS_SPACING
111 #define STATUSBAR_LOCKM_WIDTH 5
112 #define STATUSBAR_LOCKR_X_POS STATUSBAR_X_POS + \
113 STATUSBAR_BATTERY_WIDTH + \
114 STATUSBAR_PLUG_WIDTH + \
115 STATUSBAR_VOLUME_WIDTH + \
116 STATUSBAR_PLAY_STATE_WIDTH + \
117 STATUSBAR_PLAY_MODE_WIDTH + \
118 STATUSBAR_SHUFFLE_WIDTH + \
119 STATUSBAR_LOCKM_WIDTH + \
120 7*ICONS_SPACING
121 #define STATUSBAR_LOCKR_WIDTH 5
123 #if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
124 #define STATUSBAR_DISK_WIDTH 12
125 #define STATUSBAR_DISK_X_POS(statusbar_width) statusbar_width - \
126 STATUSBAR_DISK_WIDTH
127 #else
128 #define STATUSBAR_DISK_WIDTH 0
129 #endif
130 #define STATUSBAR_TIME_X_END(statusbar_width) statusbar_width - 1 - \
131 STATUSBAR_DISK_WIDTH
132 struct gui_syncstatusbar statusbars;
134 /* Prototypes */
135 #ifdef HAVE_LCD_BITMAP
136 static void gui_statusbar_icon_battery(struct screen * display, int percent,
137 int batt_charge_step);
138 static bool gui_statusbar_icon_volume(struct gui_statusbar * bar, int volume);
139 static void gui_statusbar_icon_play_state(struct screen * display, int state);
140 static void gui_statusbar_icon_play_mode(struct screen * display, int mode);
141 static void gui_statusbar_icon_shuffle(struct screen * display);
142 static void gui_statusbar_icon_lock(struct screen * display);
143 #ifdef HAS_REMOTE_BUTTON_HOLD
144 static void gui_statusbar_icon_lock_remote(struct screen * display);
145 #endif
146 #if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
147 static void gui_statusbar_led(struct screen * display);
148 #endif
149 #ifdef HAVE_RECORDING
150 static void gui_statusbar_icon_recording_info(struct screen * display);
151 #endif
152 #if CONFIG_RTC
153 static void gui_statusbar_time(struct screen * display, struct tm *time);
154 #endif
155 #endif
157 /* End prototypes */
161 * Initializes a status bar
162 * - bar : the bar to initialize
164 static void gui_statusbar_init(struct gui_statusbar * bar)
166 bar->redraw_volume = true;
167 bar->volume_icon_switch_tick = bar->battery_icon_switch_tick = current_tick;
168 memset((void*)&(bar->lastinfo), 0, sizeof(struct status_info));
169 #if CONFIG_RTC
170 bar->last_tm_min = 0;
171 #endif
174 void gui_statusbar_draw(struct gui_statusbar * bar, bool force_redraw)
176 struct screen * display = bar->display;
178 #ifdef HAVE_LCD_CHARCELLS
179 int val;
180 (void)force_redraw; /* players always "redraw" */
181 #endif /* HAVE_LCD_CHARCELLS */
183 bar->info.battlevel = battery_level();
184 #ifdef HAVE_USB_POWER
185 bar->info.usb_inserted = usb_inserted();
186 #endif
187 #if CONFIG_CHARGING
188 bar->info.inserted = (charger_input_state == CHARGER);
189 if (bar->info.inserted)
191 bar->info.battery_state = true;
193 #if CONFIG_CHARGING >= CHARGING_MONITOR
195 /* zero battery run time if charging */
196 if (charge_state > DISCHARGING)
197 lasttime = current_tick;
199 /* animate battery if charging */
200 if ((charge_state == DISCHARGING) || (charge_state == TRICKLE))
202 bar->info.batt_charge_step = -1;
204 else
206 #else /* CONFIG_CHARGING < CHARGING_MONITOR */
207 lasttime = current_tick;
209 #endif /* CONFIG_CHARGING < CHARGING_MONITOR */
210 /* animate in (max.) 4 steps, starting near the current charge level */
211 if (TIME_AFTER(current_tick, bar->battery_icon_switch_tick))
213 if (++bar->info.batt_charge_step > 3)
214 bar->info.batt_charge_step = bar->info.battlevel / 34;
215 bar->battery_icon_switch_tick = current_tick + HZ;
219 else
220 #endif /* CONFIG_CHARGING */
222 bar->info.batt_charge_step = -1;
223 if (battery_level_safe())
224 bar->info.battery_state = true;
225 else
226 /* blink battery if level is low */
227 if (TIME_AFTER(current_tick, bar->battery_icon_switch_tick) &&
228 (bar->info.battlevel > -1))
230 bar->info.battery_state = !bar->info.battery_state;
231 bar->battery_icon_switch_tick = current_tick + HZ;
235 bar->info.volume = global_settings.volume;
236 #ifdef HAVE_LCD_BITMAP
237 bar->info.shuffle = global_settings.playlist_shuffle;
238 #ifdef HAS_BUTTON_HOLD
239 bar->info.keylock = button_hold();
240 #else
241 bar->info.keylock = is_keys_locked();
242 #endif /* HAS_BUTTON_HOLD */
243 #ifdef HAS_REMOTE_BUTTON_HOLD
244 bar->info.keylockremote = remote_button_hold();
245 #endif
246 bar->info.repeat = global_settings.repeat_mode;
247 bar->info.playmode = current_playmode();
249 #if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
250 if(!display->has_disk_led)
251 bar->info.led = led_read(HZ/2); /* delay should match polling interval */
252 #endif
253 #if CONFIG_RTC
254 bar->time = get_time();
255 #endif /* CONFIG_RTC */
257 /* only redraw if forced to, or info has changed */
258 if (force_redraw || bar->redraw_volume ||
259 #if CONFIG_RTC
260 (bar->time->tm_min != bar->last_tm_min) ||
261 #endif
262 memcmp(&(bar->info), &(bar->lastinfo), sizeof(struct status_info)))
264 struct viewport vp;
265 viewport_set_defaults(&vp, display->screen_type);
266 vp.height = STATUSBAR_HEIGHT;
267 vp.x = STATUSBAR_X_POS;
268 vp.y = STATUSBAR_Y_POS;
269 display->set_viewport(&vp);
270 display->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
271 display->fillrect(0, 0, display->getwidth(), STATUSBAR_HEIGHT);
272 display->set_drawmode(DRMODE_SOLID);
274 if (bar->info.battery_state)
275 gui_statusbar_icon_battery(display, bar->info.battlevel,
276 bar->info.batt_charge_step);
277 #ifdef HAVE_USB_POWER
278 if (bar->info.usb_inserted)
279 display->mono_bitmap(bitmap_icons_7x8[Icon_USBPlug],
280 STATUSBAR_PLUG_X_POS,
281 STATUSBAR_Y_POS, STATUSBAR_PLUG_WIDTH,
282 STATUSBAR_HEIGHT);
283 #endif /* HAVE_USB_POWER */
284 #if CONFIG_CHARGING
285 #ifdef HAVE_USB_POWER
286 else
287 #endif
288 /* draw power plug if charging */
289 if (bar->info.inserted)
290 display->mono_bitmap(bitmap_icons_7x8[Icon_Plug],
291 STATUSBAR_PLUG_X_POS,
292 STATUSBAR_Y_POS, STATUSBAR_PLUG_WIDTH,
293 STATUSBAR_HEIGHT);
294 #endif /* CONFIG_CHARGING */
295 #ifdef HAVE_RECORDING
296 /* turn off volume display in recording screen */
297 bool recscreen_on = in_recording_screen();
298 if (!recscreen_on)
299 #endif
300 bar->redraw_volume = gui_statusbar_icon_volume(bar, bar->info.volume);
301 gui_statusbar_icon_play_state(display, current_playmode() + Icon_Play);
303 #ifdef HAVE_RECORDING
304 /* If in recording screen, replace repeat mode, volume
305 and shuffle icons with recording info */
306 if (recscreen_on)
307 gui_statusbar_icon_recording_info(display);
308 else
309 #endif
311 switch (bar->info.repeat) {
312 #ifdef AB_REPEAT_ENABLE
313 case REPEAT_AB:
314 gui_statusbar_icon_play_mode(display, Icon_RepeatAB);
315 break;
316 #endif /* AB_REPEAT_ENABLE == 1 */
318 case REPEAT_ONE:
319 gui_statusbar_icon_play_mode(display, Icon_RepeatOne);
320 break;
322 case REPEAT_ALL:
323 case REPEAT_SHUFFLE:
324 gui_statusbar_icon_play_mode(display, Icon_Repeat);
325 break;
327 if (bar->info.shuffle)
328 gui_statusbar_icon_shuffle(display);
330 if (bar->info.keylock)
331 gui_statusbar_icon_lock(display);
332 #ifdef HAS_REMOTE_BUTTON_HOLD
333 if (bar->info.keylockremote)
334 gui_statusbar_icon_lock_remote(display);
335 #endif
336 #if CONFIG_RTC
337 gui_statusbar_time(display, bar->time);
338 bar->last_tm_min = bar->time->tm_min;
339 #endif /* CONFIG_RTC */
340 #if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
341 if(!display->has_disk_led && bar->info.led)
342 gui_statusbar_led(display);
343 #endif
344 display->update_viewport();
345 display->set_viewport(NULL);
346 bar->lastinfo = bar->info;
348 #endif /* HAVE_LCD_BITMAP */
351 #ifdef HAVE_LCD_CHARCELLS
352 display->icon(ICON_BATTERY, bar->info.battery_state);
354 if (bar->info.batt_charge_step > -1)
355 val = bar->info.batt_charge_step;
356 else
357 val = (bar->info.battlevel * 3 + 50) / 100;
358 display->icon(ICON_BATTERY_1, val >= 1);
359 display->icon(ICON_BATTERY_2, val >= 2);
360 display->icon(ICON_BATTERY_3, val >= 3);
362 val = 10 * (bar->info.volume - sound_min(SOUND_VOLUME))
363 / (sound_max(SOUND_VOLUME) - sound_min(SOUND_VOLUME));
364 display->icon(ICON_VOLUME, true);
365 display->icon(ICON_VOLUME_1, val >= 1);
366 display->icon(ICON_VOLUME_2, val >= 3);
367 display->icon(ICON_VOLUME_3, val >= 5);
368 display->icon(ICON_VOLUME_4, val >= 7);
369 display->icon(ICON_VOLUME_5, val >= 9);
371 display->icon(ICON_PLAY, current_playmode() == STATUS_PLAY);
372 display->icon(ICON_PAUSE, current_playmode() == STATUS_PAUSE);
374 display->icon(ICON_REPEAT, global_settings.repeat_mode != REPEAT_OFF);
375 display->icon(ICON_1, global_settings.repeat_mode == REPEAT_ONE);
377 display->icon(ICON_RECORD, record);
378 display->icon(ICON_AUDIO, audio);
379 display->icon(ICON_PARAM, param);
380 display->icon(ICON_USB, usb);
381 #endif /* HAVE_LCD_CHARCELLS */
384 #ifdef HAVE_LCD_BITMAP
385 /* from icon.c */
387 * Print battery icon to status bar
389 static void gui_statusbar_icon_battery(struct screen * display, int percent,
390 int batt_charge_step)
392 int fill, endfill;
393 char buffer[5];
394 unsigned int width, height;
395 #if LCD_DEPTH > 1
396 unsigned int prevfg = 0;
397 #endif
399 #if CONFIG_CHARGING
400 if (batt_charge_step >= 0)
402 fill = percent * (STATUSBAR_BATTERY_WIDTH-3) / 100;
403 endfill = 34 * batt_charge_step * (STATUSBAR_BATTERY_WIDTH-3) / 100;
405 else
406 #else
407 (void)batt_charge_step;
408 #endif
410 fill = endfill = (percent * (STATUSBAR_BATTERY_WIDTH-3) + 50) / 100;
413 #if CONFIG_CHARGING == CHARGING_MONITOR && !defined(SIMULATOR)
414 /* Certain charge controlled targets */
415 /* show graphical animation when charging instead of numbers */
416 if ((global_settings.battery_display) &&
417 (charge_state != CHARGING) &&
418 (percent > -1)) {
419 #else /* all others */
420 if (global_settings.battery_display && (percent > -1)) {
421 #endif
422 /* Numeric display */
423 display->setfont(FONT_SYSFIXED);
424 snprintf(buffer, sizeof(buffer), "%3d", percent);
425 display->getstringsize(buffer, &width, &height);
426 if (height <= STATUSBAR_HEIGHT)
427 display->putsxy(STATUSBAR_BATTERY_X_POS
428 + STATUSBAR_BATTERY_WIDTH / 2
429 - width/2, STATUSBAR_Y_POS, buffer);
430 display->setfont(FONT_UI);
433 else {
434 /* draw battery */
435 display->drawrect(STATUSBAR_BATTERY_X_POS, STATUSBAR_Y_POS, 17, 7);
436 display->vline(STATUSBAR_BATTERY_X_POS + 17, STATUSBAR_Y_POS + 2,
437 STATUSBAR_Y_POS + 4);
439 display->fillrect(STATUSBAR_BATTERY_X_POS + 1, STATUSBAR_Y_POS + 1,
440 fill, 5);
441 #if LCD_DEPTH > 1
442 if (display->depth > 1)
444 prevfg = display->get_foreground();
445 display->set_foreground(LCD_DARKGRAY);
447 #endif
448 display->fillrect(STATUSBAR_BATTERY_X_POS + 1 + fill,
449 STATUSBAR_Y_POS + 1, endfill - fill, 5);
450 #if LCD_DEPTH > 1
451 if (display->depth > 1)
452 display->set_foreground(prevfg);
453 #endif
456 if (percent == -1) {
457 display->setfont(FONT_SYSFIXED);
458 display->putsxy(STATUSBAR_BATTERY_X_POS + STATUSBAR_BATTERY_WIDTH / 2
459 - 4, STATUSBAR_Y_POS, "?");
460 display->setfont(FONT_UI);
465 * Print volume gauge to status bar
467 static bool gui_statusbar_icon_volume(struct gui_statusbar * bar, int volume)
469 int i;
470 int vol;
471 char buffer[4];
472 unsigned int width, height;
473 bool needs_redraw = false;
474 int type = global_settings.volume_type;
475 struct screen * display=bar->display;
476 const int minvol = sound_min(SOUND_VOLUME);
477 const int maxvol = sound_max(SOUND_VOLUME);
479 if (volume < minvol)
480 volume = minvol;
481 if (volume > maxvol)
482 volume = maxvol;
484 if (volume == minvol) {
485 display->mono_bitmap(bitmap_icons_7x8[Icon_Mute],
486 STATUSBAR_VOLUME_X_POS + STATUSBAR_VOLUME_WIDTH / 2 - 4,
487 STATUSBAR_Y_POS, 7, STATUSBAR_HEIGHT);
489 else {
490 /* We want to redraw the icon later on */
491 if (bar->last_volume != volume && bar->last_volume >= minvol) {
492 bar->volume_icon_switch_tick = current_tick + HZ;
495 /* If the timeout hasn't yet been reached, we show it numerically
496 and tell the caller that we want to be called again */
497 if (TIME_BEFORE(current_tick,bar->volume_icon_switch_tick)) {
498 type = 1;
499 needs_redraw = true;
502 /* display volume level numerical? */
503 if (type)
505 display->setfont(FONT_SYSFIXED);
506 snprintf(buffer, sizeof(buffer), "%2d", volume);
507 display->getstringsize(buffer, &width, &height);
508 if (height <= STATUSBAR_HEIGHT)
510 display->putsxy(STATUSBAR_VOLUME_X_POS
511 + STATUSBAR_VOLUME_WIDTH / 2
512 - width/2, STATUSBAR_Y_POS, buffer);
514 display->setfont(FONT_UI);
515 } else {
516 /* display volume bar */
517 vol = (volume - minvol) * 14 / (maxvol - minvol);
518 for(i=0; i < vol; i++) {
519 display->vline(STATUSBAR_VOLUME_X_POS + i,
520 STATUSBAR_Y_POS + 6 - i / 2,
521 STATUSBAR_Y_POS + 6);
525 bar->last_volume = volume;
527 return needs_redraw;
531 * Print play state to status bar
533 static void gui_statusbar_icon_play_state(struct screen * display, int state)
535 display->mono_bitmap(bitmap_icons_7x8[state], STATUSBAR_PLAY_STATE_X_POS,
536 STATUSBAR_Y_POS, STATUSBAR_PLAY_STATE_WIDTH,
537 STATUSBAR_HEIGHT);
541 * Print play mode to status bar
543 static void gui_statusbar_icon_play_mode(struct screen * display, int mode)
545 display->mono_bitmap(bitmap_icons_7x8[mode], STATUSBAR_PLAY_MODE_X_POS,
546 STATUSBAR_Y_POS, STATUSBAR_PLAY_MODE_WIDTH,
547 STATUSBAR_HEIGHT);
551 * Print shuffle mode to status bar
553 static void gui_statusbar_icon_shuffle(struct screen * display)
555 display->mono_bitmap(bitmap_icons_7x8[Icon_Shuffle],
556 STATUSBAR_SHUFFLE_X_POS, STATUSBAR_Y_POS,
557 STATUSBAR_SHUFFLE_WIDTH, STATUSBAR_HEIGHT);
561 * Print lock when keys are locked
563 static void gui_statusbar_icon_lock(struct screen * display)
565 display->mono_bitmap(bitmap_icons_5x8[Icon_Lock_Main],
566 STATUSBAR_LOCKM_X_POS, STATUSBAR_Y_POS,
567 STATUSBAR_LOCKM_WIDTH, STATUSBAR_HEIGHT);
570 #ifdef HAS_REMOTE_BUTTON_HOLD
572 * Print remote lock when remote hold is enabled
574 static void gui_statusbar_icon_lock_remote(struct screen * display)
576 display->mono_bitmap(bitmap_icons_5x8[Icon_Lock_Remote],
577 STATUSBAR_LOCKR_X_POS, STATUSBAR_Y_POS,
578 STATUSBAR_LOCKR_WIDTH, STATUSBAR_HEIGHT);
580 #endif
582 #if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
584 * no real LED: disk activity in status bar
586 static void gui_statusbar_led(struct screen * display)
588 display->mono_bitmap(bitmap_icon_disk,
589 STATUSBAR_DISK_X_POS(display->getwidth()),
590 STATUSBAR_Y_POS, STATUSBAR_DISK_WIDTH,
591 STATUSBAR_HEIGHT);
593 #endif
595 #if CONFIG_RTC
597 * Print time to status bar
599 static void gui_statusbar_time(struct screen * display, struct tm *time)
601 unsigned char buffer[6];
602 unsigned int width, height;
603 int hour, minute;
604 if ( valid_time(time) ) {
605 hour = time->tm_hour;
606 minute = time->tm_min;
607 if ( global_settings.timeformat ) { /* 12 hour clock */
608 hour %= 12;
609 if ( hour == 0 ) {
610 hour += 12;
613 snprintf(buffer, sizeof(buffer), "%02d:%02d", hour, minute);
615 else {
616 strncpy(buffer, "--:--", sizeof buffer);
618 display->setfont(FONT_SYSFIXED);
619 display->getstringsize(buffer, &width, &height);
620 if (height <= STATUSBAR_HEIGHT) {
621 display->putsxy(STATUSBAR_TIME_X_END(display->getwidth()) - width,
622 STATUSBAR_Y_POS, buffer);
624 display->setfont(FONT_UI);
627 #endif
629 #ifdef HAVE_RECORDING
630 #if CONFIG_CODEC == SWCODEC
632 * Write a number to the display using bitmaps and return new position
634 static int write_bitmap_number(struct screen * display, int value,
635 int x, int y)
637 char buf[12], *ptr;
638 snprintf(buf, sizeof(buf), "%d", value);
640 for (ptr = buf; *ptr != '\0'; ptr++, x += BM_GLYPH_WIDTH)
641 display->mono_bitmap(bitmap_glyphs_4x8[*ptr - '0'], x, y,
642 BM_GLYPH_WIDTH, STATUSBAR_HEIGHT);
643 return x;
647 * Write format info bitmaps - right justified
649 static void gui_statusbar_write_format_info(struct screen * display)
651 /* Can't fit info for sw codec targets in statusbar using FONT_SYSFIXED
652 so must use icons */
653 int rec_format = global_settings.rec_format;
654 unsigned bitrk = 0; /* compiler warns about unitialized use !! */
655 int xpos = STATUSBAR_ENCODER_X_POS;
656 int width = STATUSBAR_ENCODER_WIDTH;
657 const unsigned char *bm = bitmap_formats_18x8[rec_format];
659 if (rec_format == REC_FORMAT_MPA_L3)
661 /* Special handling for mp3 */
662 bitrk = global_settings.mp3_enc_config.bitrate;
663 bitrk = mp3_enc_bitr[bitrk];
665 width = BM_MPA_L3_M_WIDTH;
667 /* Slide 'M' to right if fewer than three digits used */
668 if (bitrk > 999)
669 bitrk = 999; /* neurotic safety check if corrupted */
670 else
672 if (bitrk < 100)
673 xpos += BM_GLYPH_WIDTH;
674 if (bitrk < 10)
675 xpos += BM_GLYPH_WIDTH;
680 /* Show bitmap - clipping right edge if needed */
681 display->mono_bitmap_part(bm, 0, 0, STATUSBAR_ENCODER_WIDTH,
682 xpos, STATUSBAR_Y_POS, width, STATUSBAR_HEIGHT);
684 if (rec_format == REC_FORMAT_MPA_L3)
686 xpos += BM_MPA_L3_M_WIDTH; /* to right of 'M' */
687 write_bitmap_number(display, bitrk, xpos, STATUSBAR_Y_POS);
692 * Write sample rate using bitmaps - left justified
694 static void gui_statusbar_write_samplerate_info(struct screen * display)
696 unsigned long samprk;
697 int xpos;
699 #ifdef SIMULATOR
700 samprk = 44100;
701 #else
702 #ifdef HAVE_SPDIF_REC
703 if (global_settings.rec_source == AUDIO_SRC_SPDIF)
704 /* Use rate in use, not current measured rate if it changed */
705 samprk = pcm_rec_sample_rate();
706 else
707 #endif
708 samprk = rec_freq_sampr[global_settings.rec_frequency];
709 #endif /* SIMULATOR */
711 samprk /= 1000;
712 if (samprk > 99)
713 samprk = 99; /* Limit to 3 glyphs */
715 xpos = write_bitmap_number(display, (unsigned)samprk,
716 STATUSBAR_RECFREQ_X_POS, STATUSBAR_Y_POS);
718 /* write the 'k' */
719 display->mono_bitmap(bitmap_glyphs_4x8[Glyph_4x8_k], xpos,
720 STATUSBAR_Y_POS, BM_GLYPH_WIDTH,
721 STATUSBAR_HEIGHT);
723 #endif /* CONFIG_CODEC == SWCODEC */
725 static void gui_statusbar_icon_recording_info(struct screen * display)
727 #if CONFIG_CODEC != SWCODEC
728 char buffer[3];
729 int width, height;
730 display->setfont(FONT_SYSFIXED);
731 #endif /* CONFIG_CODEC != SWCODEC */
733 /* Display Codec info in statusbar */
734 #if CONFIG_CODEC == SWCODEC
735 gui_statusbar_write_format_info(display);
736 #else /* !SWCODEC */
737 display->mono_bitmap(bitmap_icons_5x8[Icon_q],
738 STATUSBAR_ENCODER_X_POS + 8, STATUSBAR_Y_POS,
739 5, STATUSBAR_HEIGHT);
741 snprintf(buffer, sizeof(buffer), "%d", global_settings.rec_quality);
742 display->getstringsize(buffer, &width, &height);
743 if (height <= STATUSBAR_HEIGHT)
744 display->putsxy(STATUSBAR_ENCODER_X_POS + 13, STATUSBAR_Y_POS, buffer);
745 #endif /* CONFIG_CODEC == SWCODEC */
747 /* Display Samplerate info in statusbar */
748 #if CONFIG_CODEC == SWCODEC
749 /* SWCODEC targets use bitmaps for glyphs */
750 gui_statusbar_write_samplerate_info(display);
751 #else /* !SWCODEC */
752 /* hwcodec targets have sysfont characters */
753 #ifdef HAVE_SPDIF_REC
754 if (global_settings.rec_source == AUDIO_SRC_SPDIF)
756 /* Can't measure S/PDIF sample rate on Archos/Sim yet */
757 strncpy(buffer, "--", sizeof(buffer));
759 else
760 #endif /* HAVE_SPDIF_IN */
762 static char const * const freq_strings[12] =
763 { "44", "48", "32", "22", "24", "16" };
764 strncpy(buffer, freq_strings[global_settings.rec_frequency],
765 sizeof(buffer));
768 display->getstringsize(buffer, &width, &height);
770 if (height <= STATUSBAR_HEIGHT)
771 display->putsxy(STATUSBAR_RECFREQ_X_POS, STATUSBAR_Y_POS, buffer);
773 display->setfont(FONT_UI);
774 #endif /* CONFIG_CODEC == SWCODEC */
776 /* Display Channel status in status bar */
777 if(global_settings.rec_channels)
779 display->mono_bitmap(bitmap_icons_5x8[Icon_Mono],
780 STATUSBAR_RECCHANNELS_X_POS , STATUSBAR_Y_POS,
781 STATUSBAR_RECCHANNELS_WIDTH, STATUSBAR_HEIGHT);
783 else
785 display->mono_bitmap(bitmap_icons_5x8[Icon_Stereo],
786 STATUSBAR_RECCHANNELS_X_POS, STATUSBAR_Y_POS,
787 STATUSBAR_RECCHANNELS_WIDTH, STATUSBAR_HEIGHT);
790 #endif /* HAVE_RECORDING */
792 #endif /* HAVE_LCD_BITMAP */
794 void gui_syncstatusbar_init(struct gui_syncstatusbar * bars)
796 int i;
797 FOR_NB_SCREENS(i) {
798 gui_statusbar_init( &(bars->statusbars[i]) );
799 gui_statusbar_set_screen( &(bars->statusbars[i]), &(screens[i]) );
803 void gui_syncstatusbar_draw(struct gui_syncstatusbar * bars,
804 bool force_redraw)
806 #ifdef HAVE_LCD_BITMAP
807 if(!global_settings.statusbar)
808 return;
809 #endif /* HAVE_LCD_BITMAP */
810 int i;
811 FOR_NB_SCREENS(i) {
812 gui_statusbar_draw( &(bars->statusbars[i]), force_redraw );
816 void gui_statusbar_changed(bool enabled)
818 (void)enabled;
819 send_event(GUI_EVENT_STATUSBAR_TOGGLE, NULL);