Also rename as3525_codec in the e200/fuze backlight driver
[kugel-rb.git] / apps / gui / statusbar.c
blob1a264ee3d6499cd6d62f5277b27fadd464f0dc23
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 #if CONFIG_CODEC == SWCODEC
30 #include "metadata.h"
31 #endif
32 #include "icons.h"
33 #include "powermgmt.h"
34 #include "usb.h"
35 #include "led.h"
37 #include "status.h" /* needed for battery_state global var */
38 #include "action.h" /* for keys_locked */
39 #include "statusbar.h"
40 #ifdef HAVE_RECORDING
41 #include "audio.h"
42 #include "recording.h"
43 #include "pcm_record.h"
44 #endif
46 /* FIXME: should be removed from icon.h to avoid redefinition,
47 but still needed for compatibility with old system */
48 #define ICONS_SPACING 2
49 #define STATUSBAR_BATTERY_X_POS 0*ICONS_SPACING
50 #define STATUSBAR_BATTERY_WIDTH 18
51 #define STATUSBAR_PLUG_X_POS STATUSBAR_X_POS + \
52 STATUSBAR_BATTERY_WIDTH + \
53 ICONS_SPACING
54 #define STATUSBAR_PLUG_WIDTH 7
55 #define STATUSBAR_VOLUME_X_POS STATUSBAR_X_POS + \
56 STATUSBAR_BATTERY_WIDTH + \
57 STATUSBAR_PLUG_WIDTH + \
58 2*ICONS_SPACING
59 #define STATUSBAR_VOLUME_WIDTH 16
60 #define STATUSBAR_ENCODER_X_POS STATUSBAR_X_POS + \
61 STATUSBAR_BATTERY_WIDTH + \
62 STATUSBAR_PLUG_WIDTH + \
63 2*ICONS_SPACING - 1
64 #define STATUSBAR_ENCODER_WIDTH 18
65 #define STATUSBAR_PLAY_STATE_X_POS STATUSBAR_X_POS + \
66 STATUSBAR_BATTERY_WIDTH + \
67 STATUSBAR_PLUG_WIDTH + \
68 STATUSBAR_VOLUME_WIDTH + \
69 3*ICONS_SPACING
70 #define STATUSBAR_PLAY_STATE_WIDTH 7
71 #define STATUSBAR_PLAY_MODE_X_POS STATUSBAR_X_POS + \
72 STATUSBAR_BATTERY_WIDTH + \
73 STATUSBAR_PLUG_WIDTH + \
74 STATUSBAR_VOLUME_WIDTH + \
75 STATUSBAR_PLAY_STATE_WIDTH + \
76 4*ICONS_SPACING
77 #define STATUSBAR_PLAY_MODE_WIDTH 7
78 #define STATUSBAR_RECFREQ_X_POS STATUSBAR_X_POS + \
79 STATUSBAR_BATTERY_WIDTH + \
80 STATUSBAR_PLUG_WIDTH + \
81 STATUSBAR_VOLUME_WIDTH + \
82 STATUSBAR_PLAY_STATE_WIDTH + \
83 3*ICONS_SPACING
84 #define STATUSBAR_RECFREQ_WIDTH 12
85 #define STATUSBAR_RECCHANNELS_X_POS STATUSBAR_X_POS + \
86 STATUSBAR_BATTERY_WIDTH + \
87 STATUSBAR_PLUG_WIDTH + \
88 STATUSBAR_VOLUME_WIDTH + \
89 STATUSBAR_PLAY_STATE_WIDTH + \
90 STATUSBAR_RECFREQ_WIDTH + \
91 4*ICONS_SPACING
92 #define STATUSBAR_RECCHANNELS_WIDTH 5
93 #define STATUSBAR_SHUFFLE_X_POS STATUSBAR_X_POS + \
94 STATUSBAR_BATTERY_WIDTH + \
95 STATUSBAR_PLUG_WIDTH + \
96 STATUSBAR_VOLUME_WIDTH + \
97 STATUSBAR_PLAY_STATE_WIDTH + \
98 STATUSBAR_PLAY_MODE_WIDTH + \
99 5*ICONS_SPACING
100 #define STATUSBAR_SHUFFLE_WIDTH 7
101 #define STATUSBAR_LOCKM_X_POS STATUSBAR_X_POS + \
102 STATUSBAR_BATTERY_WIDTH + \
103 STATUSBAR_PLUG_WIDTH + \
104 STATUSBAR_VOLUME_WIDTH + \
105 STATUSBAR_PLAY_STATE_WIDTH + \
106 STATUSBAR_PLAY_MODE_WIDTH + \
107 STATUSBAR_SHUFFLE_WIDTH + \
108 6*ICONS_SPACING
109 #define STATUSBAR_LOCKM_WIDTH 5
110 #define STATUSBAR_LOCKR_X_POS STATUSBAR_X_POS + \
111 STATUSBAR_BATTERY_WIDTH + \
112 STATUSBAR_PLUG_WIDTH + \
113 STATUSBAR_VOLUME_WIDTH + \
114 STATUSBAR_PLAY_STATE_WIDTH + \
115 STATUSBAR_PLAY_MODE_WIDTH + \
116 STATUSBAR_SHUFFLE_WIDTH + \
117 STATUSBAR_LOCKM_WIDTH + \
118 7*ICONS_SPACING
119 #define STATUSBAR_LOCKR_WIDTH 5
121 #if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
122 #define STATUSBAR_DISK_WIDTH 12
123 #define STATUSBAR_DISK_X_POS(statusbar_width) statusbar_width - \
124 STATUSBAR_DISK_WIDTH
125 #else
126 #define STATUSBAR_DISK_WIDTH 0
127 #endif
128 #define STATUSBAR_TIME_X_END(statusbar_width) statusbar_width - 1 - \
129 STATUSBAR_DISK_WIDTH
130 struct gui_syncstatusbar statusbars;
132 /* Prototypes */
133 #ifdef HAVE_LCD_BITMAP
134 static void gui_statusbar_icon_battery(struct screen * display, int percent,
135 int batt_charge_step);
136 static bool gui_statusbar_icon_volume(struct gui_statusbar * bar, int volume);
137 static void gui_statusbar_icon_play_state(struct screen * display, int state);
138 static void gui_statusbar_icon_play_mode(struct screen * display, int mode);
139 static void gui_statusbar_icon_shuffle(struct screen * display);
140 static void gui_statusbar_icon_lock(struct screen * display);
141 #ifdef HAS_REMOTE_BUTTON_HOLD
142 static void gui_statusbar_icon_lock_remote(struct screen * display);
143 #endif
144 #if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
145 static void gui_statusbar_led(struct screen * display);
146 #endif
147 #ifdef HAVE_RECORDING
148 static void gui_statusbar_icon_recording_info(struct screen * display);
149 #endif
150 #if CONFIG_RTC
151 static void gui_statusbar_time(struct screen * display, struct tm *time);
152 #endif
153 #endif
155 /* End prototypes */
159 * Initializes a status bar
160 * - bar : the bar to initialize
162 static void gui_statusbar_init(struct gui_statusbar * bar)
164 bar->redraw_volume = true;
165 bar->volume_icon_switch_tick = bar->battery_icon_switch_tick = current_tick;
166 memset((void*)&(bar->lastinfo), 0, sizeof(struct status_info));
167 #if CONFIG_RTC
168 bar->last_tm_min = 0;
169 #endif
172 void gui_statusbar_draw(struct gui_statusbar * bar, bool force_redraw)
174 struct screen * display = bar->display;
176 #ifdef HAVE_LCD_CHARCELLS
177 int val;
178 (void)force_redraw; /* players always "redraw" */
179 #endif /* HAVE_LCD_CHARCELLS */
181 bar->info.battlevel = battery_level();
182 #ifdef HAVE_USB_POWER
183 bar->info.usb_inserted = usb_inserted();
184 #endif
185 #if CONFIG_CHARGING
186 bar->info.inserted = (charger_input_state == CHARGER);
187 if (bar->info.inserted)
189 bar->info.battery_state = true;
191 #if CONFIG_CHARGING >= CHARGING_MONITOR
193 /* zero battery run time if charging */
194 if (charge_state > DISCHARGING)
195 lasttime = current_tick;
197 /* animate battery if charging */
198 if ((charge_state == DISCHARGING) || (charge_state == TRICKLE))
200 bar->info.batt_charge_step = -1;
202 else
204 #else /* CONFIG_CHARGING < CHARGING_MONITOR */
205 lasttime = current_tick;
207 #endif /* CONFIG_CHARGING < CHARGING_MONITOR */
208 /* animate in (max.) 4 steps, starting near the current charge level */
209 if (TIME_AFTER(current_tick, bar->battery_icon_switch_tick))
211 if (++bar->info.batt_charge_step > 3)
212 bar->info.batt_charge_step = bar->info.battlevel / 34;
213 bar->battery_icon_switch_tick = current_tick + HZ;
217 else
218 #endif /* CONFIG_CHARGING */
220 bar->info.batt_charge_step = -1;
221 if (battery_level_safe())
222 bar->info.battery_state = true;
223 else
224 /* blink battery if level is low */
225 if (TIME_AFTER(current_tick, bar->battery_icon_switch_tick) &&
226 (bar->info.battlevel > -1))
228 bar->info.battery_state = !bar->info.battery_state;
229 bar->battery_icon_switch_tick = current_tick + HZ;
233 bar->info.volume = global_settings.volume;
234 #ifdef HAVE_LCD_BITMAP
235 bar->info.shuffle = global_settings.playlist_shuffle;
236 #ifdef HAS_BUTTON_HOLD
237 bar->info.keylock = button_hold();
238 #else
239 bar->info.keylock = is_keys_locked();
240 #endif /* HAS_BUTTON_HOLD */
241 #ifdef HAS_REMOTE_BUTTON_HOLD
242 bar->info.keylockremote = remote_button_hold();
243 #endif
244 bar->info.repeat = global_settings.repeat_mode;
245 bar->info.playmode = current_playmode();
247 #if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
248 if(!display->has_disk_led)
249 bar->info.led = led_read(HZ/2); /* delay should match polling interval */
250 #endif
251 #if CONFIG_RTC
252 bar->time = get_time();
253 #endif /* CONFIG_RTC */
255 /* only redraw if forced to, or info has changed */
256 if (force_redraw || bar->redraw_volume ||
257 #if CONFIG_RTC
258 (bar->time->tm_min != bar->last_tm_min) ||
259 #endif
260 memcmp(&(bar->info), &(bar->lastinfo), sizeof(struct status_info)))
262 display->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
263 display->fillrect(0, 0, display->getwidth(), STATUSBAR_HEIGHT);
264 display->set_drawmode(DRMODE_SOLID);
266 if (bar->info.battery_state)
267 gui_statusbar_icon_battery(display, bar->info.battlevel,
268 bar->info.batt_charge_step);
269 #ifdef HAVE_USB_POWER
270 if (bar->info.usb_inserted)
271 display->mono_bitmap(bitmap_icons_7x8[Icon_USBPlug],
272 STATUSBAR_PLUG_X_POS,
273 STATUSBAR_Y_POS, STATUSBAR_PLUG_WIDTH,
274 STATUSBAR_HEIGHT);
275 #endif /* HAVE_USB_POWER */
276 #if CONFIG_CHARGING
277 #ifdef HAVE_USB_POWER
278 else
279 #endif
280 /* draw power plug if charging */
281 if (bar->info.inserted)
282 display->mono_bitmap(bitmap_icons_7x8[Icon_Plug],
283 STATUSBAR_PLUG_X_POS,
284 STATUSBAR_Y_POS, STATUSBAR_PLUG_WIDTH,
285 STATUSBAR_HEIGHT);
286 #endif /* CONFIG_CHARGING */
287 #ifdef HAVE_RECORDING
288 /* turn off volume display in recording screen */
289 bool recscreen_on = in_recording_screen();
290 if (!recscreen_on)
291 #endif
292 bar->redraw_volume = gui_statusbar_icon_volume(bar, bar->info.volume);
293 gui_statusbar_icon_play_state(display, current_playmode() + Icon_Play);
295 #ifdef HAVE_RECORDING
296 /* If in recording screen, replace repeat mode, volume
297 and shuffle icons with recording info */
298 if (recscreen_on)
299 gui_statusbar_icon_recording_info(display);
300 else
301 #endif
303 switch (bar->info.repeat) {
304 #ifdef AB_REPEAT_ENABLE
305 case REPEAT_AB:
306 gui_statusbar_icon_play_mode(display, Icon_RepeatAB);
307 break;
308 #endif /* AB_REPEAT_ENABLE == 1 */
310 case REPEAT_ONE:
311 gui_statusbar_icon_play_mode(display, Icon_RepeatOne);
312 break;
314 case REPEAT_ALL:
315 case REPEAT_SHUFFLE:
316 gui_statusbar_icon_play_mode(display, Icon_Repeat);
317 break;
319 if (bar->info.shuffle)
320 gui_statusbar_icon_shuffle(display);
322 if (bar->info.keylock)
323 gui_statusbar_icon_lock(display);
324 #ifdef HAS_REMOTE_BUTTON_HOLD
325 if (bar->info.keylockremote)
326 gui_statusbar_icon_lock_remote(display);
327 #endif
328 #if CONFIG_RTC
329 gui_statusbar_time(display, bar->time);
330 bar->last_tm_min = bar->time->tm_min;
331 #endif /* CONFIG_RTC */
332 #if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
333 if(!display->has_disk_led && bar->info.led)
334 gui_statusbar_led(display);
335 #endif
336 display->update_rect(0, 0, display->getwidth(), STATUSBAR_HEIGHT);
337 bar->lastinfo = bar->info;
339 #endif /* HAVE_LCD_BITMAP */
342 #ifdef HAVE_LCD_CHARCELLS
343 display->icon(ICON_BATTERY, bar->info.battery_state);
345 if (bar->info.batt_charge_step > -1)
346 val = bar->info.batt_charge_step;
347 else
348 val = (bar->info.battlevel * 3 + 50) / 100;
349 display->icon(ICON_BATTERY_1, val >= 1);
350 display->icon(ICON_BATTERY_2, val >= 2);
351 display->icon(ICON_BATTERY_3, val >= 3);
353 val = 10 * (bar->info.volume - sound_min(SOUND_VOLUME))
354 / (sound_max(SOUND_VOLUME) - sound_min(SOUND_VOLUME));
355 display->icon(ICON_VOLUME, true);
356 display->icon(ICON_VOLUME_1, val >= 1);
357 display->icon(ICON_VOLUME_2, val >= 3);
358 display->icon(ICON_VOLUME_3, val >= 5);
359 display->icon(ICON_VOLUME_4, val >= 7);
360 display->icon(ICON_VOLUME_5, val >= 9);
362 display->icon(ICON_PLAY, current_playmode() == STATUS_PLAY);
363 display->icon(ICON_PAUSE, current_playmode() == STATUS_PAUSE);
365 display->icon(ICON_REPEAT, global_settings.repeat_mode != REPEAT_OFF);
366 display->icon(ICON_1, global_settings.repeat_mode == REPEAT_ONE);
368 display->icon(ICON_RECORD, record);
369 display->icon(ICON_AUDIO, audio);
370 display->icon(ICON_PARAM, param);
371 display->icon(ICON_USB, usb);
372 #endif /* HAVE_LCD_CHARCELLS */
375 #ifdef HAVE_LCD_BITMAP
376 /* from icon.c */
378 * Print battery icon to status bar
380 static void gui_statusbar_icon_battery(struct screen * display, int percent,
381 int batt_charge_step)
383 int fill, endfill;
384 char buffer[5];
385 unsigned int width, height;
386 #if LCD_DEPTH > 1
387 unsigned int prevfg = 0;
388 #endif
390 #if CONFIG_CHARGING
391 if (batt_charge_step >= 0)
393 fill = percent * (STATUSBAR_BATTERY_WIDTH-3) / 100;
394 endfill = 34 * batt_charge_step * (STATUSBAR_BATTERY_WIDTH-3) / 100;
396 else
397 #else
398 (void)batt_charge_step;
399 #endif
401 fill = endfill = (percent * (STATUSBAR_BATTERY_WIDTH-3) + 50) / 100;
404 #if CONFIG_CHARGING == CHARGING_MONITOR && !defined(SIMULATOR)
405 /* Certain charge controlled targets */
406 /* show graphical animation when charging instead of numbers */
407 if ((global_settings.battery_display) &&
408 (charge_state != CHARGING) &&
409 (percent > -1)) {
410 #else /* all others */
411 if (global_settings.battery_display && (percent > -1)) {
412 #endif
413 /* Numeric display */
414 display->setfont(FONT_SYSFIXED);
415 snprintf(buffer, sizeof(buffer), "%3d", percent);
416 display->getstringsize(buffer, &width, &height);
417 if (height <= STATUSBAR_HEIGHT)
418 display->putsxy(STATUSBAR_BATTERY_X_POS
419 + STATUSBAR_BATTERY_WIDTH / 2
420 - width/2, STATUSBAR_Y_POS, buffer);
421 display->setfont(FONT_UI);
424 else {
425 /* draw battery */
426 display->drawrect(STATUSBAR_BATTERY_X_POS, STATUSBAR_Y_POS, 17, 7);
427 display->vline(STATUSBAR_BATTERY_X_POS + 17, STATUSBAR_Y_POS + 2,
428 STATUSBAR_Y_POS + 4);
430 display->fillrect(STATUSBAR_BATTERY_X_POS + 1, STATUSBAR_Y_POS + 1,
431 fill, 5);
432 #if LCD_DEPTH > 1
433 if (display->depth > 1)
435 prevfg = display->get_foreground();
436 display->set_foreground(LCD_DARKGRAY);
438 #endif
439 display->fillrect(STATUSBAR_BATTERY_X_POS + 1 + fill,
440 STATUSBAR_Y_POS + 1, endfill - fill, 5);
441 #if LCD_DEPTH > 1
442 if (display->depth > 1)
443 display->set_foreground(prevfg);
444 #endif
447 if (percent == -1) {
448 display->setfont(FONT_SYSFIXED);
449 display->putsxy(STATUSBAR_BATTERY_X_POS + STATUSBAR_BATTERY_WIDTH / 2
450 - 4, STATUSBAR_Y_POS, "?");
451 display->setfont(FONT_UI);
456 * Print volume gauge to status bar
458 static bool gui_statusbar_icon_volume(struct gui_statusbar * bar, int volume)
460 int i;
461 int vol;
462 char buffer[4];
463 unsigned int width, height;
464 bool needs_redraw = false;
465 int type = global_settings.volume_type;
466 struct screen * display=bar->display;
467 const int minvol = sound_min(SOUND_VOLUME);
468 const int maxvol = sound_max(SOUND_VOLUME);
470 if (volume < minvol)
471 volume = minvol;
472 if (volume > maxvol)
473 volume = maxvol;
475 if (volume == minvol) {
476 display->mono_bitmap(bitmap_icons_7x8[Icon_Mute],
477 STATUSBAR_VOLUME_X_POS + STATUSBAR_VOLUME_WIDTH / 2 - 4,
478 STATUSBAR_Y_POS, 7, STATUSBAR_HEIGHT);
480 else {
481 /* We want to redraw the icon later on */
482 if (bar->last_volume != volume && bar->last_volume >= minvol) {
483 bar->volume_icon_switch_tick = current_tick + HZ;
486 /* If the timeout hasn't yet been reached, we show it numerically
487 and tell the caller that we want to be called again */
488 if (TIME_BEFORE(current_tick,bar->volume_icon_switch_tick)) {
489 type = 1;
490 needs_redraw = true;
493 /* display volume level numerical? */
494 if (type)
496 display->setfont(FONT_SYSFIXED);
497 snprintf(buffer, sizeof(buffer), "%2d", volume);
498 display->getstringsize(buffer, &width, &height);
499 if (height <= STATUSBAR_HEIGHT)
501 display->putsxy(STATUSBAR_VOLUME_X_POS
502 + STATUSBAR_VOLUME_WIDTH / 2
503 - width/2, STATUSBAR_Y_POS, buffer);
505 display->setfont(FONT_UI);
506 } else {
507 /* display volume bar */
508 vol = (volume - minvol) * 14 / (maxvol - minvol);
509 for(i=0; i < vol; i++) {
510 display->vline(STATUSBAR_VOLUME_X_POS + i,
511 STATUSBAR_Y_POS + 6 - i / 2,
512 STATUSBAR_Y_POS + 6);
516 bar->last_volume = volume;
518 return needs_redraw;
522 * Print play state to status bar
524 static void gui_statusbar_icon_play_state(struct screen * display, int state)
526 display->mono_bitmap(bitmap_icons_7x8[state], STATUSBAR_PLAY_STATE_X_POS,
527 STATUSBAR_Y_POS, STATUSBAR_PLAY_STATE_WIDTH,
528 STATUSBAR_HEIGHT);
532 * Print play mode to status bar
534 static void gui_statusbar_icon_play_mode(struct screen * display, int mode)
536 display->mono_bitmap(bitmap_icons_7x8[mode], STATUSBAR_PLAY_MODE_X_POS,
537 STATUSBAR_Y_POS, STATUSBAR_PLAY_MODE_WIDTH,
538 STATUSBAR_HEIGHT);
542 * Print shuffle mode to status bar
544 static void gui_statusbar_icon_shuffle(struct screen * display)
546 display->mono_bitmap(bitmap_icons_7x8[Icon_Shuffle],
547 STATUSBAR_SHUFFLE_X_POS, STATUSBAR_Y_POS,
548 STATUSBAR_SHUFFLE_WIDTH, STATUSBAR_HEIGHT);
552 * Print lock when keys are locked
554 static void gui_statusbar_icon_lock(struct screen * display)
556 display->mono_bitmap(bitmap_icons_5x8[Icon_Lock_Main],
557 STATUSBAR_LOCKM_X_POS, STATUSBAR_Y_POS,
558 STATUSBAR_LOCKM_WIDTH, STATUSBAR_HEIGHT);
561 #ifdef HAS_REMOTE_BUTTON_HOLD
563 * Print remote lock when remote hold is enabled
565 static void gui_statusbar_icon_lock_remote(struct screen * display)
567 display->mono_bitmap(bitmap_icons_5x8[Icon_Lock_Remote],
568 STATUSBAR_LOCKR_X_POS, STATUSBAR_Y_POS,
569 STATUSBAR_LOCKR_WIDTH, STATUSBAR_HEIGHT);
571 #endif
573 #if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
575 * no real LED: disk activity in status bar
577 static void gui_statusbar_led(struct screen * display)
579 display->mono_bitmap(bitmap_icon_disk,
580 STATUSBAR_DISK_X_POS(display->getwidth()),
581 STATUSBAR_Y_POS, STATUSBAR_DISK_WIDTH,
582 STATUSBAR_HEIGHT);
584 #endif
586 #if CONFIG_RTC
588 * Print time to status bar
590 static void gui_statusbar_time(struct screen * display, struct tm *time)
592 unsigned char buffer[6];
593 unsigned int width, height;
594 int hour, minute;
595 if ( valid_time(time) ) {
596 hour = time->tm_hour;
597 minute = time->tm_min;
598 if ( global_settings.timeformat ) { /* 12 hour clock */
599 hour %= 12;
600 if ( hour == 0 ) {
601 hour += 12;
604 snprintf(buffer, sizeof(buffer), "%02d:%02d", hour, minute);
606 else {
607 strncpy(buffer, "--:--", sizeof buffer);
609 display->setfont(FONT_SYSFIXED);
610 display->getstringsize(buffer, &width, &height);
611 if (height <= STATUSBAR_HEIGHT) {
612 display->putsxy(STATUSBAR_TIME_X_END(display->getwidth()) - width,
613 STATUSBAR_Y_POS, buffer);
615 display->setfont(FONT_UI);
618 #endif
620 #ifdef HAVE_RECORDING
621 #if CONFIG_CODEC == SWCODEC
623 * Write a number to the display using bitmaps and return new position
625 static int write_bitmap_number(struct screen * display, int value,
626 int x, int y)
628 char buf[12], *ptr;
629 snprintf(buf, sizeof(buf), "%d", value);
631 for (ptr = buf; *ptr != '\0'; ptr++, x += BM_GLYPH_WIDTH)
632 display->mono_bitmap(bitmap_glyphs_4x8[*ptr - '0'], x, y,
633 BM_GLYPH_WIDTH, STATUSBAR_HEIGHT);
634 return x;
638 * Write format info bitmaps - right justified
640 static void gui_statusbar_write_format_info(struct screen * display)
642 /* Can't fit info for sw codec targets in statusbar using FONT_SYSFIXED
643 so must use icons */
644 int rec_format = global_settings.rec_format;
645 unsigned bitrk = 0; /* compiler warns about unitialized use !! */
646 int xpos = STATUSBAR_ENCODER_X_POS;
647 int width = STATUSBAR_ENCODER_WIDTH;
648 const unsigned char *bm = bitmap_formats_18x8[rec_format];
650 if (rec_format == REC_FORMAT_MPA_L3)
652 /* Special handling for mp3 */
653 bitrk = global_settings.mp3_enc_config.bitrate;
654 bitrk = mp3_enc_bitr[bitrk];
656 width = BM_MPA_L3_M_WIDTH;
658 /* Slide 'M' to right if fewer than three digits used */
659 if (bitrk > 999)
660 bitrk = 999; /* neurotic safety check if corrupted */
661 else
663 if (bitrk < 100)
664 xpos += BM_GLYPH_WIDTH;
665 if (bitrk < 10)
666 xpos += BM_GLYPH_WIDTH;
671 /* Show bitmap - clipping right edge if needed */
672 display->mono_bitmap_part(bm, 0, 0, STATUSBAR_ENCODER_WIDTH,
673 xpos, STATUSBAR_Y_POS, width, STATUSBAR_HEIGHT);
675 if (rec_format == REC_FORMAT_MPA_L3)
677 xpos += BM_MPA_L3_M_WIDTH; /* to right of 'M' */
678 write_bitmap_number(display, bitrk, xpos, STATUSBAR_Y_POS);
683 * Write sample rate using bitmaps - left justified
685 static void gui_statusbar_write_samplerate_info(struct screen * display)
687 unsigned long samprk;
688 int xpos;
690 #ifdef SIMULATOR
691 samprk = 44100;
692 #else
693 #ifdef HAVE_SPDIF_REC
694 if (global_settings.rec_source == AUDIO_SRC_SPDIF)
695 /* Use rate in use, not current measured rate if it changed */
696 samprk = pcm_rec_sample_rate();
697 else
698 #endif
699 samprk = rec_freq_sampr[global_settings.rec_frequency];
700 #endif /* SIMULATOR */
702 samprk /= 1000;
703 if (samprk > 99)
704 samprk = 99; /* Limit to 3 glyphs */
706 xpos = write_bitmap_number(display, (unsigned)samprk,
707 STATUSBAR_RECFREQ_X_POS, STATUSBAR_Y_POS);
709 /* write the 'k' */
710 display->mono_bitmap(bitmap_glyphs_4x8[Glyph_4x8_k], xpos,
711 STATUSBAR_Y_POS, BM_GLYPH_WIDTH,
712 STATUSBAR_HEIGHT);
714 #endif /* CONFIG_CODEC == SWCODEC */
716 static void gui_statusbar_icon_recording_info(struct screen * display)
718 #if CONFIG_CODEC != SWCODEC
719 char buffer[3];
720 int width, height;
721 display->setfont(FONT_SYSFIXED);
722 #endif /* CONFIG_CODEC != SWCODEC */
724 /* Display Codec info in statusbar */
725 #if CONFIG_CODEC == SWCODEC
726 gui_statusbar_write_format_info(display);
727 #else /* !SWCODEC */
728 display->mono_bitmap(bitmap_icons_5x8[Icon_q],
729 STATUSBAR_ENCODER_X_POS + 8, STATUSBAR_Y_POS,
730 5, STATUSBAR_HEIGHT);
732 snprintf(buffer, sizeof(buffer), "%d", global_settings.rec_quality);
733 display->getstringsize(buffer, &width, &height);
734 if (height <= STATUSBAR_HEIGHT)
735 display->putsxy(STATUSBAR_ENCODER_X_POS + 13, STATUSBAR_Y_POS, buffer);
736 #endif /* CONFIG_CODEC == SWCODEC */
738 /* Display Samplerate info in statusbar */
739 #if CONFIG_CODEC == SWCODEC
740 /* SWCODEC targets use bitmaps for glyphs */
741 gui_statusbar_write_samplerate_info(display);
742 #else /* !SWCODEC */
743 /* hwcodec targets have sysfont characters */
744 #ifdef HAVE_SPDIF_REC
745 if (global_settings.rec_source == AUDIO_SRC_SPDIF)
747 /* Can't measure S/PDIF sample rate on Archos/Sim yet */
748 strncpy(buffer, "--", sizeof(buffer));
750 else
751 #endif /* HAVE_SPDIF_IN */
753 static char const * const freq_strings[12] =
754 { "44", "48", "32", "22", "24", "16" };
755 strncpy(buffer, freq_strings[global_settings.rec_frequency],
756 sizeof(buffer));
759 display->getstringsize(buffer, &width, &height);
761 if (height <= STATUSBAR_HEIGHT)
762 display->putsxy(STATUSBAR_RECFREQ_X_POS, STATUSBAR_Y_POS, buffer);
764 display->setfont(FONT_UI);
765 #endif /* CONFIG_CODEC == SWCODEC */
767 /* Display Channel status in status bar */
768 if(global_settings.rec_channels)
770 display->mono_bitmap(bitmap_icons_5x8[Icon_Mono],
771 STATUSBAR_RECCHANNELS_X_POS , STATUSBAR_Y_POS,
772 STATUSBAR_RECCHANNELS_WIDTH, STATUSBAR_HEIGHT);
774 else
776 display->mono_bitmap(bitmap_icons_5x8[Icon_Stereo],
777 STATUSBAR_RECCHANNELS_X_POS, STATUSBAR_Y_POS,
778 STATUSBAR_RECCHANNELS_WIDTH, STATUSBAR_HEIGHT);
781 #endif /* HAVE_RECORDING */
783 #endif /* HAVE_LCD_BITMAP */
785 void gui_syncstatusbar_init(struct gui_syncstatusbar * bars)
787 int i;
788 FOR_NB_SCREENS(i) {
789 gui_statusbar_init( &(bars->statusbars[i]) );
790 gui_statusbar_set_screen( &(bars->statusbars[i]), &(screens[i]) );
794 void gui_syncstatusbar_draw(struct gui_syncstatusbar * bars,
795 bool force_redraw)
797 #ifdef HAVE_LCD_BITMAP
798 if(!global_settings.statusbar)
799 return;
800 #endif /* HAVE_LCD_BITMAP */
801 int i;
802 FOR_NB_SCREENS(i) {
803 gui_statusbar_draw( &(bars->statusbars[i]), force_redraw );
807 int gui_statusbar_height(void)
809 return global_settings.statusbar ? STATUSBAR_HEIGHT : 0;