Add Sam Bouwer to the credits and inside the langfile header
[kugel-rb.git] / apps / gui / statusbar.c
blobec804ab41f04a0d04597a7b100d4fb543dc9fb7d
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"
47 #include "timefuncs.h"
49 /* FIXME: should be removed from icon.h to avoid redefinition,
50 but still needed for compatibility with old system */
51 #define ICONS_SPACING 2
52 #define STATUSBAR_BATTERY_X_POS 0*ICONS_SPACING
53 #define STATUSBAR_BATTERY_WIDTH 18
54 #define STATUSBAR_PLUG_X_POS STATUSBAR_X_POS + \
55 STATUSBAR_BATTERY_WIDTH + \
56 ICONS_SPACING
57 #define STATUSBAR_PLUG_WIDTH 7
58 #define STATUSBAR_VOLUME_X_POS STATUSBAR_X_POS + \
59 STATUSBAR_BATTERY_WIDTH + \
60 STATUSBAR_PLUG_WIDTH + \
61 2*ICONS_SPACING
62 #define STATUSBAR_VOLUME_WIDTH 16
63 #define STATUSBAR_ENCODER_X_POS STATUSBAR_X_POS + \
64 STATUSBAR_BATTERY_WIDTH + \
65 STATUSBAR_PLUG_WIDTH + \
66 2*ICONS_SPACING - 1
67 #define STATUSBAR_ENCODER_WIDTH 18
68 #define STATUSBAR_PLAY_STATE_X_POS STATUSBAR_X_POS + \
69 STATUSBAR_BATTERY_WIDTH + \
70 STATUSBAR_PLUG_WIDTH + \
71 STATUSBAR_VOLUME_WIDTH + \
72 3*ICONS_SPACING
73 #define STATUSBAR_PLAY_STATE_WIDTH 7
74 #define STATUSBAR_PLAY_MODE_X_POS STATUSBAR_X_POS + \
75 STATUSBAR_BATTERY_WIDTH + \
76 STATUSBAR_PLUG_WIDTH + \
77 STATUSBAR_VOLUME_WIDTH + \
78 STATUSBAR_PLAY_STATE_WIDTH + \
79 4*ICONS_SPACING
80 #define STATUSBAR_PLAY_MODE_WIDTH 7
81 #define STATUSBAR_RECFREQ_X_POS STATUSBAR_X_POS + \
82 STATUSBAR_BATTERY_WIDTH + \
83 STATUSBAR_PLUG_WIDTH + \
84 STATUSBAR_VOLUME_WIDTH + \
85 STATUSBAR_PLAY_STATE_WIDTH + \
86 3*ICONS_SPACING
87 #define STATUSBAR_RECFREQ_WIDTH 12
88 #define STATUSBAR_RECCHANNELS_X_POS STATUSBAR_X_POS + \
89 STATUSBAR_BATTERY_WIDTH + \
90 STATUSBAR_PLUG_WIDTH + \
91 STATUSBAR_VOLUME_WIDTH + \
92 STATUSBAR_PLAY_STATE_WIDTH + \
93 STATUSBAR_RECFREQ_WIDTH + \
94 4*ICONS_SPACING
95 #define STATUSBAR_RECCHANNELS_WIDTH 5
96 #define STATUSBAR_SHUFFLE_X_POS STATUSBAR_X_POS + \
97 STATUSBAR_BATTERY_WIDTH + \
98 STATUSBAR_PLUG_WIDTH + \
99 STATUSBAR_VOLUME_WIDTH + \
100 STATUSBAR_PLAY_STATE_WIDTH + \
101 STATUSBAR_PLAY_MODE_WIDTH + \
102 5*ICONS_SPACING
103 #define STATUSBAR_SHUFFLE_WIDTH 7
104 #define STATUSBAR_LOCKM_X_POS STATUSBAR_X_POS + \
105 STATUSBAR_BATTERY_WIDTH + \
106 STATUSBAR_PLUG_WIDTH + \
107 STATUSBAR_VOLUME_WIDTH + \
108 STATUSBAR_PLAY_STATE_WIDTH + \
109 STATUSBAR_PLAY_MODE_WIDTH + \
110 STATUSBAR_SHUFFLE_WIDTH + \
111 6*ICONS_SPACING
112 #define STATUSBAR_LOCKM_WIDTH 5
113 #define STATUSBAR_LOCKR_X_POS STATUSBAR_X_POS + \
114 STATUSBAR_BATTERY_WIDTH + \
115 STATUSBAR_PLUG_WIDTH + \
116 STATUSBAR_VOLUME_WIDTH + \
117 STATUSBAR_PLAY_STATE_WIDTH + \
118 STATUSBAR_PLAY_MODE_WIDTH + \
119 STATUSBAR_SHUFFLE_WIDTH + \
120 STATUSBAR_LOCKM_WIDTH + \
121 7*ICONS_SPACING
122 #define STATUSBAR_LOCKR_WIDTH 5
124 #if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
125 #define STATUSBAR_DISK_WIDTH 12
126 #define STATUSBAR_DISK_X_POS(statusbar_width) statusbar_width - \
127 STATUSBAR_DISK_WIDTH
128 #else
129 #define STATUSBAR_DISK_WIDTH 0
130 #endif
131 #define STATUSBAR_TIME_X_END(statusbar_width) statusbar_width - 1 - \
132 STATUSBAR_DISK_WIDTH
133 struct gui_syncstatusbar statusbars;
135 /* Prototypes */
136 #ifdef HAVE_LCD_BITMAP
137 static void gui_statusbar_icon_battery(struct screen * display, int percent,
138 int batt_charge_step);
139 static bool gui_statusbar_icon_volume(struct gui_statusbar * bar, int volume);
140 static void gui_statusbar_icon_play_state(struct screen * display, int state);
141 static void gui_statusbar_icon_play_mode(struct screen * display, int mode);
142 static void gui_statusbar_icon_shuffle(struct screen * display);
143 static void gui_statusbar_icon_lock(struct screen * display);
144 #ifdef HAS_REMOTE_BUTTON_HOLD
145 static void gui_statusbar_icon_lock_remote(struct screen * display);
146 #endif
147 #if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
148 static void gui_statusbar_led(struct screen * display);
149 #endif
150 #ifdef HAVE_RECORDING
151 static void gui_statusbar_icon_recording_info(struct screen * display);
152 #endif
153 #if CONFIG_RTC
154 static void gui_statusbar_time(struct screen * display, struct tm *time);
155 #endif
156 #endif
158 /* End prototypes */
162 * Initializes a status bar
163 * - bar : the bar to initialize
165 static void gui_statusbar_init(struct gui_statusbar * bar)
167 bar->redraw_volume = true;
168 bar->volume_icon_switch_tick = bar->battery_icon_switch_tick = current_tick;
169 memset((void*)&(bar->lastinfo), 0, sizeof(struct status_info));
170 #if CONFIG_RTC
171 bar->last_tm_min = 0;
172 #endif
175 void gui_statusbar_draw(struct gui_statusbar * bar, bool force_redraw)
177 struct screen * display = bar->display;
179 #ifdef HAVE_LCD_CHARCELLS
180 int val;
181 (void)force_redraw; /* players always "redraw" */
182 #endif /* HAVE_LCD_CHARCELLS */
184 bar->info.battlevel = battery_level();
185 #ifdef HAVE_USB_POWER
186 bar->info.usb_inserted = usb_inserted();
187 #endif
188 #if CONFIG_CHARGING
189 bar->info.inserted = (charger_input_state == CHARGER);
190 if (bar->info.inserted)
192 bar->info.battery_state = true;
194 #if CONFIG_CHARGING >= CHARGING_MONITOR
196 /* zero battery run time if charging */
197 if (charge_state > DISCHARGING)
198 lasttime = current_tick;
200 /* animate battery if charging */
201 if ((charge_state == DISCHARGING) || (charge_state == TRICKLE))
203 bar->info.batt_charge_step = -1;
205 else
207 #else /* CONFIG_CHARGING < CHARGING_MONITOR */
208 lasttime = current_tick;
210 #endif /* CONFIG_CHARGING < CHARGING_MONITOR */
211 /* animate in (max.) 4 steps, starting near the current charge level */
212 if (TIME_AFTER(current_tick, bar->battery_icon_switch_tick))
214 if (++bar->info.batt_charge_step > 3)
215 bar->info.batt_charge_step = bar->info.battlevel / 34;
216 bar->battery_icon_switch_tick = current_tick + HZ;
220 else
221 #endif /* CONFIG_CHARGING */
223 bar->info.batt_charge_step = -1;
224 if (battery_level_safe())
225 bar->info.battery_state = true;
226 else
227 /* blink battery if level is low */
228 if (TIME_AFTER(current_tick, bar->battery_icon_switch_tick) &&
229 (bar->info.battlevel > -1))
231 bar->info.battery_state = !bar->info.battery_state;
232 bar->battery_icon_switch_tick = current_tick + HZ;
236 bar->info.volume = global_settings.volume;
237 #ifdef HAVE_LCD_BITMAP
238 bar->info.shuffle = global_settings.playlist_shuffle;
239 #ifdef HAS_BUTTON_HOLD
240 bar->info.keylock = button_hold();
241 #else
242 bar->info.keylock = is_keys_locked();
243 #endif /* HAS_BUTTON_HOLD */
244 #ifdef HAS_REMOTE_BUTTON_HOLD
245 bar->info.keylockremote = remote_button_hold();
246 #endif
247 bar->info.repeat = global_settings.repeat_mode;
248 bar->info.playmode = current_playmode();
250 #if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
251 if(!display->has_disk_led)
252 bar->info.led = led_read(HZ/2); /* delay should match polling interval */
253 #endif
254 #if CONFIG_RTC
255 bar->time = get_time();
256 #endif /* CONFIG_RTC */
258 /* only redraw if forced to, or info has changed */
259 if (force_redraw || bar->redraw_volume ||
260 #if CONFIG_RTC
261 (bar->time->tm_min != bar->last_tm_min) ||
262 #endif
263 memcmp(&(bar->info), &(bar->lastinfo), sizeof(struct status_info)))
265 struct viewport vp;
266 viewport_set_defaults(&vp, display->screen_type);
267 vp.height = STATUSBAR_HEIGHT;
268 vp.x = STATUSBAR_X_POS;
269 vp.y = STATUSBAR_Y_POS;
270 display->set_viewport(&vp);
271 display->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
272 display->fillrect(0, 0, display->getwidth(), STATUSBAR_HEIGHT);
273 display->set_drawmode(DRMODE_SOLID);
275 if (bar->info.battery_state)
276 gui_statusbar_icon_battery(display, bar->info.battlevel,
277 bar->info.batt_charge_step);
278 #ifdef HAVE_USB_POWER
279 if (bar->info.usb_inserted)
280 display->mono_bitmap(bitmap_icons_7x8[Icon_USBPlug],
281 STATUSBAR_PLUG_X_POS,
282 STATUSBAR_Y_POS, STATUSBAR_PLUG_WIDTH,
283 STATUSBAR_HEIGHT);
284 #endif /* HAVE_USB_POWER */
285 #if CONFIG_CHARGING
286 #ifdef HAVE_USB_POWER
287 else
288 #endif
289 /* draw power plug if charging */
290 if (bar->info.inserted)
291 display->mono_bitmap(bitmap_icons_7x8[Icon_Plug],
292 STATUSBAR_PLUG_X_POS,
293 STATUSBAR_Y_POS, STATUSBAR_PLUG_WIDTH,
294 STATUSBAR_HEIGHT);
295 #endif /* CONFIG_CHARGING */
296 #ifdef HAVE_RECORDING
297 /* turn off volume display in recording screen */
298 bool recscreen_on = in_recording_screen();
299 if (!recscreen_on)
300 #endif
301 bar->redraw_volume = gui_statusbar_icon_volume(bar, bar->info.volume);
302 gui_statusbar_icon_play_state(display, current_playmode() + Icon_Play);
304 #ifdef HAVE_RECORDING
305 /* If in recording screen, replace repeat mode, volume
306 and shuffle icons with recording info */
307 if (recscreen_on)
308 gui_statusbar_icon_recording_info(display);
309 else
310 #endif
312 switch (bar->info.repeat) {
313 #ifdef AB_REPEAT_ENABLE
314 case REPEAT_AB:
315 gui_statusbar_icon_play_mode(display, Icon_RepeatAB);
316 break;
317 #endif /* AB_REPEAT_ENABLE == 1 */
319 case REPEAT_ONE:
320 gui_statusbar_icon_play_mode(display, Icon_RepeatOne);
321 break;
323 case REPEAT_ALL:
324 case REPEAT_SHUFFLE:
325 gui_statusbar_icon_play_mode(display, Icon_Repeat);
326 break;
328 if (bar->info.shuffle)
329 gui_statusbar_icon_shuffle(display);
331 if (bar->info.keylock)
332 gui_statusbar_icon_lock(display);
333 #ifdef HAS_REMOTE_BUTTON_HOLD
334 if (bar->info.keylockremote)
335 gui_statusbar_icon_lock_remote(display);
336 #endif
337 #if CONFIG_RTC
338 gui_statusbar_time(display, bar->time);
339 bar->last_tm_min = bar->time->tm_min;
340 #endif /* CONFIG_RTC */
341 #if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
342 if(!display->has_disk_led && bar->info.led)
343 gui_statusbar_led(display);
344 #endif
345 display->update_viewport();
346 display->set_viewport(NULL);
347 bar->lastinfo = bar->info;
349 #endif /* HAVE_LCD_BITMAP */
352 #ifdef HAVE_LCD_CHARCELLS
353 display->icon(ICON_BATTERY, bar->info.battery_state);
355 if (bar->info.batt_charge_step > -1)
356 val = bar->info.batt_charge_step;
357 else
358 val = (bar->info.battlevel * 3 + 50) / 100;
359 display->icon(ICON_BATTERY_1, val >= 1);
360 display->icon(ICON_BATTERY_2, val >= 2);
361 display->icon(ICON_BATTERY_3, val >= 3);
363 val = 10 * (bar->info.volume - sound_min(SOUND_VOLUME))
364 / (sound_max(SOUND_VOLUME) - sound_min(SOUND_VOLUME));
365 display->icon(ICON_VOLUME, true);
366 display->icon(ICON_VOLUME_1, val >= 1);
367 display->icon(ICON_VOLUME_2, val >= 3);
368 display->icon(ICON_VOLUME_3, val >= 5);
369 display->icon(ICON_VOLUME_4, val >= 7);
370 display->icon(ICON_VOLUME_5, val >= 9);
372 display->icon(ICON_PLAY, current_playmode() == STATUS_PLAY);
373 display->icon(ICON_PAUSE, current_playmode() == STATUS_PAUSE);
375 display->icon(ICON_REPEAT, global_settings.repeat_mode != REPEAT_OFF);
376 display->icon(ICON_1, global_settings.repeat_mode == REPEAT_ONE);
378 display->icon(ICON_RECORD, record);
379 display->icon(ICON_AUDIO, audio);
380 display->icon(ICON_PARAM, param);
381 display->icon(ICON_USB, usb);
382 #endif /* HAVE_LCD_CHARCELLS */
385 #ifdef HAVE_LCD_BITMAP
386 /* from icon.c */
388 * Print battery icon to status bar
390 static void gui_statusbar_icon_battery(struct screen * display, int percent,
391 int batt_charge_step)
393 int fill, endfill;
394 char buffer[5];
395 unsigned int width, height;
396 #if LCD_DEPTH > 1
397 unsigned int prevfg = 0;
398 #endif
400 #if CONFIG_CHARGING
401 if (batt_charge_step >= 0)
403 fill = percent * (STATUSBAR_BATTERY_WIDTH-3) / 100;
404 endfill = 34 * batt_charge_step * (STATUSBAR_BATTERY_WIDTH-3) / 100;
406 else
407 #else
408 (void)batt_charge_step;
409 #endif
411 fill = endfill = (percent * (STATUSBAR_BATTERY_WIDTH-3) + 50) / 100;
414 #if CONFIG_CHARGING == CHARGING_MONITOR && !defined(SIMULATOR)
415 /* Certain charge controlled targets */
416 /* show graphical animation when charging instead of numbers */
417 if ((global_settings.battery_display) &&
418 (charge_state != CHARGING) &&
419 (percent > -1)) {
420 #else /* all others */
421 if (global_settings.battery_display && (percent > -1)) {
422 #endif
423 /* Numeric display */
424 display->setfont(FONT_SYSFIXED);
425 snprintf(buffer, sizeof(buffer), "%3d", percent);
426 display->getstringsize(buffer, &width, &height);
427 if (height <= STATUSBAR_HEIGHT)
428 display->putsxy(STATUSBAR_BATTERY_X_POS
429 + STATUSBAR_BATTERY_WIDTH / 2
430 - width/2, STATUSBAR_Y_POS, buffer);
431 display->setfont(FONT_UI);
434 else {
435 /* draw battery */
436 display->drawrect(STATUSBAR_BATTERY_X_POS, STATUSBAR_Y_POS, 17, 7);
437 display->vline(STATUSBAR_BATTERY_X_POS + 17, STATUSBAR_Y_POS + 2,
438 STATUSBAR_Y_POS + 4);
440 display->fillrect(STATUSBAR_BATTERY_X_POS + 1, STATUSBAR_Y_POS + 1,
441 fill, 5);
442 #if LCD_DEPTH > 1
443 if (display->depth > 1)
445 prevfg = display->get_foreground();
446 display->set_foreground(LCD_DARKGRAY);
448 #endif
449 display->fillrect(STATUSBAR_BATTERY_X_POS + 1 + fill,
450 STATUSBAR_Y_POS + 1, endfill - fill, 5);
451 #if LCD_DEPTH > 1
452 if (display->depth > 1)
453 display->set_foreground(prevfg);
454 #endif
457 if (percent == -1) {
458 display->setfont(FONT_SYSFIXED);
459 display->putsxy(STATUSBAR_BATTERY_X_POS + STATUSBAR_BATTERY_WIDTH / 2
460 - 4, STATUSBAR_Y_POS, "?");
461 display->setfont(FONT_UI);
466 * Print volume gauge to status bar
468 static bool gui_statusbar_icon_volume(struct gui_statusbar * bar, int volume)
470 int i;
471 int vol;
472 char buffer[4];
473 unsigned int width, height;
474 bool needs_redraw = false;
475 int type = global_settings.volume_type;
476 struct screen * display=bar->display;
477 const int minvol = sound_min(SOUND_VOLUME);
478 const int maxvol = sound_max(SOUND_VOLUME);
480 if (volume < minvol)
481 volume = minvol;
482 if (volume > maxvol)
483 volume = maxvol;
485 if (volume == minvol) {
486 display->mono_bitmap(bitmap_icons_7x8[Icon_Mute],
487 STATUSBAR_VOLUME_X_POS + STATUSBAR_VOLUME_WIDTH / 2 - 4,
488 STATUSBAR_Y_POS, 7, STATUSBAR_HEIGHT);
490 else {
491 /* We want to redraw the icon later on */
492 if (bar->last_volume != volume && bar->last_volume >= minvol) {
493 bar->volume_icon_switch_tick = current_tick + HZ;
496 /* If the timeout hasn't yet been reached, we show it numerically
497 and tell the caller that we want to be called again */
498 if (TIME_BEFORE(current_tick,bar->volume_icon_switch_tick)) {
499 type = 1;
500 needs_redraw = true;
503 /* display volume level numerical? */
504 if (type)
506 display->setfont(FONT_SYSFIXED);
507 snprintf(buffer, sizeof(buffer), "%2d", volume);
508 display->getstringsize(buffer, &width, &height);
509 if (height <= STATUSBAR_HEIGHT)
511 display->putsxy(STATUSBAR_VOLUME_X_POS
512 + STATUSBAR_VOLUME_WIDTH / 2
513 - width/2, STATUSBAR_Y_POS, buffer);
515 display->setfont(FONT_UI);
516 } else {
517 /* display volume bar */
518 vol = (volume - minvol) * 14 / (maxvol - minvol);
519 for(i=0; i < vol; i++) {
520 display->vline(STATUSBAR_VOLUME_X_POS + i,
521 STATUSBAR_Y_POS + 6 - i / 2,
522 STATUSBAR_Y_POS + 6);
526 bar->last_volume = volume;
528 return needs_redraw;
532 * Print play state to status bar
534 static void gui_statusbar_icon_play_state(struct screen * display, int state)
536 display->mono_bitmap(bitmap_icons_7x8[state], STATUSBAR_PLAY_STATE_X_POS,
537 STATUSBAR_Y_POS, STATUSBAR_PLAY_STATE_WIDTH,
538 STATUSBAR_HEIGHT);
542 * Print play mode to status bar
544 static void gui_statusbar_icon_play_mode(struct screen * display, int mode)
546 display->mono_bitmap(bitmap_icons_7x8[mode], STATUSBAR_PLAY_MODE_X_POS,
547 STATUSBAR_Y_POS, STATUSBAR_PLAY_MODE_WIDTH,
548 STATUSBAR_HEIGHT);
552 * Print shuffle mode to status bar
554 static void gui_statusbar_icon_shuffle(struct screen * display)
556 display->mono_bitmap(bitmap_icons_7x8[Icon_Shuffle],
557 STATUSBAR_SHUFFLE_X_POS, STATUSBAR_Y_POS,
558 STATUSBAR_SHUFFLE_WIDTH, STATUSBAR_HEIGHT);
562 * Print lock when keys are locked
564 static void gui_statusbar_icon_lock(struct screen * display)
566 display->mono_bitmap(bitmap_icons_5x8[Icon_Lock_Main],
567 STATUSBAR_LOCKM_X_POS, STATUSBAR_Y_POS,
568 STATUSBAR_LOCKM_WIDTH, STATUSBAR_HEIGHT);
571 #ifdef HAS_REMOTE_BUTTON_HOLD
573 * Print remote lock when remote hold is enabled
575 static void gui_statusbar_icon_lock_remote(struct screen * display)
577 display->mono_bitmap(bitmap_icons_5x8[Icon_Lock_Remote],
578 STATUSBAR_LOCKR_X_POS, STATUSBAR_Y_POS,
579 STATUSBAR_LOCKR_WIDTH, STATUSBAR_HEIGHT);
581 #endif
583 #if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
585 * no real LED: disk activity in status bar
587 static void gui_statusbar_led(struct screen * display)
589 display->mono_bitmap(bitmap_icon_disk,
590 STATUSBAR_DISK_X_POS(display->getwidth()),
591 STATUSBAR_Y_POS, STATUSBAR_DISK_WIDTH,
592 STATUSBAR_HEIGHT);
594 #endif
596 #if CONFIG_RTC
598 * Print time to status bar
600 static void gui_statusbar_time(struct screen * display, struct tm *time)
602 unsigned char buffer[6];
603 unsigned int width, height;
604 int hour, minute;
605 if ( valid_time(time) ) {
606 hour = time->tm_hour;
607 minute = time->tm_min;
608 if ( global_settings.timeformat ) { /* 12 hour clock */
609 hour %= 12;
610 if ( hour == 0 ) {
611 hour += 12;
614 snprintf(buffer, sizeof(buffer), "%02d:%02d", hour, minute);
616 else {
617 strncpy(buffer, "--:--", sizeof buffer);
619 display->setfont(FONT_SYSFIXED);
620 display->getstringsize(buffer, &width, &height);
621 if (height <= STATUSBAR_HEIGHT) {
622 display->putsxy(STATUSBAR_TIME_X_END(display->getwidth()) - width,
623 STATUSBAR_Y_POS, buffer);
625 display->setfont(FONT_UI);
628 #endif
630 #ifdef HAVE_RECORDING
631 #if CONFIG_CODEC == SWCODEC
633 * Write a number to the display using bitmaps and return new position
635 static int write_bitmap_number(struct screen * display, int value,
636 int x, int y)
638 char buf[12], *ptr;
639 snprintf(buf, sizeof(buf), "%d", value);
641 for (ptr = buf; *ptr != '\0'; ptr++, x += BM_GLYPH_WIDTH)
642 display->mono_bitmap(bitmap_glyphs_4x8[*ptr - '0'], x, y,
643 BM_GLYPH_WIDTH, STATUSBAR_HEIGHT);
644 return x;
648 * Write format info bitmaps - right justified
650 static void gui_statusbar_write_format_info(struct screen * display)
652 /* Can't fit info for sw codec targets in statusbar using FONT_SYSFIXED
653 so must use icons */
654 int rec_format = global_settings.rec_format;
655 unsigned bitrk = 0; /* compiler warns about unitialized use !! */
656 int xpos = STATUSBAR_ENCODER_X_POS;
657 int width = STATUSBAR_ENCODER_WIDTH;
658 const unsigned char *bm = bitmap_formats_18x8[rec_format];
660 if (rec_format == REC_FORMAT_MPA_L3)
662 /* Special handling for mp3 */
663 bitrk = global_settings.mp3_enc_config.bitrate;
664 bitrk = mp3_enc_bitr[bitrk];
666 width = BM_MPA_L3_M_WIDTH;
668 /* Slide 'M' to right if fewer than three digits used */
669 if (bitrk > 999)
670 bitrk = 999; /* neurotic safety check if corrupted */
671 else
673 if (bitrk < 100)
674 xpos += BM_GLYPH_WIDTH;
675 if (bitrk < 10)
676 xpos += BM_GLYPH_WIDTH;
681 /* Show bitmap - clipping right edge if needed */
682 display->mono_bitmap_part(bm, 0, 0, STATUSBAR_ENCODER_WIDTH,
683 xpos, STATUSBAR_Y_POS, width, STATUSBAR_HEIGHT);
685 if (rec_format == REC_FORMAT_MPA_L3)
687 xpos += BM_MPA_L3_M_WIDTH; /* to right of 'M' */
688 write_bitmap_number(display, bitrk, xpos, STATUSBAR_Y_POS);
693 * Write sample rate using bitmaps - left justified
695 static void gui_statusbar_write_samplerate_info(struct screen * display)
697 unsigned long samprk;
698 int xpos;
700 #ifdef SIMULATOR
701 samprk = 44100;
702 #else
703 #ifdef HAVE_SPDIF_REC
704 if (global_settings.rec_source == AUDIO_SRC_SPDIF)
705 /* Use rate in use, not current measured rate if it changed */
706 samprk = pcm_rec_sample_rate();
707 else
708 #endif
709 samprk = rec_freq_sampr[global_settings.rec_frequency];
710 #endif /* SIMULATOR */
712 samprk /= 1000;
713 if (samprk > 99)
714 samprk = 99; /* Limit to 3 glyphs */
716 xpos = write_bitmap_number(display, (unsigned)samprk,
717 STATUSBAR_RECFREQ_X_POS, STATUSBAR_Y_POS);
719 /* write the 'k' */
720 display->mono_bitmap(bitmap_glyphs_4x8[Glyph_4x8_k], xpos,
721 STATUSBAR_Y_POS, BM_GLYPH_WIDTH,
722 STATUSBAR_HEIGHT);
724 #endif /* CONFIG_CODEC == SWCODEC */
726 static void gui_statusbar_icon_recording_info(struct screen * display)
728 #if CONFIG_CODEC != SWCODEC
729 char buffer[3];
730 int width, height;
731 display->setfont(FONT_SYSFIXED);
732 #endif /* CONFIG_CODEC != SWCODEC */
734 /* Display Codec info in statusbar */
735 #if CONFIG_CODEC == SWCODEC
736 gui_statusbar_write_format_info(display);
737 #else /* !SWCODEC */
738 display->mono_bitmap(bitmap_icons_5x8[Icon_q],
739 STATUSBAR_ENCODER_X_POS + 8, STATUSBAR_Y_POS,
740 5, STATUSBAR_HEIGHT);
742 snprintf(buffer, sizeof(buffer), "%d", global_settings.rec_quality);
743 display->getstringsize(buffer, &width, &height);
744 if (height <= STATUSBAR_HEIGHT)
745 display->putsxy(STATUSBAR_ENCODER_X_POS + 13, STATUSBAR_Y_POS, buffer);
746 #endif /* CONFIG_CODEC == SWCODEC */
748 /* Display Samplerate info in statusbar */
749 #if CONFIG_CODEC == SWCODEC
750 /* SWCODEC targets use bitmaps for glyphs */
751 gui_statusbar_write_samplerate_info(display);
752 #else /* !SWCODEC */
753 /* hwcodec targets have sysfont characters */
754 #ifdef HAVE_SPDIF_REC
755 if (global_settings.rec_source == AUDIO_SRC_SPDIF)
757 /* Can't measure S/PDIF sample rate on Archos/Sim yet */
758 strncpy(buffer, "--", sizeof(buffer));
760 else
761 #endif /* HAVE_SPDIF_IN */
763 static char const * const freq_strings[12] =
764 { "44", "48", "32", "22", "24", "16" };
765 strncpy(buffer, freq_strings[global_settings.rec_frequency],
766 sizeof(buffer));
769 display->getstringsize(buffer, &width, &height);
771 if (height <= STATUSBAR_HEIGHT)
772 display->putsxy(STATUSBAR_RECFREQ_X_POS, STATUSBAR_Y_POS, buffer);
774 display->setfont(FONT_UI);
775 #endif /* CONFIG_CODEC == SWCODEC */
777 /* Display Channel status in status bar */
778 if(global_settings.rec_channels)
780 display->mono_bitmap(bitmap_icons_5x8[Icon_Mono],
781 STATUSBAR_RECCHANNELS_X_POS , STATUSBAR_Y_POS,
782 STATUSBAR_RECCHANNELS_WIDTH, STATUSBAR_HEIGHT);
784 else
786 display->mono_bitmap(bitmap_icons_5x8[Icon_Stereo],
787 STATUSBAR_RECCHANNELS_X_POS, STATUSBAR_Y_POS,
788 STATUSBAR_RECCHANNELS_WIDTH, STATUSBAR_HEIGHT);
791 #endif /* HAVE_RECORDING */
793 #endif /* HAVE_LCD_BITMAP */
795 void gui_syncstatusbar_init(struct gui_syncstatusbar * bars)
797 int i;
798 FOR_NB_SCREENS(i) {
799 gui_statusbar_init( &(bars->statusbars[i]) );
800 gui_statusbar_set_screen( &(bars->statusbars[i]), &(screens[i]) );
804 void gui_syncstatusbar_draw(struct gui_syncstatusbar * bars,
805 bool force_redraw)
807 #ifdef HAVE_LCD_BITMAP
808 if(!global_settings.statusbar)
809 return;
810 #endif /* HAVE_LCD_BITMAP */
811 int i;
812 FOR_NB_SCREENS(i) {
813 gui_statusbar_draw( &(bars->statusbars[i]), force_redraw );
817 void gui_statusbar_changed(bool enabled)
819 (void)enabled;
820 send_event(GUI_EVENT_STATUSBAR_TOGGLE, NULL);