* combine i2c_ack and i2c_outb
[kugel-rb.git] / apps / gui / statusbar.c
blobfc0b9637cf546c9b9903be3c5553bfbd83aaba8a
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
47 /* FIXME: should be removed from icon.h to avoid redefinition,
48 but still needed for compatibility with old system */
49 #define ICONS_SPACING 2
50 #define STATUSBAR_BATTERY_X_POS 0*ICONS_SPACING
51 #define STATUSBAR_BATTERY_WIDTH 18
52 #define STATUSBAR_PLUG_X_POS STATUSBAR_X_POS + \
53 STATUSBAR_BATTERY_WIDTH + \
54 ICONS_SPACING
55 #define STATUSBAR_PLUG_WIDTH 7
56 #define STATUSBAR_VOLUME_X_POS STATUSBAR_X_POS + \
57 STATUSBAR_BATTERY_WIDTH + \
58 STATUSBAR_PLUG_WIDTH + \
59 2*ICONS_SPACING
60 #define STATUSBAR_VOLUME_WIDTH 16
61 #define STATUSBAR_ENCODER_X_POS STATUSBAR_X_POS + \
62 STATUSBAR_BATTERY_WIDTH + \
63 STATUSBAR_PLUG_WIDTH + \
64 2*ICONS_SPACING - 1
65 #define STATUSBAR_ENCODER_WIDTH 18
66 #define STATUSBAR_PLAY_STATE_X_POS STATUSBAR_X_POS + \
67 STATUSBAR_BATTERY_WIDTH + \
68 STATUSBAR_PLUG_WIDTH + \
69 STATUSBAR_VOLUME_WIDTH + \
70 3*ICONS_SPACING
71 #define STATUSBAR_PLAY_STATE_WIDTH 7
72 #define STATUSBAR_PLAY_MODE_X_POS STATUSBAR_X_POS + \
73 STATUSBAR_BATTERY_WIDTH + \
74 STATUSBAR_PLUG_WIDTH + \
75 STATUSBAR_VOLUME_WIDTH + \
76 STATUSBAR_PLAY_STATE_WIDTH + \
77 4*ICONS_SPACING
78 #define STATUSBAR_PLAY_MODE_WIDTH 7
79 #define STATUSBAR_RECFREQ_X_POS STATUSBAR_X_POS + \
80 STATUSBAR_BATTERY_WIDTH + \
81 STATUSBAR_PLUG_WIDTH + \
82 STATUSBAR_VOLUME_WIDTH + \
83 STATUSBAR_PLAY_STATE_WIDTH + \
84 3*ICONS_SPACING
85 #define STATUSBAR_RECFREQ_WIDTH 12
86 #define STATUSBAR_RECCHANNELS_X_POS STATUSBAR_X_POS + \
87 STATUSBAR_BATTERY_WIDTH + \
88 STATUSBAR_PLUG_WIDTH + \
89 STATUSBAR_VOLUME_WIDTH + \
90 STATUSBAR_PLAY_STATE_WIDTH + \
91 STATUSBAR_RECFREQ_WIDTH + \
92 4*ICONS_SPACING
93 #define STATUSBAR_RECCHANNELS_WIDTH 5
94 #define STATUSBAR_SHUFFLE_X_POS STATUSBAR_X_POS + \
95 STATUSBAR_BATTERY_WIDTH + \
96 STATUSBAR_PLUG_WIDTH + \
97 STATUSBAR_VOLUME_WIDTH + \
98 STATUSBAR_PLAY_STATE_WIDTH + \
99 STATUSBAR_PLAY_MODE_WIDTH + \
100 5*ICONS_SPACING
101 #define STATUSBAR_SHUFFLE_WIDTH 7
102 #define STATUSBAR_LOCKM_X_POS STATUSBAR_X_POS + \
103 STATUSBAR_BATTERY_WIDTH + \
104 STATUSBAR_PLUG_WIDTH + \
105 STATUSBAR_VOLUME_WIDTH + \
106 STATUSBAR_PLAY_STATE_WIDTH + \
107 STATUSBAR_PLAY_MODE_WIDTH + \
108 STATUSBAR_SHUFFLE_WIDTH + \
109 6*ICONS_SPACING
110 #define STATUSBAR_LOCKM_WIDTH 5
111 #define STATUSBAR_LOCKR_X_POS STATUSBAR_X_POS + \
112 STATUSBAR_BATTERY_WIDTH + \
113 STATUSBAR_PLUG_WIDTH + \
114 STATUSBAR_VOLUME_WIDTH + \
115 STATUSBAR_PLAY_STATE_WIDTH + \
116 STATUSBAR_PLAY_MODE_WIDTH + \
117 STATUSBAR_SHUFFLE_WIDTH + \
118 STATUSBAR_LOCKM_WIDTH + \
119 7*ICONS_SPACING
120 #define STATUSBAR_LOCKR_WIDTH 5
122 #if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
123 #define STATUSBAR_DISK_WIDTH 12
124 #define STATUSBAR_DISK_X_POS(statusbar_width) statusbar_width - \
125 STATUSBAR_DISK_WIDTH
126 #else
127 #define STATUSBAR_DISK_WIDTH 0
128 #endif
129 #define STATUSBAR_TIME_X_END(statusbar_width) statusbar_width - 1 - \
130 STATUSBAR_DISK_WIDTH
131 struct gui_syncstatusbar statusbars;
133 /* Prototypes */
134 #ifdef HAVE_LCD_BITMAP
135 static void gui_statusbar_icon_battery(struct screen * display, int percent,
136 int batt_charge_step);
137 static bool gui_statusbar_icon_volume(struct gui_statusbar * bar, int volume);
138 static void gui_statusbar_icon_play_state(struct screen * display, int state);
139 static void gui_statusbar_icon_play_mode(struct screen * display, int mode);
140 static void gui_statusbar_icon_shuffle(struct screen * display);
141 static void gui_statusbar_icon_lock(struct screen * display);
142 #ifdef HAS_REMOTE_BUTTON_HOLD
143 static void gui_statusbar_icon_lock_remote(struct screen * display);
144 #endif
145 #if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
146 static void gui_statusbar_led(struct screen * display);
147 #endif
148 #ifdef HAVE_RECORDING
149 static void gui_statusbar_icon_recording_info(struct screen * display);
150 #endif
151 #if CONFIG_RTC
152 static void gui_statusbar_time(struct screen * display, struct tm *time);
153 #endif
154 #endif
156 /* End prototypes */
160 * Initializes a status bar
161 * - bar : the bar to initialize
163 static void gui_statusbar_init(struct gui_statusbar * bar)
165 bar->redraw_volume = true;
166 bar->volume_icon_switch_tick = bar->battery_icon_switch_tick = current_tick;
167 memset((void*)&(bar->lastinfo), 0, sizeof(struct status_info));
168 #if CONFIG_RTC
169 bar->last_tm_min = 0;
170 #endif
173 void gui_statusbar_draw(struct gui_statusbar * bar, bool force_redraw)
175 struct screen * display = bar->display;
176 struct viewport vp;
177 viewport_set_defaults(&vp, display->screen_type);
178 vp.height = STATUSBAR_HEIGHT;
179 vp.x = STATUSBAR_X_POS;
180 vp.y = STATUSBAR_Y_POS;
181 display->set_viewport(&vp);
183 #ifdef HAVE_LCD_CHARCELLS
184 int val;
185 (void)force_redraw; /* players always "redraw" */
186 #endif /* HAVE_LCD_CHARCELLS */
188 bar->info.battlevel = battery_level();
189 #ifdef HAVE_USB_POWER
190 bar->info.usb_inserted = usb_inserted();
191 #endif
192 #if CONFIG_CHARGING
193 bar->info.inserted = (charger_input_state == CHARGER);
194 if (bar->info.inserted)
196 bar->info.battery_state = true;
198 #if CONFIG_CHARGING >= CHARGING_MONITOR
200 /* zero battery run time if charging */
201 if (charge_state > DISCHARGING)
202 lasttime = current_tick;
204 /* animate battery if charging */
205 if ((charge_state == DISCHARGING) || (charge_state == TRICKLE))
207 bar->info.batt_charge_step = -1;
209 else
211 #else /* CONFIG_CHARGING < CHARGING_MONITOR */
212 lasttime = current_tick;
214 #endif /* CONFIG_CHARGING < CHARGING_MONITOR */
215 /* animate in (max.) 4 steps, starting near the current charge level */
216 if (TIME_AFTER(current_tick, bar->battery_icon_switch_tick))
218 if (++bar->info.batt_charge_step > 3)
219 bar->info.batt_charge_step = bar->info.battlevel / 34;
220 bar->battery_icon_switch_tick = current_tick + HZ;
224 else
225 #endif /* CONFIG_CHARGING */
227 bar->info.batt_charge_step = -1;
228 if (battery_level_safe())
229 bar->info.battery_state = true;
230 else
231 /* blink battery if level is low */
232 if (TIME_AFTER(current_tick, bar->battery_icon_switch_tick) &&
233 (bar->info.battlevel > -1))
235 bar->info.battery_state = !bar->info.battery_state;
236 bar->battery_icon_switch_tick = current_tick + HZ;
240 bar->info.volume = global_settings.volume;
241 #ifdef HAVE_LCD_BITMAP
242 bar->info.shuffle = global_settings.playlist_shuffle;
243 #ifdef HAS_BUTTON_HOLD
244 bar->info.keylock = button_hold();
245 #else
246 bar->info.keylock = is_keys_locked();
247 #endif /* HAS_BUTTON_HOLD */
248 #ifdef HAS_REMOTE_BUTTON_HOLD
249 bar->info.keylockremote = remote_button_hold();
250 #endif
251 bar->info.repeat = global_settings.repeat_mode;
252 bar->info.playmode = current_playmode();
254 #if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
255 if(!display->has_disk_led)
256 bar->info.led = led_read(HZ/2); /* delay should match polling interval */
257 #endif
258 #if CONFIG_RTC
259 bar->time = get_time();
260 #endif /* CONFIG_RTC */
262 /* only redraw if forced to, or info has changed */
263 if (force_redraw || bar->redraw_volume ||
264 #if CONFIG_RTC
265 (bar->time->tm_min != bar->last_tm_min) ||
266 #endif
267 memcmp(&(bar->info), &(bar->lastinfo), sizeof(struct status_info)))
269 display->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
270 display->fillrect(0, 0, display->getwidth(), STATUSBAR_HEIGHT);
271 display->set_drawmode(DRMODE_SOLID);
273 if (bar->info.battery_state)
274 gui_statusbar_icon_battery(display, bar->info.battlevel,
275 bar->info.batt_charge_step);
276 #ifdef HAVE_USB_POWER
277 if (bar->info.usb_inserted)
278 display->mono_bitmap(bitmap_icons_7x8[Icon_USBPlug],
279 STATUSBAR_PLUG_X_POS,
280 STATUSBAR_Y_POS, STATUSBAR_PLUG_WIDTH,
281 STATUSBAR_HEIGHT);
282 #endif /* HAVE_USB_POWER */
283 #if CONFIG_CHARGING
284 #ifdef HAVE_USB_POWER
285 else
286 #endif
287 /* draw power plug if charging */
288 if (bar->info.inserted)
289 display->mono_bitmap(bitmap_icons_7x8[Icon_Plug],
290 STATUSBAR_PLUG_X_POS,
291 STATUSBAR_Y_POS, STATUSBAR_PLUG_WIDTH,
292 STATUSBAR_HEIGHT);
293 #endif /* CONFIG_CHARGING */
294 #ifdef HAVE_RECORDING
295 /* turn off volume display in recording screen */
296 bool recscreen_on = in_recording_screen();
297 if (!recscreen_on)
298 #endif
299 bar->redraw_volume = gui_statusbar_icon_volume(bar, bar->info.volume);
300 gui_statusbar_icon_play_state(display, current_playmode() + Icon_Play);
302 #ifdef HAVE_RECORDING
303 /* If in recording screen, replace repeat mode, volume
304 and shuffle icons with recording info */
305 if (recscreen_on)
306 gui_statusbar_icon_recording_info(display);
307 else
308 #endif
310 switch (bar->info.repeat) {
311 #ifdef AB_REPEAT_ENABLE
312 case REPEAT_AB:
313 gui_statusbar_icon_play_mode(display, Icon_RepeatAB);
314 break;
315 #endif /* AB_REPEAT_ENABLE == 1 */
317 case REPEAT_ONE:
318 gui_statusbar_icon_play_mode(display, Icon_RepeatOne);
319 break;
321 case REPEAT_ALL:
322 case REPEAT_SHUFFLE:
323 gui_statusbar_icon_play_mode(display, Icon_Repeat);
324 break;
326 if (bar->info.shuffle)
327 gui_statusbar_icon_shuffle(display);
329 if (bar->info.keylock)
330 gui_statusbar_icon_lock(display);
331 #ifdef HAS_REMOTE_BUTTON_HOLD
332 if (bar->info.keylockremote)
333 gui_statusbar_icon_lock_remote(display);
334 #endif
335 #if CONFIG_RTC
336 gui_statusbar_time(display, bar->time);
337 bar->last_tm_min = bar->time->tm_min;
338 #endif /* CONFIG_RTC */
339 #if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
340 if(!display->has_disk_led && bar->info.led)
341 gui_statusbar_led(display);
342 #endif
343 display->update_rect(0, 0, display->getwidth(), STATUSBAR_HEIGHT);
344 bar->lastinfo = bar->info;
346 #endif /* HAVE_LCD_BITMAP */
349 #ifdef HAVE_LCD_CHARCELLS
350 display->icon(ICON_BATTERY, bar->info.battery_state);
352 if (bar->info.batt_charge_step > -1)
353 val = bar->info.batt_charge_step;
354 else
355 val = (bar->info.battlevel * 3 + 50) / 100;
356 display->icon(ICON_BATTERY_1, val >= 1);
357 display->icon(ICON_BATTERY_2, val >= 2);
358 display->icon(ICON_BATTERY_3, val >= 3);
360 val = 10 * (bar->info.volume - sound_min(SOUND_VOLUME))
361 / (sound_max(SOUND_VOLUME) - sound_min(SOUND_VOLUME));
362 display->icon(ICON_VOLUME, true);
363 display->icon(ICON_VOLUME_1, val >= 1);
364 display->icon(ICON_VOLUME_2, val >= 3);
365 display->icon(ICON_VOLUME_3, val >= 5);
366 display->icon(ICON_VOLUME_4, val >= 7);
367 display->icon(ICON_VOLUME_5, val >= 9);
369 display->icon(ICON_PLAY, current_playmode() == STATUS_PLAY);
370 display->icon(ICON_PAUSE, current_playmode() == STATUS_PAUSE);
372 display->icon(ICON_REPEAT, global_settings.repeat_mode != REPEAT_OFF);
373 display->icon(ICON_1, global_settings.repeat_mode == REPEAT_ONE);
375 display->icon(ICON_RECORD, record);
376 display->icon(ICON_AUDIO, audio);
377 display->icon(ICON_PARAM, param);
378 display->icon(ICON_USB, usb);
379 #endif /* HAVE_LCD_CHARCELLS */
380 display->set_viewport(NULL);
383 #ifdef HAVE_LCD_BITMAP
384 /* from icon.c */
386 * Print battery icon to status bar
388 static void gui_statusbar_icon_battery(struct screen * display, int percent,
389 int batt_charge_step)
391 int fill, endfill;
392 char buffer[5];
393 unsigned int width, height;
394 #if LCD_DEPTH > 1
395 unsigned int prevfg = 0;
396 #endif
398 #if CONFIG_CHARGING
399 if (batt_charge_step >= 0)
401 fill = percent * (STATUSBAR_BATTERY_WIDTH-3) / 100;
402 endfill = 34 * batt_charge_step * (STATUSBAR_BATTERY_WIDTH-3) / 100;
404 else
405 #else
406 (void)batt_charge_step;
407 #endif
409 fill = endfill = (percent * (STATUSBAR_BATTERY_WIDTH-3) + 50) / 100;
412 #if CONFIG_CHARGING == CHARGING_MONITOR && !defined(SIMULATOR)
413 /* Certain charge controlled targets */
414 /* show graphical animation when charging instead of numbers */
415 if ((global_settings.battery_display) &&
416 (charge_state != CHARGING) &&
417 (percent > -1)) {
418 #else /* all others */
419 if (global_settings.battery_display && (percent > -1)) {
420 #endif
421 /* Numeric display */
422 display->setfont(FONT_SYSFIXED);
423 snprintf(buffer, sizeof(buffer), "%3d", percent);
424 display->getstringsize(buffer, &width, &height);
425 if (height <= STATUSBAR_HEIGHT)
426 display->putsxy(STATUSBAR_BATTERY_X_POS
427 + STATUSBAR_BATTERY_WIDTH / 2
428 - width/2, STATUSBAR_Y_POS, buffer);
429 display->setfont(FONT_UI);
432 else {
433 /* draw battery */
434 display->drawrect(STATUSBAR_BATTERY_X_POS, STATUSBAR_Y_POS, 17, 7);
435 display->vline(STATUSBAR_BATTERY_X_POS + 17, STATUSBAR_Y_POS + 2,
436 STATUSBAR_Y_POS + 4);
438 display->fillrect(STATUSBAR_BATTERY_X_POS + 1, STATUSBAR_Y_POS + 1,
439 fill, 5);
440 #if LCD_DEPTH > 1
441 if (display->depth > 1)
443 prevfg = display->get_foreground();
444 display->set_foreground(LCD_DARKGRAY);
446 #endif
447 display->fillrect(STATUSBAR_BATTERY_X_POS + 1 + fill,
448 STATUSBAR_Y_POS + 1, endfill - fill, 5);
449 #if LCD_DEPTH > 1
450 if (display->depth > 1)
451 display->set_foreground(prevfg);
452 #endif
455 if (percent == -1) {
456 display->setfont(FONT_SYSFIXED);
457 display->putsxy(STATUSBAR_BATTERY_X_POS + STATUSBAR_BATTERY_WIDTH / 2
458 - 4, STATUSBAR_Y_POS, "?");
459 display->setfont(FONT_UI);
464 * Print volume gauge to status bar
466 static bool gui_statusbar_icon_volume(struct gui_statusbar * bar, int volume)
468 int i;
469 int vol;
470 char buffer[4];
471 unsigned int width, height;
472 bool needs_redraw = false;
473 int type = global_settings.volume_type;
474 struct screen * display=bar->display;
475 const int minvol = sound_min(SOUND_VOLUME);
476 const int maxvol = sound_max(SOUND_VOLUME);
478 if (volume < minvol)
479 volume = minvol;
480 if (volume > maxvol)
481 volume = maxvol;
483 if (volume == minvol) {
484 display->mono_bitmap(bitmap_icons_7x8[Icon_Mute],
485 STATUSBAR_VOLUME_X_POS + STATUSBAR_VOLUME_WIDTH / 2 - 4,
486 STATUSBAR_Y_POS, 7, STATUSBAR_HEIGHT);
488 else {
489 /* We want to redraw the icon later on */
490 if (bar->last_volume != volume && bar->last_volume >= minvol) {
491 bar->volume_icon_switch_tick = current_tick + HZ;
494 /* If the timeout hasn't yet been reached, we show it numerically
495 and tell the caller that we want to be called again */
496 if (TIME_BEFORE(current_tick,bar->volume_icon_switch_tick)) {
497 type = 1;
498 needs_redraw = true;
501 /* display volume level numerical? */
502 if (type)
504 display->setfont(FONT_SYSFIXED);
505 snprintf(buffer, sizeof(buffer), "%2d", volume);
506 display->getstringsize(buffer, &width, &height);
507 if (height <= STATUSBAR_HEIGHT)
509 display->putsxy(STATUSBAR_VOLUME_X_POS
510 + STATUSBAR_VOLUME_WIDTH / 2
511 - width/2, STATUSBAR_Y_POS, buffer);
513 display->setfont(FONT_UI);
514 } else {
515 /* display volume bar */
516 vol = (volume - minvol) * 14 / (maxvol - minvol);
517 for(i=0; i < vol; i++) {
518 display->vline(STATUSBAR_VOLUME_X_POS + i,
519 STATUSBAR_Y_POS + 6 - i / 2,
520 STATUSBAR_Y_POS + 6);
524 bar->last_volume = volume;
526 return needs_redraw;
530 * Print play state to status bar
532 static void gui_statusbar_icon_play_state(struct screen * display, int state)
534 display->mono_bitmap(bitmap_icons_7x8[state], STATUSBAR_PLAY_STATE_X_POS,
535 STATUSBAR_Y_POS, STATUSBAR_PLAY_STATE_WIDTH,
536 STATUSBAR_HEIGHT);
540 * Print play mode to status bar
542 static void gui_statusbar_icon_play_mode(struct screen * display, int mode)
544 display->mono_bitmap(bitmap_icons_7x8[mode], STATUSBAR_PLAY_MODE_X_POS,
545 STATUSBAR_Y_POS, STATUSBAR_PLAY_MODE_WIDTH,
546 STATUSBAR_HEIGHT);
550 * Print shuffle mode to status bar
552 static void gui_statusbar_icon_shuffle(struct screen * display)
554 display->mono_bitmap(bitmap_icons_7x8[Icon_Shuffle],
555 STATUSBAR_SHUFFLE_X_POS, STATUSBAR_Y_POS,
556 STATUSBAR_SHUFFLE_WIDTH, STATUSBAR_HEIGHT);
560 * Print lock when keys are locked
562 static void gui_statusbar_icon_lock(struct screen * display)
564 display->mono_bitmap(bitmap_icons_5x8[Icon_Lock_Main],
565 STATUSBAR_LOCKM_X_POS, STATUSBAR_Y_POS,
566 STATUSBAR_LOCKM_WIDTH, STATUSBAR_HEIGHT);
569 #ifdef HAS_REMOTE_BUTTON_HOLD
571 * Print remote lock when remote hold is enabled
573 static void gui_statusbar_icon_lock_remote(struct screen * display)
575 display->mono_bitmap(bitmap_icons_5x8[Icon_Lock_Remote],
576 STATUSBAR_LOCKR_X_POS, STATUSBAR_Y_POS,
577 STATUSBAR_LOCKR_WIDTH, STATUSBAR_HEIGHT);
579 #endif
581 #if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
583 * no real LED: disk activity in status bar
585 static void gui_statusbar_led(struct screen * display)
587 display->mono_bitmap(bitmap_icon_disk,
588 STATUSBAR_DISK_X_POS(display->getwidth()),
589 STATUSBAR_Y_POS, STATUSBAR_DISK_WIDTH,
590 STATUSBAR_HEIGHT);
592 #endif
594 #if CONFIG_RTC
596 * Print time to status bar
598 static void gui_statusbar_time(struct screen * display, struct tm *time)
600 unsigned char buffer[6];
601 unsigned int width, height;
602 int hour, minute;
603 if ( valid_time(time) ) {
604 hour = time->tm_hour;
605 minute = time->tm_min;
606 if ( global_settings.timeformat ) { /* 12 hour clock */
607 hour %= 12;
608 if ( hour == 0 ) {
609 hour += 12;
612 snprintf(buffer, sizeof(buffer), "%02d:%02d", hour, minute);
614 else {
615 strncpy(buffer, "--:--", sizeof buffer);
617 display->setfont(FONT_SYSFIXED);
618 display->getstringsize(buffer, &width, &height);
619 if (height <= STATUSBAR_HEIGHT) {
620 display->putsxy(STATUSBAR_TIME_X_END(display->getwidth()) - width,
621 STATUSBAR_Y_POS, buffer);
623 display->setfont(FONT_UI);
626 #endif
628 #ifdef HAVE_RECORDING
629 #if CONFIG_CODEC == SWCODEC
631 * Write a number to the display using bitmaps and return new position
633 static int write_bitmap_number(struct screen * display, int value,
634 int x, int y)
636 char buf[12], *ptr;
637 snprintf(buf, sizeof(buf), "%d", value);
639 for (ptr = buf; *ptr != '\0'; ptr++, x += BM_GLYPH_WIDTH)
640 display->mono_bitmap(bitmap_glyphs_4x8[*ptr - '0'], x, y,
641 BM_GLYPH_WIDTH, STATUSBAR_HEIGHT);
642 return x;
646 * Write format info bitmaps - right justified
648 static void gui_statusbar_write_format_info(struct screen * display)
650 /* Can't fit info for sw codec targets in statusbar using FONT_SYSFIXED
651 so must use icons */
652 int rec_format = global_settings.rec_format;
653 unsigned bitrk = 0; /* compiler warns about unitialized use !! */
654 int xpos = STATUSBAR_ENCODER_X_POS;
655 int width = STATUSBAR_ENCODER_WIDTH;
656 const unsigned char *bm = bitmap_formats_18x8[rec_format];
658 if (rec_format == REC_FORMAT_MPA_L3)
660 /* Special handling for mp3 */
661 bitrk = global_settings.mp3_enc_config.bitrate;
662 bitrk = mp3_enc_bitr[bitrk];
664 width = BM_MPA_L3_M_WIDTH;
666 /* Slide 'M' to right if fewer than three digits used */
667 if (bitrk > 999)
668 bitrk = 999; /* neurotic safety check if corrupted */
669 else
671 if (bitrk < 100)
672 xpos += BM_GLYPH_WIDTH;
673 if (bitrk < 10)
674 xpos += BM_GLYPH_WIDTH;
679 /* Show bitmap - clipping right edge if needed */
680 display->mono_bitmap_part(bm, 0, 0, STATUSBAR_ENCODER_WIDTH,
681 xpos, STATUSBAR_Y_POS, width, STATUSBAR_HEIGHT);
683 if (rec_format == REC_FORMAT_MPA_L3)
685 xpos += BM_MPA_L3_M_WIDTH; /* to right of 'M' */
686 write_bitmap_number(display, bitrk, xpos, STATUSBAR_Y_POS);
691 * Write sample rate using bitmaps - left justified
693 static void gui_statusbar_write_samplerate_info(struct screen * display)
695 unsigned long samprk;
696 int xpos;
698 #ifdef SIMULATOR
699 samprk = 44100;
700 #else
701 #ifdef HAVE_SPDIF_REC
702 if (global_settings.rec_source == AUDIO_SRC_SPDIF)
703 /* Use rate in use, not current measured rate if it changed */
704 samprk = pcm_rec_sample_rate();
705 else
706 #endif
707 samprk = rec_freq_sampr[global_settings.rec_frequency];
708 #endif /* SIMULATOR */
710 samprk /= 1000;
711 if (samprk > 99)
712 samprk = 99; /* Limit to 3 glyphs */
714 xpos = write_bitmap_number(display, (unsigned)samprk,
715 STATUSBAR_RECFREQ_X_POS, STATUSBAR_Y_POS);
717 /* write the 'k' */
718 display->mono_bitmap(bitmap_glyphs_4x8[Glyph_4x8_k], xpos,
719 STATUSBAR_Y_POS, BM_GLYPH_WIDTH,
720 STATUSBAR_HEIGHT);
722 #endif /* CONFIG_CODEC == SWCODEC */
724 static void gui_statusbar_icon_recording_info(struct screen * display)
726 #if CONFIG_CODEC != SWCODEC
727 char buffer[3];
728 int width, height;
729 display->setfont(FONT_SYSFIXED);
730 #endif /* CONFIG_CODEC != SWCODEC */
732 /* Display Codec info in statusbar */
733 #if CONFIG_CODEC == SWCODEC
734 gui_statusbar_write_format_info(display);
735 #else /* !SWCODEC */
736 display->mono_bitmap(bitmap_icons_5x8[Icon_q],
737 STATUSBAR_ENCODER_X_POS + 8, STATUSBAR_Y_POS,
738 5, STATUSBAR_HEIGHT);
740 snprintf(buffer, sizeof(buffer), "%d", global_settings.rec_quality);
741 display->getstringsize(buffer, &width, &height);
742 if (height <= STATUSBAR_HEIGHT)
743 display->putsxy(STATUSBAR_ENCODER_X_POS + 13, STATUSBAR_Y_POS, buffer);
744 #endif /* CONFIG_CODEC == SWCODEC */
746 /* Display Samplerate info in statusbar */
747 #if CONFIG_CODEC == SWCODEC
748 /* SWCODEC targets use bitmaps for glyphs */
749 gui_statusbar_write_samplerate_info(display);
750 #else /* !SWCODEC */
751 /* hwcodec targets have sysfont characters */
752 #ifdef HAVE_SPDIF_REC
753 if (global_settings.rec_source == AUDIO_SRC_SPDIF)
755 /* Can't measure S/PDIF sample rate on Archos/Sim yet */
756 strncpy(buffer, "--", sizeof(buffer));
758 else
759 #endif /* HAVE_SPDIF_IN */
761 static char const * const freq_strings[12] =
762 { "44", "48", "32", "22", "24", "16" };
763 strncpy(buffer, freq_strings[global_settings.rec_frequency],
764 sizeof(buffer));
767 display->getstringsize(buffer, &width, &height);
769 if (height <= STATUSBAR_HEIGHT)
770 display->putsxy(STATUSBAR_RECFREQ_X_POS, STATUSBAR_Y_POS, buffer);
772 display->setfont(FONT_UI);
773 #endif /* CONFIG_CODEC == SWCODEC */
775 /* Display Channel status in status bar */
776 if(global_settings.rec_channels)
778 display->mono_bitmap(bitmap_icons_5x8[Icon_Mono],
779 STATUSBAR_RECCHANNELS_X_POS , STATUSBAR_Y_POS,
780 STATUSBAR_RECCHANNELS_WIDTH, STATUSBAR_HEIGHT);
782 else
784 display->mono_bitmap(bitmap_icons_5x8[Icon_Stereo],
785 STATUSBAR_RECCHANNELS_X_POS, STATUSBAR_Y_POS,
786 STATUSBAR_RECCHANNELS_WIDTH, STATUSBAR_HEIGHT);
789 #endif /* HAVE_RECORDING */
791 #endif /* HAVE_LCD_BITMAP */
793 void gui_syncstatusbar_init(struct gui_syncstatusbar * bars)
795 int i;
796 FOR_NB_SCREENS(i) {
797 gui_statusbar_init( &(bars->statusbars[i]) );
798 gui_statusbar_set_screen( &(bars->statusbars[i]), &(screens[i]) );
802 void gui_syncstatusbar_draw(struct gui_syncstatusbar * bars,
803 bool force_redraw)
805 #ifdef HAVE_LCD_BITMAP
806 if(!global_settings.statusbar)
807 return;
808 #endif /* HAVE_LCD_BITMAP */
809 int i;
810 FOR_NB_SCREENS(i) {
811 gui_statusbar_draw( &(bars->statusbars[i]), force_redraw );
815 int gui_statusbar_height(void)
817 return global_settings.statusbar ? STATUSBAR_HEIGHT : 0;