Strip trailing directory slash
[kugel-rb.git] / apps / status.c
blob03badc5b75c5f112c15b835aa8a7d3850409cdf8
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2002 by Linus Nielsen Feltzing
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
19 #include "string.h"
20 #include "lcd.h"
21 #include "debug.h"
22 #include "kernel.h"
23 #include "power.h"
24 #include "thread.h"
25 #include "settings.h"
26 #include "status.h"
27 #include "mp3_playback.h"
28 #include "mpeg.h"
29 #include "wps.h"
30 #ifdef HAVE_RTC
31 #include "timefuncs.h"
32 #endif
33 #ifdef HAVE_LCD_BITMAP
34 #include "icons.h"
35 #include "font.h"
36 #endif
37 #include "powermgmt.h"
39 static enum playmode ff_mode;
41 static long switch_tick;
42 static int battery_charge_step = 0;
43 static bool plug_state;
44 static bool battery_state = true;
46 struct status_info {
47 int battlevel;
48 int volume;
49 int hour;
50 int minute;
51 int playmode;
52 int repeat;
53 bool inserted;
54 bool shuffle;
55 bool keylock;
56 bool battery_safe;
57 bool redraw_volume; /* true if the volume gauge needs updating */
60 void status_init(void)
62 ff_mode = 0;
65 void status_set_ffmode(enum playmode mode)
67 ff_mode = mode; /* Either STATUS_FASTFORWARD or STATUS_FASTBACKWARD */
68 status_draw(false);
71 int current_playmode(void)
73 int mpeg_stat = mpeg_status();
75 /* ff_mode can be either STATUS_FASTFORWARD or STATUS_FASTBACKWARD
76 and that supercedes the other modes */
77 if(ff_mode)
78 return ff_mode;
80 if(mpeg_stat & MPEG_STATUS_PLAY)
82 if(mpeg_stat & MPEG_STATUS_PAUSE)
83 return STATUS_PAUSE;
84 else
85 return STATUS_PLAY;
87 #if CONFIG_HWCODEC == MAS3587F
88 else
90 if(mpeg_stat & MPEG_STATUS_RECORD)
92 if(mpeg_stat & MPEG_STATUS_PAUSE)
93 return STATUS_RECORD_PAUSE;
94 else
95 return STATUS_RECORD;
98 #endif
100 return STATUS_STOP;
103 #if defined(HAVE_LCD_CHARCELLS)
104 static bool record = false;
105 static bool audio = false;
106 static bool param = false;
107 static bool usb = false;
109 void status_set_record(bool b)
111 record = b;
114 void status_set_audio(bool b)
116 audio = b;
119 void status_set_param(bool b)
121 param = b;
124 void status_set_usb(bool b)
126 usb = b;
129 #endif /* HAVE_LCD_CHARCELLS */
131 void status_draw(bool force_redraw)
133 struct status_info info;
135 #ifdef HAVE_LCD_BITMAP
136 static struct status_info lastinfo;
137 struct tm* tm;
139 if ( !global_settings.statusbar )
140 return;
141 #else
142 (void)force_redraw; /* players always "redraw" */
143 #endif
145 info.volume = mpeg_val2phys(SOUND_VOLUME, global_settings.volume);
146 info.inserted = charger_inserted();
147 info.battlevel = battery_level();
148 info.battery_safe = battery_level_safe();
150 #ifdef HAVE_LCD_BITMAP
151 tm = get_time();
152 info.hour = tm->tm_hour;
153 info.minute = tm->tm_min;
154 info.shuffle = global_settings.playlist_shuffle;
155 info.keylock = keys_locked;
156 info.repeat = global_settings.repeat_mode;
157 info.playmode = current_playmode();
159 /* only redraw if forced to, or info has changed */
160 if (force_redraw ||
161 info.inserted ||
162 !info.battery_safe ||
163 info.redraw_volume ||
164 memcmp(&info, &lastinfo, sizeof(struct status_info)))
166 lcd_clearrect(0,0,LCD_WIDTH,8);
167 #else
168 /* players always "redraw" */
170 #endif
172 if (info.inserted) {
173 battery_state = true;
174 plug_state = true;
175 #if defined(HAVE_CHARGE_CTRL) || CONFIG_BATTERY == BATT_LIION2200
176 /* zero battery run time if charging */
177 if (charge_state > 0) {
178 global_settings.runtime = 0;
179 lasttime = current_tick;
182 /* animate battery if charging */
183 if ((charge_state == 1) ||
184 (charge_state == 2)) {
185 #else
186 global_settings.runtime = 0;
187 lasttime = current_tick;
189 #endif
190 /* animate in three steps (34% per step for a better look) */
191 info.battlevel = battery_charge_step * 34;
192 if (info.battlevel > 100)
193 info.battlevel = 100;
194 if(TIME_AFTER(current_tick, switch_tick)) {
195 battery_charge_step=(battery_charge_step+1)%4;
196 switch_tick = current_tick + HZ;
200 else {
201 plug_state=false;
202 if (info.battery_safe)
203 battery_state = true;
204 else {
205 /* blink battery if level is low */
206 if(TIME_AFTER(current_tick, switch_tick) &&
207 (info.battlevel > -1)) {
208 switch_tick = current_tick+HZ;
209 battery_state =! battery_state;
214 #ifdef HAVE_LCD_BITMAP
215 if (battery_state)
216 statusbar_icon_battery(info.battlevel, plug_state);
218 info.redraw_volume = statusbar_icon_volume(info.volume);
219 statusbar_icon_play_state(current_playmode() + Icon_Play);
220 switch (info.repeat) {
221 case REPEAT_ONE:
222 statusbar_icon_play_mode(Icon_RepeatOne);
223 break;
225 case REPEAT_ALL:
226 statusbar_icon_play_mode(Icon_Repeat);
227 break;
229 if (info.shuffle)
230 statusbar_icon_shuffle();
231 if (info.keylock)
232 statusbar_icon_lock();
233 #ifdef HAVE_RTC
234 statusbar_time(info.hour, info.minute);
235 #endif
236 lcd_update_rect(0, 0, LCD_WIDTH, STATUSBAR_HEIGHT);
237 lastinfo = info;
238 #endif
242 #if defined(HAVE_LCD_CHARCELLS)
243 if (info.battlevel > -1)
244 lcd_icon(ICON_BATTERY, battery_state);
245 lcd_icon(ICON_BATTERY_1, info.battlevel > 25);
246 lcd_icon(ICON_BATTERY_2, info.battlevel > 50);
247 lcd_icon(ICON_BATTERY_3, info.battlevel > 75);
249 lcd_icon(ICON_VOLUME, true);
250 lcd_icon(ICON_VOLUME_1, info.volume > 10);
251 lcd_icon(ICON_VOLUME_2, info.volume > 30);
252 lcd_icon(ICON_VOLUME_3, info.volume > 50);
253 lcd_icon(ICON_VOLUME_4, info.volume > 70);
254 lcd_icon(ICON_VOLUME_5, info.volume > 90);
256 lcd_icon(ICON_PLAY, current_playmode() == STATUS_PLAY);
257 lcd_icon(ICON_PAUSE, current_playmode() == STATUS_PAUSE);
259 lcd_icon(ICON_REPEAT, global_settings.repeat_mode != REPEAT_OFF);
260 lcd_icon(ICON_1, global_settings.repeat_mode == REPEAT_ONE);
262 lcd_icon(ICON_RECORD, record);
263 lcd_icon(ICON_AUDIO, audio);
264 lcd_icon(ICON_PARAM, param);
265 lcd_icon(ICON_USB, usb);
266 #endif
270 #if defined(HAVE_LCD_BITMAP) && (CONFIG_KEYPAD == RECORDER_PAD)
271 static void draw_buttonbar_btn(int num, const char* caption)
273 int xpos, ypos, button_width, text_width;
274 int fw, fh;
276 lcd_setfont(FONT_SYSFIXED);
277 lcd_getstringsize("M", &fw, &fh);
279 button_width = LCD_WIDTH/3;
280 xpos = num * button_width;
281 ypos = LCD_HEIGHT - fh;
283 if(caption)
285 /* center the text */
286 text_width = fw * strlen(caption);
287 lcd_putsxy(xpos + (button_width - text_width)/2, ypos, caption);
290 lcd_invertrect(xpos, ypos, button_width - 1, fh);
293 static char stored_caption1[8];
294 static char stored_caption2[8];
295 static char stored_caption3[8];
297 void buttonbar_set(const char* caption1, const char *caption2,
298 const char *caption3)
300 buttonbar_unset();
301 if(caption1)
303 strncpy(stored_caption1, caption1, 7);
304 stored_caption1[7] = 0;
306 if(caption2)
308 strncpy(stored_caption2, caption2, 7);
309 stored_caption2[7] = 0;
311 if(caption3)
313 strncpy(stored_caption3, caption3, 7);
314 stored_caption3[7] = 0;
318 void buttonbar_unset(void)
320 stored_caption1[0] = 0;
321 stored_caption2[0] = 0;
322 stored_caption3[0] = 0;
325 void buttonbar_draw(void)
327 lcd_clearrect(0, LCD_HEIGHT-8, LCD_WIDTH, 8);
328 draw_buttonbar_btn(0, stored_caption1);
329 draw_buttonbar_btn(1, stored_caption2);
330 draw_buttonbar_btn(2, stored_caption3);
333 bool buttonbar_isset(void)
335 /* If all buttons are unset, the button bar is considered disabled */
336 return (global_settings.buttonbar &&
337 ((stored_caption1[0] != 0) ||
338 (stored_caption2[0] != 0) ||
339 (stored_caption3[0] != 0)));
342 #endif