Reorder some operands to increase frequency of multiply early termination on TDMI...
[kugel-rb.git] / apps / gui / statusbar.c
blob47dcb4ead17e15ef62dc2bd92d06657324d198ca
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 if (statusbar_position(display->screen_type) != STATUSBAR_BOTTOM)
270 vp.y = 0;
271 else
272 vp.y = display->lcdheight - STATUSBAR_HEIGHT;
273 display->set_viewport(&vp);
274 display->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
275 display->fillrect(0, 0, display->getwidth(), STATUSBAR_HEIGHT);
276 display->set_drawmode(DRMODE_SOLID);
278 if (bar->info.battery_state)
279 gui_statusbar_icon_battery(display, bar->info.battlevel,
280 bar->info.batt_charge_step);
281 #ifdef HAVE_USB_POWER
282 if (bar->info.usb_inserted)
283 display->mono_bitmap(bitmap_icons_7x8[Icon_USBPlug],
284 STATUSBAR_PLUG_X_POS,
285 STATUSBAR_Y_POS, STATUSBAR_PLUG_WIDTH,
286 STATUSBAR_HEIGHT);
287 #endif /* HAVE_USB_POWER */
288 #if CONFIG_CHARGING
289 #ifdef HAVE_USB_POWER
290 else
291 #endif
292 /* draw power plug if charging */
293 if (bar->info.inserted)
294 display->mono_bitmap(bitmap_icons_7x8[Icon_Plug],
295 STATUSBAR_PLUG_X_POS,
296 STATUSBAR_Y_POS, STATUSBAR_PLUG_WIDTH,
297 STATUSBAR_HEIGHT);
298 #endif /* CONFIG_CHARGING */
299 #ifdef HAVE_RECORDING
300 /* turn off volume display in recording screen */
301 bool recscreen_on = in_recording_screen();
302 if (!recscreen_on)
303 #endif
304 bar->redraw_volume = gui_statusbar_icon_volume(bar, bar->info.volume);
305 gui_statusbar_icon_play_state(display, current_playmode() + Icon_Play);
307 #ifdef HAVE_RECORDING
308 /* If in recording screen, replace repeat mode, volume
309 and shuffle icons with recording info */
310 if (recscreen_on)
311 gui_statusbar_icon_recording_info(display);
312 else
313 #endif
315 switch (bar->info.repeat) {
316 #ifdef AB_REPEAT_ENABLE
317 case REPEAT_AB:
318 gui_statusbar_icon_play_mode(display, Icon_RepeatAB);
319 break;
320 #endif /* AB_REPEAT_ENABLE == 1 */
322 case REPEAT_ONE:
323 gui_statusbar_icon_play_mode(display, Icon_RepeatOne);
324 break;
326 case REPEAT_ALL:
327 case REPEAT_SHUFFLE:
328 gui_statusbar_icon_play_mode(display, Icon_Repeat);
329 break;
331 if (bar->info.shuffle)
332 gui_statusbar_icon_shuffle(display);
334 if (bar->info.keylock)
335 gui_statusbar_icon_lock(display);
336 #ifdef HAS_REMOTE_BUTTON_HOLD
337 if (bar->info.keylockremote)
338 gui_statusbar_icon_lock_remote(display);
339 #endif
340 #if CONFIG_RTC
341 gui_statusbar_time(display, bar->time);
342 bar->last_tm_min = bar->time->tm_min;
343 #endif /* CONFIG_RTC */
344 #if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
345 if(!display->has_disk_led && bar->info.led)
346 gui_statusbar_led(display);
347 #endif
348 display->update_viewport();
349 display->set_viewport(NULL);
350 bar->lastinfo = bar->info;
352 #endif /* HAVE_LCD_BITMAP */
355 #ifdef HAVE_LCD_CHARCELLS
356 display->icon(ICON_BATTERY, bar->info.battery_state);
358 if (bar->info.batt_charge_step > -1)
359 val = bar->info.batt_charge_step;
360 else
361 val = (bar->info.battlevel * 3 + 50) / 100;
362 display->icon(ICON_BATTERY_1, val >= 1);
363 display->icon(ICON_BATTERY_2, val >= 2);
364 display->icon(ICON_BATTERY_3, val >= 3);
366 val = 10 * (bar->info.volume - sound_min(SOUND_VOLUME))
367 / (sound_max(SOUND_VOLUME) - sound_min(SOUND_VOLUME));
368 display->icon(ICON_VOLUME, true);
369 display->icon(ICON_VOLUME_1, val >= 1);
370 display->icon(ICON_VOLUME_2, val >= 3);
371 display->icon(ICON_VOLUME_3, val >= 5);
372 display->icon(ICON_VOLUME_4, val >= 7);
373 display->icon(ICON_VOLUME_5, val >= 9);
375 display->icon(ICON_PLAY, current_playmode() == STATUS_PLAY);
376 display->icon(ICON_PAUSE, current_playmode() == STATUS_PAUSE);
378 display->icon(ICON_REPEAT, global_settings.repeat_mode != REPEAT_OFF);
379 display->icon(ICON_1, global_settings.repeat_mode == REPEAT_ONE);
381 display->icon(ICON_RECORD, record);
382 display->icon(ICON_AUDIO, audio);
383 display->icon(ICON_PARAM, param);
384 display->icon(ICON_USB, usb);
385 #endif /* HAVE_LCD_CHARCELLS */
388 #ifdef HAVE_LCD_BITMAP
389 /* from icon.c */
391 * Print battery icon to status bar
393 static void gui_statusbar_icon_battery(struct screen * display, int percent,
394 int batt_charge_step)
396 int fill, endfill;
397 char buffer[5];
398 unsigned int width, height;
399 #if LCD_DEPTH > 1
400 unsigned int prevfg = 0;
401 #endif
403 #if CONFIG_CHARGING
404 if (batt_charge_step >= 0)
406 fill = percent * (STATUSBAR_BATTERY_WIDTH-3) / 100;
407 endfill = 34 * batt_charge_step * (STATUSBAR_BATTERY_WIDTH-3) / 100;
409 else
410 #else
411 (void)batt_charge_step;
412 #endif
414 fill = endfill = (percent * (STATUSBAR_BATTERY_WIDTH-3) + 50) / 100;
417 #if CONFIG_CHARGING == CHARGING_MONITOR && !defined(SIMULATOR)
418 /* Certain charge controlled targets */
419 /* show graphical animation when charging instead of numbers */
420 if ((global_settings.battery_display) &&
421 (charge_state != CHARGING) &&
422 (percent > -1)) {
423 #else /* all others */
424 if (global_settings.battery_display && (percent > -1)) {
425 #endif
426 /* Numeric display */
427 display->setfont(FONT_SYSFIXED);
428 snprintf(buffer, sizeof(buffer), "%3d", percent);
429 display->getstringsize(buffer, &width, &height);
430 if (height <= STATUSBAR_HEIGHT)
431 display->putsxy(STATUSBAR_BATTERY_X_POS
432 + STATUSBAR_BATTERY_WIDTH / 2
433 - width/2, STATUSBAR_Y_POS, buffer);
434 display->setfont(FONT_UI);
437 else {
438 /* draw battery */
439 display->drawrect(STATUSBAR_BATTERY_X_POS, STATUSBAR_Y_POS, 17, 7);
440 display->vline(STATUSBAR_BATTERY_X_POS + 17, STATUSBAR_Y_POS + 2,
441 STATUSBAR_Y_POS + 4);
443 display->fillrect(STATUSBAR_BATTERY_X_POS + 1, STATUSBAR_Y_POS + 1,
444 fill, 5);
445 #if LCD_DEPTH > 1
446 if (display->depth > 1)
448 prevfg = display->get_foreground();
449 display->set_foreground(LCD_DARKGRAY);
451 #endif
452 display->fillrect(STATUSBAR_BATTERY_X_POS + 1 + fill,
453 STATUSBAR_Y_POS + 1, endfill - fill, 5);
454 #if LCD_DEPTH > 1
455 if (display->depth > 1)
456 display->set_foreground(prevfg);
457 #endif
460 if (percent == -1) {
461 display->setfont(FONT_SYSFIXED);
462 display->putsxy(STATUSBAR_BATTERY_X_POS + STATUSBAR_BATTERY_WIDTH / 2
463 - 4, STATUSBAR_Y_POS, "?");
464 display->setfont(FONT_UI);
469 * Print volume gauge to status bar
471 static bool gui_statusbar_icon_volume(struct gui_statusbar * bar, int volume)
473 int i;
474 int vol;
475 char buffer[4];
476 unsigned int width, height;
477 bool needs_redraw = false;
478 int type = global_settings.volume_type;
479 struct screen * display=bar->display;
480 const int minvol = sound_min(SOUND_VOLUME);
481 const int maxvol = sound_max(SOUND_VOLUME);
483 if (volume < minvol)
484 volume = minvol;
485 if (volume > maxvol)
486 volume = maxvol;
488 if (volume == minvol) {
489 display->mono_bitmap(bitmap_icons_7x8[Icon_Mute],
490 STATUSBAR_VOLUME_X_POS + STATUSBAR_VOLUME_WIDTH / 2 - 4,
491 STATUSBAR_Y_POS, 7, STATUSBAR_HEIGHT);
493 else {
494 /* We want to redraw the icon later on */
495 if (bar->last_volume != volume && bar->last_volume >= minvol) {
496 bar->volume_icon_switch_tick = current_tick + HZ;
499 /* If the timeout hasn't yet been reached, we show it numerically
500 and tell the caller that we want to be called again */
501 if (TIME_BEFORE(current_tick,bar->volume_icon_switch_tick)) {
502 type = 1;
503 needs_redraw = true;
506 /* display volume level numerical? */
507 if (type)
509 display->setfont(FONT_SYSFIXED);
510 snprintf(buffer, sizeof(buffer), "%2d", volume);
511 display->getstringsize(buffer, &width, &height);
512 if (height <= STATUSBAR_HEIGHT)
514 display->putsxy(STATUSBAR_VOLUME_X_POS
515 + STATUSBAR_VOLUME_WIDTH / 2
516 - width/2, STATUSBAR_Y_POS, buffer);
518 display->setfont(FONT_UI);
519 } else {
520 /* display volume bar */
521 vol = (volume - minvol) * 14 / (maxvol - minvol);
522 for(i=0; i < vol; i++) {
523 display->vline(STATUSBAR_VOLUME_X_POS + i,
524 STATUSBAR_Y_POS + 6 - i / 2,
525 STATUSBAR_Y_POS + 6);
529 bar->last_volume = volume;
531 return needs_redraw;
535 * Print play state to status bar
537 static void gui_statusbar_icon_play_state(struct screen * display, int state)
539 display->mono_bitmap(bitmap_icons_7x8[state], STATUSBAR_PLAY_STATE_X_POS,
540 STATUSBAR_Y_POS, STATUSBAR_PLAY_STATE_WIDTH,
541 STATUSBAR_HEIGHT);
545 * Print play mode to status bar
547 static void gui_statusbar_icon_play_mode(struct screen * display, int mode)
549 display->mono_bitmap(bitmap_icons_7x8[mode], STATUSBAR_PLAY_MODE_X_POS,
550 STATUSBAR_Y_POS, STATUSBAR_PLAY_MODE_WIDTH,
551 STATUSBAR_HEIGHT);
555 * Print shuffle mode to status bar
557 static void gui_statusbar_icon_shuffle(struct screen * display)
559 display->mono_bitmap(bitmap_icons_7x8[Icon_Shuffle],
560 STATUSBAR_SHUFFLE_X_POS, STATUSBAR_Y_POS,
561 STATUSBAR_SHUFFLE_WIDTH, STATUSBAR_HEIGHT);
565 * Print lock when keys are locked
567 static void gui_statusbar_icon_lock(struct screen * display)
569 display->mono_bitmap(bitmap_icons_5x8[Icon_Lock_Main],
570 STATUSBAR_LOCKM_X_POS, STATUSBAR_Y_POS,
571 STATUSBAR_LOCKM_WIDTH, STATUSBAR_HEIGHT);
574 #ifdef HAS_REMOTE_BUTTON_HOLD
576 * Print remote lock when remote hold is enabled
578 static void gui_statusbar_icon_lock_remote(struct screen * display)
580 display->mono_bitmap(bitmap_icons_5x8[Icon_Lock_Remote],
581 STATUSBAR_LOCKR_X_POS, STATUSBAR_Y_POS,
582 STATUSBAR_LOCKR_WIDTH, STATUSBAR_HEIGHT);
584 #endif
586 #if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
588 * no real LED: disk activity in status bar
590 static void gui_statusbar_led(struct screen * display)
592 display->mono_bitmap(bitmap_icon_disk,
593 STATUSBAR_DISK_X_POS(display->getwidth()),
594 STATUSBAR_Y_POS, STATUSBAR_DISK_WIDTH,
595 STATUSBAR_HEIGHT);
597 #endif
599 #if CONFIG_RTC
601 * Print time to status bar
603 static void gui_statusbar_time(struct screen * display, struct tm *time)
605 unsigned char buffer[6];
606 unsigned int width, height;
607 int hour, minute;
608 if ( valid_time(time) ) {
609 hour = time->tm_hour;
610 minute = time->tm_min;
611 if ( global_settings.timeformat ) { /* 12 hour clock */
612 hour %= 12;
613 if ( hour == 0 ) {
614 hour += 12;
617 snprintf(buffer, sizeof(buffer), "%02d:%02d", hour, minute);
619 else {
620 strncpy(buffer, "--:--", sizeof buffer);
622 display->setfont(FONT_SYSFIXED);
623 display->getstringsize(buffer, &width, &height);
624 if (height <= STATUSBAR_HEIGHT) {
625 display->putsxy(STATUSBAR_TIME_X_END(display->getwidth()) - width,
626 STATUSBAR_Y_POS, buffer);
628 display->setfont(FONT_UI);
631 #endif
633 #ifdef HAVE_RECORDING
634 #if CONFIG_CODEC == SWCODEC
636 * Write a number to the display using bitmaps and return new position
638 static int write_bitmap_number(struct screen * display, int value,
639 int x, int y)
641 char buf[12], *ptr;
642 snprintf(buf, sizeof(buf), "%d", value);
644 for (ptr = buf; *ptr != '\0'; ptr++, x += BM_GLYPH_WIDTH)
645 display->mono_bitmap(bitmap_glyphs_4x8[*ptr - '0'], x, y,
646 BM_GLYPH_WIDTH, STATUSBAR_HEIGHT);
647 return x;
651 * Write format info bitmaps - right justified
653 static void gui_statusbar_write_format_info(struct screen * display)
655 /* Can't fit info for sw codec targets in statusbar using FONT_SYSFIXED
656 so must use icons */
657 int rec_format = global_settings.rec_format;
658 unsigned bitrk = 0; /* compiler warns about unitialized use !! */
659 int xpos = STATUSBAR_ENCODER_X_POS;
660 int width = STATUSBAR_ENCODER_WIDTH;
661 const unsigned char *bm = bitmap_formats_18x8[rec_format];
663 if (rec_format == REC_FORMAT_MPA_L3)
665 /* Special handling for mp3 */
666 bitrk = global_settings.mp3_enc_config.bitrate;
667 bitrk = mp3_enc_bitr[bitrk];
669 width = BM_MPA_L3_M_WIDTH;
671 /* Slide 'M' to right if fewer than three digits used */
672 if (bitrk > 999)
673 bitrk = 999; /* neurotic safety check if corrupted */
674 else
676 if (bitrk < 100)
677 xpos += BM_GLYPH_WIDTH;
678 if (bitrk < 10)
679 xpos += BM_GLYPH_WIDTH;
684 /* Show bitmap - clipping right edge if needed */
685 display->mono_bitmap_part(bm, 0, 0, STATUSBAR_ENCODER_WIDTH,
686 xpos, STATUSBAR_Y_POS, width, STATUSBAR_HEIGHT);
688 if (rec_format == REC_FORMAT_MPA_L3)
690 xpos += BM_MPA_L3_M_WIDTH; /* to right of 'M' */
691 write_bitmap_number(display, bitrk, xpos, STATUSBAR_Y_POS);
696 * Write sample rate using bitmaps - left justified
698 static void gui_statusbar_write_samplerate_info(struct screen * display)
700 unsigned long samprk;
701 int xpos;
703 #ifdef SIMULATOR
704 samprk = 44100;
705 #else
706 #ifdef HAVE_SPDIF_REC
707 if (global_settings.rec_source == AUDIO_SRC_SPDIF)
708 /* Use rate in use, not current measured rate if it changed */
709 samprk = pcm_rec_sample_rate();
710 else
711 #endif
712 samprk = rec_freq_sampr[global_settings.rec_frequency];
713 #endif /* SIMULATOR */
715 samprk /= 1000;
716 if (samprk > 99)
717 samprk = 99; /* Limit to 3 glyphs */
719 xpos = write_bitmap_number(display, (unsigned)samprk,
720 STATUSBAR_RECFREQ_X_POS, STATUSBAR_Y_POS);
722 /* write the 'k' */
723 display->mono_bitmap(bitmap_glyphs_4x8[Glyph_4x8_k], xpos,
724 STATUSBAR_Y_POS, BM_GLYPH_WIDTH,
725 STATUSBAR_HEIGHT);
727 #endif /* CONFIG_CODEC == SWCODEC */
729 static void gui_statusbar_icon_recording_info(struct screen * display)
731 #if CONFIG_CODEC != SWCODEC
732 char buffer[3];
733 int width, height;
734 display->setfont(FONT_SYSFIXED);
735 #endif /* CONFIG_CODEC != SWCODEC */
737 /* Display Codec info in statusbar */
738 #if CONFIG_CODEC == SWCODEC
739 gui_statusbar_write_format_info(display);
740 #else /* !SWCODEC */
741 display->mono_bitmap(bitmap_icons_5x8[Icon_q],
742 STATUSBAR_ENCODER_X_POS + 8, STATUSBAR_Y_POS,
743 5, STATUSBAR_HEIGHT);
745 snprintf(buffer, sizeof(buffer), "%d", global_settings.rec_quality);
746 display->getstringsize(buffer, &width, &height);
747 if (height <= STATUSBAR_HEIGHT)
748 display->putsxy(STATUSBAR_ENCODER_X_POS + 13, STATUSBAR_Y_POS, buffer);
749 #endif /* CONFIG_CODEC == SWCODEC */
751 /* Display Samplerate info in statusbar */
752 #if CONFIG_CODEC == SWCODEC
753 /* SWCODEC targets use bitmaps for glyphs */
754 gui_statusbar_write_samplerate_info(display);
755 #else /* !SWCODEC */
756 /* hwcodec targets have sysfont characters */
757 #ifdef HAVE_SPDIF_REC
758 if (global_settings.rec_source == AUDIO_SRC_SPDIF)
760 /* Can't measure S/PDIF sample rate on Archos/Sim yet */
761 strncpy(buffer, "--", sizeof(buffer));
763 else
764 #endif /* HAVE_SPDIF_IN */
766 static char const * const freq_strings[12] =
767 { "44", "48", "32", "22", "24", "16" };
768 strncpy(buffer, freq_strings[global_settings.rec_frequency],
769 sizeof(buffer));
772 display->getstringsize(buffer, &width, &height);
774 if (height <= STATUSBAR_HEIGHT)
775 display->putsxy(STATUSBAR_RECFREQ_X_POS, STATUSBAR_Y_POS, buffer);
777 display->setfont(FONT_UI);
778 #endif /* CONFIG_CODEC == SWCODEC */
780 /* Display Channel status in status bar */
781 if(global_settings.rec_channels)
783 display->mono_bitmap(bitmap_icons_5x8[Icon_Mono],
784 STATUSBAR_RECCHANNELS_X_POS , STATUSBAR_Y_POS,
785 STATUSBAR_RECCHANNELS_WIDTH, STATUSBAR_HEIGHT);
787 else
789 display->mono_bitmap(bitmap_icons_5x8[Icon_Stereo],
790 STATUSBAR_RECCHANNELS_X_POS, STATUSBAR_Y_POS,
791 STATUSBAR_RECCHANNELS_WIDTH, STATUSBAR_HEIGHT);
794 #endif /* HAVE_RECORDING */
796 #endif /* HAVE_LCD_BITMAP */
798 void gui_syncstatusbar_init(struct gui_syncstatusbar * bars)
800 int i;
801 FOR_NB_SCREENS(i) {
802 gui_statusbar_init( &(bars->statusbars[i]) );
803 gui_statusbar_set_screen( &(bars->statusbars[i]), &(screens[i]) );
807 void gui_syncstatusbar_draw(struct gui_syncstatusbar * bars,
808 bool force_redraw)
810 #ifdef HAVE_LCD_BITMAP
811 if(!global_settings.statusbar)
812 return;
813 #endif /* HAVE_LCD_BITMAP */
814 int i;
815 FOR_NB_SCREENS(i) {
816 gui_statusbar_draw( &(bars->statusbars[i]), force_redraw );
820 void gui_statusbar_changed(int enabled)
822 (void)enabled;
823 send_event(GUI_EVENT_STATUSBAR_TOGGLE, NULL);
825 #ifdef HAVE_REMOTE_LCD
826 int statusbar_position(int screen)
828 if (screen == SCREEN_REMOTE)
829 return global_settings.remote_statusbar;
830 return global_settings.statusbar;
832 #endif