Updated our source code header to explicitly mention that we are GPL v2 or
[Rockbox.git] / apps / gui / statusbar.c
blobb9941eb0615f69c1fd1f0ed4f3a9e2f0b183a4ea
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 "icons.h"
30 #include "powermgmt.h"
31 #include "usb.h"
32 #include "led.h"
34 #include "status.h" /* needed for battery_state global var */
35 #include "action.h" /* for keys_locked */
36 #include "statusbar.h"
37 #ifdef HAVE_RECORDING
38 #include "audio.h"
39 #include "recording.h"
40 #endif
42 /* FIXME: should be removed from icon.h to avoid redefinition,
43 but still needed for compatibility with old system */
44 #define ICONS_SPACING 2
45 #define STATUSBAR_BATTERY_X_POS 0*ICONS_SPACING
46 #define STATUSBAR_BATTERY_WIDTH 18
47 #define STATUSBAR_PLUG_X_POS STATUSBAR_X_POS + \
48 STATUSBAR_BATTERY_WIDTH + \
49 ICONS_SPACING
50 #define STATUSBAR_PLUG_WIDTH 7
51 #define STATUSBAR_VOLUME_X_POS STATUSBAR_X_POS + \
52 STATUSBAR_BATTERY_WIDTH + \
53 STATUSBAR_PLUG_WIDTH + \
54 2*ICONS_SPACING
55 #define STATUSBAR_VOLUME_WIDTH 16
56 #define STATUSBAR_ENCODER_X_POS STATUSBAR_X_POS + \
57 STATUSBAR_BATTERY_WIDTH + \
58 STATUSBAR_PLUG_WIDTH + \
59 2*ICONS_SPACING - 1
60 #define STATUSBAR_ENCODER_WIDTH 18
61 #define STATUSBAR_PLAY_STATE_X_POS STATUSBAR_X_POS + \
62 STATUSBAR_BATTERY_WIDTH + \
63 STATUSBAR_PLUG_WIDTH + \
64 STATUSBAR_VOLUME_WIDTH + \
65 3*ICONS_SPACING
66 #define STATUSBAR_PLAY_STATE_WIDTH 7
67 #define STATUSBAR_PLAY_MODE_X_POS STATUSBAR_X_POS + \
68 STATUSBAR_BATTERY_WIDTH + \
69 STATUSBAR_PLUG_WIDTH + \
70 STATUSBAR_VOLUME_WIDTH + \
71 STATUSBAR_PLAY_STATE_WIDTH + \
72 4*ICONS_SPACING
73 #define STATUSBAR_PLAY_MODE_WIDTH 7
74 #define STATUSBAR_RECFREQ_X_POS STATUSBAR_X_POS + \
75 STATUSBAR_BATTERY_WIDTH + \
76 STATUSBAR_PLUG_WIDTH + \
77 STATUSBAR_VOLUME_WIDTH + \
78 STATUSBAR_PLAY_STATE_WIDTH + \
79 3*ICONS_SPACING
80 #define STATUSBAR_RECFREQ_WIDTH 12
81 #define STATUSBAR_RECCHANNELS_X_POS STATUSBAR_X_POS + \
82 STATUSBAR_BATTERY_WIDTH + \
83 STATUSBAR_PLUG_WIDTH + \
84 STATUSBAR_VOLUME_WIDTH + \
85 STATUSBAR_PLAY_STATE_WIDTH + \
86 STATUSBAR_RECFREQ_WIDTH + \
87 4*ICONS_SPACING
88 #define STATUSBAR_RECCHANNELS_WIDTH 5
89 #define STATUSBAR_SHUFFLE_X_POS STATUSBAR_X_POS + \
90 STATUSBAR_BATTERY_WIDTH + \
91 STATUSBAR_PLUG_WIDTH + \
92 STATUSBAR_VOLUME_WIDTH + \
93 STATUSBAR_PLAY_STATE_WIDTH + \
94 STATUSBAR_PLAY_MODE_WIDTH + \
95 5*ICONS_SPACING
96 #define STATUSBAR_SHUFFLE_WIDTH 7
97 #define STATUSBAR_LOCKM_X_POS STATUSBAR_X_POS + \
98 STATUSBAR_BATTERY_WIDTH + \
99 STATUSBAR_PLUG_WIDTH + \
100 STATUSBAR_VOLUME_WIDTH + \
101 STATUSBAR_PLAY_STATE_WIDTH + \
102 STATUSBAR_PLAY_MODE_WIDTH + \
103 STATUSBAR_SHUFFLE_WIDTH + \
104 6*ICONS_SPACING
105 #define STATUSBAR_LOCKM_WIDTH 5
106 #define STATUSBAR_LOCKR_X_POS STATUSBAR_X_POS + \
107 STATUSBAR_BATTERY_WIDTH + \
108 STATUSBAR_PLUG_WIDTH + \
109 STATUSBAR_VOLUME_WIDTH + \
110 STATUSBAR_PLAY_STATE_WIDTH + \
111 STATUSBAR_PLAY_MODE_WIDTH + \
112 STATUSBAR_SHUFFLE_WIDTH + \
113 STATUSBAR_LOCKM_WIDTH + \
114 7*ICONS_SPACING
115 #define STATUSBAR_LOCKR_WIDTH 5
117 #if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
118 #define STATUSBAR_DISK_WIDTH 12
119 #define STATUSBAR_DISK_X_POS(statusbar_width) statusbar_width - \
120 STATUSBAR_DISK_WIDTH
121 #else
122 #define STATUSBAR_DISK_WIDTH 0
123 #endif
124 #define STATUSBAR_TIME_X_END(statusbar_width) statusbar_width - 1 - \
125 STATUSBAR_DISK_WIDTH
126 struct gui_syncstatusbar statusbars;
128 /* Prototypes */
129 #ifdef HAVE_LCD_BITMAP
130 static void gui_statusbar_icon_battery(struct screen * display, int percent,
131 int batt_charge_step);
132 static bool gui_statusbar_icon_volume(struct gui_statusbar * bar, int volume);
133 static void gui_statusbar_icon_play_state(struct screen * display, int state);
134 static void gui_statusbar_icon_play_mode(struct screen * display, int mode);
135 static void gui_statusbar_icon_shuffle(struct screen * display);
136 static void gui_statusbar_icon_lock(struct screen * display);
137 #ifdef HAS_REMOTE_BUTTON_HOLD
138 static void gui_statusbar_icon_lock_remote(struct screen * display);
139 #endif
140 #if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
141 static void gui_statusbar_led(struct screen * display);
142 #endif
143 #ifdef HAVE_RECORDING
144 static void gui_statusbar_icon_recording_info(struct screen * display);
145 #endif
146 #if CONFIG_RTC
147 static void gui_statusbar_time(struct screen * display, struct tm *time);
148 #endif
149 #endif
151 /* End prototypes */
155 * Initializes a status bar
156 * - bar : the bar to initialize
158 static void gui_statusbar_init(struct gui_statusbar * bar)
160 bar->redraw_volume = true;
161 bar->volume_icon_switch_tick = bar->battery_icon_switch_tick = current_tick;
162 memset((void*)&(bar->lastinfo), 0, sizeof(struct status_info));
163 #if CONFIG_RTC
164 bar->last_tm_min = 0;
165 #endif
168 void gui_statusbar_draw(struct gui_statusbar * bar, bool force_redraw)
170 struct screen * display = bar->display;
172 #ifdef HAVE_LCD_CHARCELLS
173 int val;
174 (void)force_redraw; /* players always "redraw" */
175 #endif /* HAVE_LCD_CHARCELLS */
177 bar->info.battlevel = battery_level();
178 #ifdef HAVE_USB_POWER
179 bar->info.usb_inserted = usb_inserted();
180 #endif
181 #if CONFIG_CHARGING
182 bar->info.inserted = (charger_input_state == CHARGER);
183 if (bar->info.inserted)
185 bar->info.battery_state = true;
187 #if CONFIG_CHARGING >= CHARGING_MONITOR
189 /* zero battery run time if charging */
190 if (charge_state > DISCHARGING)
191 lasttime = current_tick;
193 /* animate battery if charging */
194 if ((charge_state == DISCHARGING) || (charge_state == TRICKLE))
196 bar->info.batt_charge_step = -1;
198 else
200 #else /* CONFIG_CHARGING < CHARGING_MONITOR */
201 lasttime = current_tick;
203 #endif /* CONFIG_CHARGING < CHARGING_MONITOR */
204 /* animate in (max.) 4 steps, starting near the current charge level */
205 if (TIME_AFTER(current_tick, bar->battery_icon_switch_tick))
207 if (++bar->info.batt_charge_step > 3)
208 bar->info.batt_charge_step = bar->info.battlevel / 34;
209 bar->battery_icon_switch_tick = current_tick + HZ;
213 else
214 #endif /* CONFIG_CHARGING */
216 bar->info.batt_charge_step = -1;
217 if (battery_level_safe())
218 bar->info.battery_state = true;
219 else
220 /* blink battery if level is low */
221 if (TIME_AFTER(current_tick, bar->battery_icon_switch_tick) &&
222 (bar->info.battlevel > -1))
224 bar->info.battery_state = !bar->info.battery_state;
225 bar->battery_icon_switch_tick = current_tick + HZ;
229 bar->info.volume = global_settings.volume;
230 #ifdef HAVE_LCD_BITMAP
231 bar->info.shuffle = global_settings.playlist_shuffle;
232 #ifdef HAS_BUTTON_HOLD
233 bar->info.keylock = button_hold();
234 #else
235 bar->info.keylock = is_keys_locked();
236 #endif /* HAS_BUTTON_HOLD */
237 #ifdef HAS_REMOTE_BUTTON_HOLD
238 bar->info.keylockremote = remote_button_hold();
239 #endif
240 bar->info.repeat = global_settings.repeat_mode;
241 bar->info.playmode = current_playmode();
243 #if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
244 if(!display->has_disk_led)
245 bar->info.led = led_read(HZ/2); /* delay should match polling interval */
246 #endif
247 #if CONFIG_RTC
248 bar->time = get_time();
249 #endif /* CONFIG_RTC */
251 /* only redraw if forced to, or info has changed */
252 if (force_redraw || bar->redraw_volume ||
253 #if CONFIG_RTC
254 (bar->time->tm_min != bar->last_tm_min) ||
255 #endif
256 memcmp(&(bar->info), &(bar->lastinfo), sizeof(struct status_info)))
258 display->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
259 display->fillrect(0, 0, display->width, STATUSBAR_HEIGHT);
260 display->set_drawmode(DRMODE_SOLID);
262 if (bar->info.battery_state)
263 gui_statusbar_icon_battery(display, bar->info.battlevel,
264 bar->info.batt_charge_step);
265 #ifdef HAVE_USB_POWER
266 if (bar->info.usb_inserted)
267 display->mono_bitmap(bitmap_icons_7x8[Icon_USBPlug],
268 STATUSBAR_PLUG_X_POS,
269 STATUSBAR_Y_POS, STATUSBAR_PLUG_WIDTH,
270 STATUSBAR_HEIGHT);
271 #endif /* HAVE_USB_POWER */
272 #if CONFIG_CHARGING
273 #ifdef HAVE_USB_POWER
274 else
275 #endif
276 /* draw power plug if charging */
277 if (bar->info.inserted)
278 display->mono_bitmap(bitmap_icons_7x8[Icon_Plug],
279 STATUSBAR_PLUG_X_POS,
280 STATUSBAR_Y_POS, STATUSBAR_PLUG_WIDTH,
281 STATUSBAR_HEIGHT);
282 #endif /* CONFIG_CHARGING */
283 #ifdef HAVE_RECORDING
284 /* turn off volume display in recording screen */
285 bool recscreen_on = in_recording_screen();
286 if (!recscreen_on)
287 #endif
288 bar->redraw_volume = gui_statusbar_icon_volume(bar, bar->info.volume);
289 gui_statusbar_icon_play_state(display, current_playmode() + Icon_Play);
291 #ifdef HAVE_RECORDING
292 /* If in recording screen, replace repeat mode, volume
293 and shuffle icons with recording info */
294 if (recscreen_on)
295 gui_statusbar_icon_recording_info(display);
296 else
297 #endif
299 switch (bar->info.repeat) {
300 #ifdef AB_REPEAT_ENABLE
301 case REPEAT_AB:
302 gui_statusbar_icon_play_mode(display, Icon_RepeatAB);
303 break;
304 #endif /* AB_REPEAT_ENABLE == 1 */
306 case REPEAT_ONE:
307 gui_statusbar_icon_play_mode(display, Icon_RepeatOne);
308 break;
310 case REPEAT_ALL:
311 case REPEAT_SHUFFLE:
312 gui_statusbar_icon_play_mode(display, Icon_Repeat);
313 break;
315 if (bar->info.shuffle)
316 gui_statusbar_icon_shuffle(display);
318 if (bar->info.keylock)
319 gui_statusbar_icon_lock(display);
320 #ifdef HAS_REMOTE_BUTTON_HOLD
321 if (bar->info.keylockremote)
322 gui_statusbar_icon_lock_remote(display);
323 #endif
324 #if CONFIG_RTC
325 gui_statusbar_time(display, bar->time);
326 bar->last_tm_min = bar->time->tm_min;
327 #endif /* CONFIG_RTC */
328 #if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
329 if(!display->has_disk_led && bar->info.led)
330 gui_statusbar_led(display);
331 #endif
332 display->update_rect(0, 0, display->width, STATUSBAR_HEIGHT);
333 bar->lastinfo = bar->info;
335 #endif /* HAVE_LCD_BITMAP */
338 #ifdef HAVE_LCD_CHARCELLS
339 display->icon(ICON_BATTERY, bar->info.battery_state);
341 if (bar->info.batt_charge_step > -1)
342 val = bar->info.batt_charge_step;
343 else
344 val = (bar->info.battlevel * 3 + 50) / 100;
345 display->icon(ICON_BATTERY_1, val >= 1);
346 display->icon(ICON_BATTERY_2, val >= 2);
347 display->icon(ICON_BATTERY_3, val >= 3);
349 val = 10 * (bar->info.volume - sound_min(SOUND_VOLUME))
350 / (sound_max(SOUND_VOLUME) - sound_min(SOUND_VOLUME));
351 display->icon(ICON_VOLUME, true);
352 display->icon(ICON_VOLUME_1, val >= 1);
353 display->icon(ICON_VOLUME_2, val >= 3);
354 display->icon(ICON_VOLUME_3, val >= 5);
355 display->icon(ICON_VOLUME_4, val >= 7);
356 display->icon(ICON_VOLUME_5, val >= 9);
358 display->icon(ICON_PLAY, current_playmode() == STATUS_PLAY);
359 display->icon(ICON_PAUSE, current_playmode() == STATUS_PAUSE);
361 display->icon(ICON_REPEAT, global_settings.repeat_mode != REPEAT_OFF);
362 display->icon(ICON_1, global_settings.repeat_mode == REPEAT_ONE);
364 display->icon(ICON_RECORD, record);
365 display->icon(ICON_AUDIO, audio);
366 display->icon(ICON_PARAM, param);
367 display->icon(ICON_USB, usb);
368 #endif /* HAVE_LCD_CHARCELLS */
371 #ifdef HAVE_LCD_BITMAP
372 /* from icon.c */
374 * Print battery icon to status bar
376 static void gui_statusbar_icon_battery(struct screen * display, int percent,
377 int batt_charge_step)
379 int fill, endfill;
380 char buffer[5];
381 unsigned int width, height;
382 #if LCD_DEPTH > 1
383 unsigned int prevfg = 0;
384 #endif
386 #if CONFIG_CHARGING
387 if (batt_charge_step >= 0)
389 fill = percent * (STATUSBAR_BATTERY_WIDTH-3) / 100;
390 endfill = 34 * batt_charge_step * (STATUSBAR_BATTERY_WIDTH-3) / 100;
392 else
393 #else
394 (void)batt_charge_step;
395 #endif
397 fill = endfill = (percent * (STATUSBAR_BATTERY_WIDTH-3) + 50) / 100;
400 #if CONFIG_CHARGING == CHARGING_MONITOR && !defined(SIMULATOR)
401 /* Certain charge controlled targets */
402 /* show graphical animation when charging instead of numbers */
403 if ((global_settings.battery_display) &&
404 (charge_state != CHARGING) &&
405 (percent > -1)) {
406 #else /* all others */
407 if (global_settings.battery_display && (percent > -1)) {
408 #endif
409 /* Numeric display */
410 display->setfont(FONT_SYSFIXED);
411 snprintf(buffer, sizeof(buffer), "%3d", percent);
412 display->getstringsize(buffer, &width, &height);
413 if (height <= STATUSBAR_HEIGHT)
414 display->putsxy(STATUSBAR_BATTERY_X_POS
415 + STATUSBAR_BATTERY_WIDTH / 2
416 - width/2, STATUSBAR_Y_POS, buffer);
417 display->setfont(FONT_UI);
420 else {
421 /* draw battery */
422 display->drawrect(STATUSBAR_BATTERY_X_POS, STATUSBAR_Y_POS, 17, 7);
423 display->vline(STATUSBAR_BATTERY_X_POS + 17, STATUSBAR_Y_POS + 2,
424 STATUSBAR_Y_POS + 4);
426 display->fillrect(STATUSBAR_BATTERY_X_POS + 1, STATUSBAR_Y_POS + 1,
427 fill, 5);
428 #if LCD_DEPTH > 1
429 if (display->depth > 1)
431 prevfg = display->get_foreground();
432 display->set_foreground(LCD_DARKGRAY);
434 #endif
435 display->fillrect(STATUSBAR_BATTERY_X_POS + 1 + fill,
436 STATUSBAR_Y_POS + 1, endfill - fill, 5);
437 #if LCD_DEPTH > 1
438 if (display->depth > 1)
439 display->set_foreground(prevfg);
440 #endif
443 if (percent == -1) {
444 display->setfont(FONT_SYSFIXED);
445 display->putsxy(STATUSBAR_BATTERY_X_POS + STATUSBAR_BATTERY_WIDTH / 2
446 - 4, STATUSBAR_Y_POS, "?");
447 display->setfont(FONT_UI);
452 * Print volume gauge to status bar
454 static bool gui_statusbar_icon_volume(struct gui_statusbar * bar, int volume)
456 int i;
457 int vol;
458 char buffer[4];
459 unsigned int width, height;
460 bool needs_redraw = false;
461 int type = global_settings.volume_type;
462 struct screen * display=bar->display;
463 const int minvol = sound_min(SOUND_VOLUME);
464 const int maxvol = sound_max(SOUND_VOLUME);
466 if (volume < minvol)
467 volume = minvol;
468 if (volume > maxvol)
469 volume = maxvol;
471 if (volume == minvol) {
472 display->mono_bitmap(bitmap_icons_7x8[Icon_Mute],
473 STATUSBAR_VOLUME_X_POS + STATUSBAR_VOLUME_WIDTH / 2 - 4,
474 STATUSBAR_Y_POS, 7, STATUSBAR_HEIGHT);
476 else {
477 /* We want to redraw the icon later on */
478 if (bar->last_volume != volume && bar->last_volume >= minvol) {
479 bar->volume_icon_switch_tick = current_tick + HZ;
482 /* If the timeout hasn't yet been reached, we show it numerically
483 and tell the caller that we want to be called again */
484 if (TIME_BEFORE(current_tick,bar->volume_icon_switch_tick)) {
485 type = 1;
486 needs_redraw = true;
489 /* display volume level numerical? */
490 if (type)
492 display->setfont(FONT_SYSFIXED);
493 snprintf(buffer, sizeof(buffer), "%2d", volume);
494 display->getstringsize(buffer, &width, &height);
495 if (height <= STATUSBAR_HEIGHT)
497 display->putsxy(STATUSBAR_VOLUME_X_POS
498 + STATUSBAR_VOLUME_WIDTH / 2
499 - width/2, STATUSBAR_Y_POS, buffer);
501 display->setfont(FONT_UI);
502 } else {
503 /* display volume bar */
504 vol = (volume - minvol) * 14 / (maxvol - minvol);
505 for(i=0; i < vol; i++) {
506 display->vline(STATUSBAR_VOLUME_X_POS + i,
507 STATUSBAR_Y_POS + 6 - i / 2,
508 STATUSBAR_Y_POS + 6);
512 bar->last_volume = volume;
514 return needs_redraw;
518 * Print play state to status bar
520 static void gui_statusbar_icon_play_state(struct screen * display, int state)
522 display->mono_bitmap(bitmap_icons_7x8[state], STATUSBAR_PLAY_STATE_X_POS,
523 STATUSBAR_Y_POS, STATUSBAR_PLAY_STATE_WIDTH,
524 STATUSBAR_HEIGHT);
528 * Print play mode to status bar
530 static void gui_statusbar_icon_play_mode(struct screen * display, int mode)
532 display->mono_bitmap(bitmap_icons_7x8[mode], STATUSBAR_PLAY_MODE_X_POS,
533 STATUSBAR_Y_POS, STATUSBAR_PLAY_MODE_WIDTH,
534 STATUSBAR_HEIGHT);
538 * Print shuffle mode to status bar
540 static void gui_statusbar_icon_shuffle(struct screen * display)
542 display->mono_bitmap(bitmap_icons_7x8[Icon_Shuffle],
543 STATUSBAR_SHUFFLE_X_POS, STATUSBAR_Y_POS,
544 STATUSBAR_SHUFFLE_WIDTH, STATUSBAR_HEIGHT);
548 * Print lock when keys are locked
550 static void gui_statusbar_icon_lock(struct screen * display)
552 display->mono_bitmap(bitmap_icons_5x8[Icon_Lock_Main],
553 STATUSBAR_LOCKM_X_POS, STATUSBAR_Y_POS,
554 STATUSBAR_LOCKM_WIDTH, STATUSBAR_HEIGHT);
557 #ifdef HAS_REMOTE_BUTTON_HOLD
559 * Print remote lock when remote hold is enabled
561 static void gui_statusbar_icon_lock_remote(struct screen * display)
563 display->mono_bitmap(bitmap_icons_5x8[Icon_Lock_Remote],
564 STATUSBAR_LOCKR_X_POS, STATUSBAR_Y_POS,
565 STATUSBAR_LOCKR_WIDTH, STATUSBAR_HEIGHT);
567 #endif
569 #if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
571 * no real LED: disk activity in status bar
573 static void gui_statusbar_led(struct screen * display)
575 display->mono_bitmap(bitmap_icon_disk,
576 STATUSBAR_DISK_X_POS(display->width),
577 STATUSBAR_Y_POS, STATUSBAR_DISK_WIDTH,
578 STATUSBAR_HEIGHT);
580 #endif
582 #if CONFIG_RTC
584 * Print time to status bar
586 static void gui_statusbar_time(struct screen * display, struct tm *time)
588 unsigned char buffer[6];
589 unsigned int width, height;
590 int hour, minute;
591 if ( valid_time(time) ) {
592 hour = time->tm_hour;
593 minute = time->tm_min;
594 if ( global_settings.timeformat ) { /* 12 hour clock */
595 hour %= 12;
596 if ( hour == 0 ) {
597 hour += 12;
600 snprintf(buffer, sizeof(buffer), "%02d:%02d", hour, minute);
602 else {
603 strncpy(buffer, "--:--", sizeof buffer);
605 display->setfont(FONT_SYSFIXED);
606 display->getstringsize(buffer, &width, &height);
607 if (height <= STATUSBAR_HEIGHT) {
608 display->putsxy(STATUSBAR_TIME_X_END(display->width) - width,
609 STATUSBAR_Y_POS, buffer);
611 display->setfont(FONT_UI);
614 #endif
616 #ifdef HAVE_RECORDING
617 #if CONFIG_CODEC == SWCODEC
619 * Write a number to the display using bitmaps and return new position
621 static int write_bitmap_number(struct screen * display, int value,
622 int x, int y)
624 char buf[12], *ptr;
625 snprintf(buf, sizeof(buf), "%d", value);
627 for (ptr = buf; *ptr != '\0'; ptr++, x += BM_GLYPH_WIDTH)
628 display->mono_bitmap(bitmap_glyphs_4x8[*ptr - '0'], x, y,
629 BM_GLYPH_WIDTH, STATUSBAR_HEIGHT);
630 return x;
634 * Write format info bitmaps - right justified
636 static void gui_statusbar_write_format_info(struct screen * display)
638 /* Can't fit info for sw codec targets in statusbar using FONT_SYSFIXED
639 so must use icons */
640 int rec_format = global_settings.rec_format;
641 unsigned bitrk = 0; /* compiler warns about unitialized use !! */
642 int xpos = STATUSBAR_ENCODER_X_POS;
643 int width = STATUSBAR_ENCODER_WIDTH;
644 const unsigned char *bm = bitmap_formats_18x8[rec_format];
646 if (rec_format == REC_FORMAT_MPA_L3)
648 /* Special handling for mp3 */
649 bitrk = global_settings.mp3_enc_config.bitrate;
650 bitrk = mp3_enc_bitr[bitrk];
652 width = BM_MPA_L3_M_WIDTH;
654 /* Slide 'M' to right if fewer than three digits used */
655 if (bitrk > 999)
656 bitrk = 999; /* neurotic safety check if corrupted */
657 else
659 if (bitrk < 100)
660 xpos += BM_GLYPH_WIDTH;
661 if (bitrk < 10)
662 xpos += BM_GLYPH_WIDTH;
667 /* Show bitmap - clipping right edge if needed */
668 display->mono_bitmap_part(bm, 0, 0, STATUSBAR_ENCODER_WIDTH,
669 xpos, STATUSBAR_Y_POS, width, STATUSBAR_HEIGHT);
671 if (rec_format == REC_FORMAT_MPA_L3)
673 xpos += BM_MPA_L3_M_WIDTH; /* to right of 'M' */
674 write_bitmap_number(display, bitrk, xpos, STATUSBAR_Y_POS);
679 * Write sample rate using bitmaps - left justified
681 static void gui_statusbar_write_samplerate_info(struct screen * display)
683 unsigned long samprk;
684 int xpos;
686 #ifdef SIMULATOR
687 samprk = 44100;
688 #else
689 #ifdef HAVE_SPDIF_REC
690 if (global_settings.rec_source == AUDIO_SRC_SPDIF)
691 /* Use rate in use, not current measured rate if it changed */
692 samprk = pcm_rec_sample_rate();
693 else
694 #endif
695 samprk = rec_freq_sampr[global_settings.rec_frequency];
696 #endif /* SIMULATOR */
698 samprk /= 1000;
699 if (samprk > 99)
700 samprk = 99; /* Limit to 3 glyphs */
702 xpos = write_bitmap_number(display, (unsigned)samprk,
703 STATUSBAR_RECFREQ_X_POS, STATUSBAR_Y_POS);
705 /* write the 'k' */
706 display->mono_bitmap(bitmap_glyphs_4x8[Glyph_4x8_k], xpos,
707 STATUSBAR_Y_POS, BM_GLYPH_WIDTH,
708 STATUSBAR_HEIGHT);
710 #endif /* CONFIG_CODEC == SWCODEC */
712 static void gui_statusbar_icon_recording_info(struct screen * display)
714 #if CONFIG_CODEC != SWCODEC
715 char buffer[3];
716 int width, height;
717 display->setfont(FONT_SYSFIXED);
718 #endif /* CONFIG_CODEC != SWCODEC */
720 /* Display Codec info in statusbar */
721 #if CONFIG_CODEC == SWCODEC
722 gui_statusbar_write_format_info(display);
723 #else /* !SWCODEC */
724 display->mono_bitmap(bitmap_icons_5x8[Icon_q],
725 STATUSBAR_ENCODER_X_POS + 8, STATUSBAR_Y_POS,
726 5, STATUSBAR_HEIGHT);
728 snprintf(buffer, sizeof(buffer), "%d", global_settings.rec_quality);
729 display->getstringsize(buffer, &width, &height);
730 if (height <= STATUSBAR_HEIGHT)
731 display->putsxy(STATUSBAR_ENCODER_X_POS + 13, STATUSBAR_Y_POS, buffer);
732 #endif /* CONFIG_CODEC == SWCODEC */
734 /* Display Samplerate info in statusbar */
735 #if CONFIG_CODEC == SWCODEC
736 /* SWCODEC targets use bitmaps for glyphs */
737 gui_statusbar_write_samplerate_info(display);
738 #else /* !SWCODEC */
739 /* hwcodec targets have sysfont characters */
740 #ifdef HAVE_SPDIF_REC
741 if (global_settings.rec_source == AUDIO_SRC_SPDIF)
743 /* Can't measure S/PDIF sample rate on Archos/Sim yet */
744 snprintf(buffer, sizeof(buffer), "--");
746 else
747 #endif /* HAVE_SPDIF_IN */
749 static char const * const freq_strings[12] =
750 { "44", "48", "32", "22", "24", "16" };
751 snprintf(buffer, sizeof(buffer), "%s",
752 freq_strings[global_settings.rec_frequency]);
755 display->getstringsize(buffer, &width, &height);
757 if (height <= STATUSBAR_HEIGHT)
758 display->putsxy(STATUSBAR_RECFREQ_X_POS, STATUSBAR_Y_POS, buffer);
760 display->setfont(FONT_UI);
761 #endif /* CONFIG_CODEC == SWCODEC */
763 /* Display Channel status in status bar */
764 if(global_settings.rec_channels)
766 display->mono_bitmap(bitmap_icons_5x8[Icon_Mono],
767 STATUSBAR_RECCHANNELS_X_POS , STATUSBAR_Y_POS,
768 STATUSBAR_RECCHANNELS_WIDTH, STATUSBAR_HEIGHT);
770 else
772 display->mono_bitmap(bitmap_icons_5x8[Icon_Stereo],
773 STATUSBAR_RECCHANNELS_X_POS, STATUSBAR_Y_POS,
774 STATUSBAR_RECCHANNELS_WIDTH, STATUSBAR_HEIGHT);
777 #endif /* HAVE_RECORDING */
779 #endif /* HAVE_LCD_BITMAP */
781 void gui_syncstatusbar_init(struct gui_syncstatusbar * bars)
783 int i;
784 FOR_NB_SCREENS(i) {
785 gui_statusbar_init( &(bars->statusbars[i]) );
786 gui_statusbar_set_screen( &(bars->statusbars[i]), &(screens[i]) );
790 void gui_syncstatusbar_draw(struct gui_syncstatusbar * bars,
791 bool force_redraw)
793 #ifdef HAVE_LCD_BITMAP
794 if(!global_settings.statusbar)
795 return;
796 #endif /* HAVE_LCD_BITMAP */
797 int i;
798 FOR_NB_SCREENS(i) {
799 gui_statusbar_draw( &(bars->statusbars[i]), force_redraw );
803 int gui_statusbar_height(void)
805 return global_settings.statusbar ? STATUSBAR_HEIGHT : 0;