summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/gui/skin_engine/skin_display.c83
-rw-r--r--apps/gui/skin_engine/skin_tokens.c181
2 files changed, 167 insertions, 97 deletions
diff --git a/apps/gui/skin_engine/skin_display.c b/apps/gui/skin_engine/skin_display.c
index 7d75b48506..67984cd2bb 100644
--- a/apps/gui/skin_engine/skin_display.c
+++ b/apps/gui/skin_engine/skin_display.c
@@ -145,6 +145,7 @@ static void draw_progressbar(struct gui_wps *gwps,
145 struct screen *display = gwps->display; 145 struct screen *display = gwps->display;
146 struct wps_state *state = gwps->state; 146 struct wps_state *state = gwps->state;
147 struct progressbar *pb = wps_vp->pb; 147 struct progressbar *pb = wps_vp->pb;
148 struct mp3entry *id3 = state->id3;
148 int y = pb->y; 149 int y = pb->y;
149 150
150 if (y < 0) 151 if (y < 0)
@@ -156,27 +157,37 @@ static void draw_progressbar(struct gui_wps *gwps,
156 y = (-y -1)*line_height + (0 > center ? 0 : center); 157 y = (-y -1)*line_height + (0 > center ? 0 : center);
157 } 158 }
158 159
160 int elapsed, length;
161 if (id3)
162 {
163 elapsed = id3->elapsed;
164 length = id3->length;
165 }
166 else
167 {
168 elapsed = 0;
169 length = 0;
170 }
171
159 if (pb->have_bitmap_pb) 172 if (pb->have_bitmap_pb)
160 gui_bitmap_scrollbar_draw(display, pb->bm, 173 gui_bitmap_scrollbar_draw(display, pb->bm,
161 pb->x, y, pb->width, pb->bm.height, 174 pb->x, y, pb->width, pb->bm.height,
162 state->id3->length ? state->id3->length : 1, 0, 175 length ? length : 1, 0,
163 state->id3->length ? state->id3->elapsed 176 length ? elapsed + state->ff_rewind_count : 0,
164 + state->ff_rewind_count : 0, 177 HORIZONTAL);
165 HORIZONTAL);
166 else 178 else
167 gui_scrollbar_draw(display, pb->x, y, pb->width, pb->height, 179 gui_scrollbar_draw(display, pb->x, y, pb->width, pb->height,
168 state->id3->length ? state->id3->length : 1, 0, 180 length ? length : 1, 0,
169 state->id3->length ? state->id3->elapsed 181 length ? elapsed + state->ff_rewind_count : 0,
170 + state->ff_rewind_count : 0, 182 HORIZONTAL);
171 HORIZONTAL);
172#ifdef AB_REPEAT_ENABLE 183#ifdef AB_REPEAT_ENABLE
173 if ( ab_repeat_mode_enabled() && state->id3->length != 0 ) 184 if ( ab_repeat_mode_enabled() && length != 0 )
174 ab_draw_markers(display, state->id3->length, 185 ab_draw_markers(display, length,
175 pb->x, pb->x + pb->width, y, pb->height); 186 pb->x, pb->x + pb->width, y, pb->height);
176#endif 187#endif
177 188
178 if (state->id3->cuesheet) 189 if (id3 && id3->cuesheet)
179 cue_draw_markers(display, state->id3->cuesheet, state->id3->length, 190 cue_draw_markers(display, state->id3->cuesheet, length,
180 pb->x, pb->x + pb->width, y+1, pb->height-2); 191 pb->x, pb->x + pb->width, y+1, pb->height-2);
181} 192}
182 193
@@ -266,12 +277,20 @@ static bool draw_player_progress(struct gui_wps *gwps)
266 int pos = 0; 277 int pos = 0;
267 int i; 278 int i;
268 279
269 if (!state->id3) 280 int elapsed, length;
270 return false; 281 if (LIKELY(state->id3))
282 {
283 elapsed = state->id3->elapsed;
284 length = state->id3->length;
285 }
286 else
287 {
288 elapsed = 0;
289 length = 0;
290 }
271 291
272 if (state->id3->length) 292 if (length)
273 pos = 36 * (state->id3->elapsed + state->ff_rewind_count) 293 pos = 36 * (elapsed + state->ff_rewind_count) / length;
274 / state->id3->length;
275 294
276 for (i = 0; i < 7; i++, pos -= 5) 295 for (i = 0; i < 7; i++, pos -= 5)
277 { 296 {
@@ -314,12 +333,24 @@ static void draw_player_fullbar(struct gui_wps *gwps, char* buf, int buf_size)
314 int digit, i, j; 333 int digit, i, j;
315 bool softchar; 334 bool softchar;
316 335
317 if (!state->id3 || buf_size < 34) /* worst case: 11x UTF-8 char + \0 */ 336 int elapsed, length;
337 if (LIKELY(state->id3))
338 {
339 elapsed = id3->elapsed;
340 length = id3->length;
341 }
342 else
343 {
344 elapsed = 0;
345 length = 0;
346 }
347
348 if (buf_size < 34) /* worst case: 11x UTF-8 char + \0 */
318 return; 349 return;
319 350
320 time = state->id3->elapsed + state->ff_rewind_count; 351 time = elapsed + state->ff_rewind_count;
321 if (state->id3->length) 352 if (length)
322 pos = 55 * time / state->id3->length; 353 pos = 55 * time / length;
323 354
324 memset(timestr, 0, sizeof(timestr)); 355 memset(timestr, 0, sizeof(timestr));
325 format_time(timestr, sizeof(timestr)-2, time); 356 format_time(timestr, sizeof(timestr)-2, time);
@@ -879,14 +910,8 @@ static bool skin_redraw(struct gui_wps *gwps, unsigned refresh_mode)
879{ 910{
880 struct wps_data *data = gwps->data; 911 struct wps_data *data = gwps->data;
881 struct screen *display = gwps->display; 912 struct screen *display = gwps->display;
882 struct wps_state *state = gwps->state;
883
884 if (!data || !state || !display)
885 return false;
886
887 struct mp3entry *id3 = state->id3;
888 913
889 if (!id3) 914 if (!data || !display || !gwps->state)
890 return false; 915 return false;
891 916
892 unsigned flags; 917 unsigned flags;
diff --git a/apps/gui/skin_engine/skin_tokens.c b/apps/gui/skin_engine/skin_tokens.c
index ac37c6dd3e..d607538f0f 100644
--- a/apps/gui/skin_engine/skin_tokens.c
+++ b/apps/gui/skin_engine/skin_tokens.c
@@ -63,7 +63,7 @@
63 63
64static char* get_codectype(const struct mp3entry* id3) 64static char* get_codectype(const struct mp3entry* id3)
65{ 65{
66 if (id3->codectype < AFMT_NUM_CODECS) { 66 if (id3 && id3->codectype < AFMT_NUM_CODECS) {
67 return (char*)audio_formats[id3->codectype].label; 67 return (char*)audio_formats[id3->codectype].label;
68 } else { 68 } else {
69 return NULL; 69 return NULL;
@@ -119,6 +119,27 @@ static char* get_dir(char* buf, int buf_size, const char* path, int level)
119 and the original value of *intval, inclusive). 119 and the original value of *intval, inclusive).
120 When not treating a conditional/enum, intval should be NULL. 120 When not treating a conditional/enum, intval should be NULL.
121*/ 121*/
122
123/* a few convinience macros for the id3 == NULL case
124 * depends on a few variable names in get_token_value() */
125
126#define HANDLE_NULL_ID3(id3field) (LIKELY(id3) ? (id3field) : na_str)
127
128#define HANDLE_NULL_ID3_NUM_ZERO { if (UNLIKELY(!id3)) return zero_str; }
129
130#define HANDLE_NULL_ID3_NUM_INTVAL(id3field) \
131 do { \
132 if (intval) { \
133 *intval = (LIKELY(id3) ? (id3field) + 1 : 0); \
134 } \
135 if (LIKELY(id3)) \
136 { \
137 snprintf(buf, buf_size, "%ld", (id3field)); \
138 return buf; \
139 } \
140 return zero_str; \
141 } while (0)
142
122const char *get_token_value(struct gui_wps *gwps, 143const char *get_token_value(struct gui_wps *gwps,
123 struct wps_token *token, 144 struct wps_token *token,
124 char *buf, int buf_size, 145 char *buf, int buf_size,
@@ -129,6 +150,9 @@ const char *get_token_value(struct gui_wps *gwps,
129 150
130 struct wps_data *data = gwps->data; 151 struct wps_data *data = gwps->data;
131 struct wps_state *state = gwps->state; 152 struct wps_state *state = gwps->state;
153 int elapsed, length;
154 static const char * const na_str = "n/a";
155 static const char * const zero_str = "0";
132 156
133 if (!data || !state) 157 if (!data || !state)
134 return NULL; 158 return NULL;
@@ -140,8 +164,16 @@ const char *get_token_value(struct gui_wps *gwps,
140 else 164 else
141 id3 = state->id3; 165 id3 = state->id3;
142 166
143 if (!id3) 167 if (id3)
144 return NULL; 168 {
169 elapsed = id3->elapsed;
170 length = id3->length;
171 }
172 else
173 {
174 elapsed = 0;
175 length = 0;
176 }
145 177
146#if CONFIG_RTC 178#if CONFIG_RTC
147 struct tm* tm = NULL; 179 struct tm* tm = NULL;
@@ -180,17 +212,17 @@ const char *get_token_value(struct gui_wps *gwps,
180 212
181 case WPS_TOKEN_TRACK_TIME_ELAPSED: 213 case WPS_TOKEN_TRACK_TIME_ELAPSED:
182 format_time(buf, buf_size, 214 format_time(buf, buf_size,
183 id3->elapsed + state->ff_rewind_count); 215 elapsed + state->ff_rewind_count);
184 return buf; 216 return buf;
185 217
186 case WPS_TOKEN_TRACK_TIME_REMAINING: 218 case WPS_TOKEN_TRACK_TIME_REMAINING:
187 format_time(buf, buf_size, 219 format_time(buf, buf_size,
188 id3->length - id3->elapsed - 220 length - elapsed -
189 state->ff_rewind_count); 221 state->ff_rewind_count);
190 return buf; 222 return buf;
191 223
192 case WPS_TOKEN_TRACK_LENGTH: 224 case WPS_TOKEN_TRACK_LENGTH:
193 format_time(buf, buf_size, id3->length); 225 format_time(buf, buf_size, length);
194 return buf; 226 return buf;
195 227
196 case WPS_TOKEN_PLAYLIST_ENTRIES: 228 case WPS_TOKEN_PLAYLIST_ENTRIES:
@@ -237,92 +269,102 @@ const char *get_token_value(struct gui_wps *gwps,
237 return buf; 269 return buf;
238 270
239 case WPS_TOKEN_TRACK_ELAPSED_PERCENT: 271 case WPS_TOKEN_TRACK_ELAPSED_PERCENT:
240 if (id3->length <= 0) 272 if (length <= 0)
241 return NULL; 273 return NULL;
242 274
243 if (intval) 275 if (intval)
244 { 276 {
245 *intval = limit * (id3->elapsed + state->ff_rewind_count) 277 *intval = limit * (elapsed + state->ff_rewind_count)
246 / id3->length + 1; 278 / length + 1;
247 } 279 }
248 snprintf(buf, buf_size, "%d", 280 snprintf(buf, buf_size, "%d",
249 100*(id3->elapsed + state->ff_rewind_count) / id3->length); 281 100*(elapsed + state->ff_rewind_count) / length);
250 return buf; 282 return buf;
251 283
252 case WPS_TOKEN_METADATA_ARTIST: 284 case WPS_TOKEN_METADATA_ARTIST:
253 return id3->artist; 285 return HANDLE_NULL_ID3(id3->artist);
254 286
255 case WPS_TOKEN_METADATA_COMPOSER: 287 case WPS_TOKEN_METADATA_COMPOSER:
256 return id3->composer; 288 return HANDLE_NULL_ID3(id3->composer);
257 289
258 case WPS_TOKEN_METADATA_ALBUM: 290 case WPS_TOKEN_METADATA_ALBUM:
259 return id3->album; 291 return HANDLE_NULL_ID3(id3->album);
260 292
261 case WPS_TOKEN_METADATA_ALBUM_ARTIST: 293 case WPS_TOKEN_METADATA_ALBUM_ARTIST:
262 return id3->albumartist; 294 return HANDLE_NULL_ID3(id3->albumartist);
263 295
264 case WPS_TOKEN_METADATA_GROUPING: 296 case WPS_TOKEN_METADATA_GROUPING:
265 return id3->grouping; 297 return HANDLE_NULL_ID3(id3->grouping);
266 298
267 case WPS_TOKEN_METADATA_GENRE: 299 case WPS_TOKEN_METADATA_GENRE:
268 return id3->genre_string; 300 return HANDLE_NULL_ID3(id3->genre_string);
269 301
270 case WPS_TOKEN_METADATA_DISC_NUMBER: 302 case WPS_TOKEN_METADATA_DISC_NUMBER:
271 if (id3->disc_string) 303 if (LIKELY(id3)) {
272 return id3->disc_string; 304 if (id3->disc_string)
273 if (id3->discnum) { 305 return id3->disc_string;
274 snprintf(buf, buf_size, "%d", id3->discnum); 306 if (id3->discnum) {
275 return buf; 307 snprintf(buf, buf_size, "%d", id3->discnum);
308 return buf;
309 }
276 } 310 }
277 return NULL; 311 return NULL;
278 312
279 case WPS_TOKEN_METADATA_TRACK_NUMBER: 313 case WPS_TOKEN_METADATA_TRACK_NUMBER:
280 if (id3->track_string) 314 if (LIKELY(id3)) {
281 return id3->track_string; 315 if (id3->track_string)
316 return id3->track_string;
282 317
283 if (id3->tracknum) { 318 if (id3->tracknum) {
284 snprintf(buf, buf_size, "%d", id3->tracknum); 319 snprintf(buf, buf_size, "%d", id3->tracknum);
285 return buf; 320 return buf;
321 }
286 } 322 }
287 return NULL; 323 return NULL;
288 324
289 case WPS_TOKEN_METADATA_TRACK_TITLE: 325 case WPS_TOKEN_METADATA_TRACK_TITLE:
290 return id3->title; 326 return HANDLE_NULL_ID3(id3->title);
291 327
292 case WPS_TOKEN_METADATA_VERSION: 328 case WPS_TOKEN_METADATA_VERSION:
293 switch (id3->id3version) 329 if (LIKELY(id3))
294 { 330 {
295 case ID3_VER_1_0: 331 switch (id3->id3version)
296 return "1"; 332 {
333 case ID3_VER_1_0:
334 return "1";
297 335
298 case ID3_VER_1_1: 336 case ID3_VER_1_1:
299 return "1.1"; 337 return "1.1";
300 338
301 case ID3_VER_2_2: 339 case ID3_VER_2_2:
302 return "2.2"; 340 return "2.2";
303 341
304 case ID3_VER_2_3: 342 case ID3_VER_2_3:
305 return "2.3"; 343 return "2.3";
306 344
307 case ID3_VER_2_4: 345 case ID3_VER_2_4:
308 return "2.4"; 346 return "2.4";
309 347
310 default: 348 default:
311 return NULL; 349 break;
350 }
312 } 351 }
352 return NULL;
313 353
314 case WPS_TOKEN_METADATA_YEAR: 354 case WPS_TOKEN_METADATA_YEAR:
315 if( id3->year_string ) 355 if (LIKELY(id3)) {
316 return id3->year_string; 356 if( id3->year_string )
357 return id3->year_string;
317 358
318 if (id3->year) { 359 if (id3->year) {
319 snprintf(buf, buf_size, "%d", id3->year); 360 snprintf(buf, buf_size, "%d", id3->year);
320 return buf; 361 return buf;
362 }
321 } 363 }
322 return NULL; 364 return NULL;
323 365
324 case WPS_TOKEN_METADATA_COMMENT: 366 case WPS_TOKEN_METADATA_COMMENT:
325 return id3->comment; 367 return HANDLE_NULL_ID3(id3->comment);
326 368
327#ifdef HAVE_ALBUMART 369#ifdef HAVE_ALBUMART
328 case WPS_TOKEN_ALBUMART_FOUND: 370 case WPS_TOKEN_ALBUMART_FOUND:
@@ -340,7 +382,7 @@ const char *get_token_value(struct gui_wps *gwps,
340#endif 382#endif
341 383
342 case WPS_TOKEN_FILE_BITRATE: 384 case WPS_TOKEN_FILE_BITRATE:
343 if(id3->bitrate) 385 if(id3 && id3->bitrate)
344 snprintf(buf, buf_size, "%d", id3->bitrate); 386 snprintf(buf, buf_size, "%d", id3->bitrate);
345 else 387 else
346 return "?"; 388 return "?";
@@ -349,7 +391,9 @@ const char *get_token_value(struct gui_wps *gwps,
349 case WPS_TOKEN_FILE_CODEC: 391 case WPS_TOKEN_FILE_CODEC:
350 if (intval) 392 if (intval)
351 { 393 {
352 if(id3->codectype == AFMT_UNKNOWN) 394 if (UNLIKELY(!id3))
395 *intval = 0;
396 else if(id3->codectype == AFMT_UNKNOWN)
353 *intval = AFMT_NUM_CODECS; 397 *intval = AFMT_NUM_CODECS;
354 else 398 else
355 *intval = id3->codectype; 399 *intval = id3->codectype;
@@ -357,10 +401,12 @@ const char *get_token_value(struct gui_wps *gwps,
357 return get_codectype(id3); 401 return get_codectype(id3);
358 402
359 case WPS_TOKEN_FILE_FREQUENCY: 403 case WPS_TOKEN_FILE_FREQUENCY:
404 HANDLE_NULL_ID3_NUM_ZERO;
360 snprintf(buf, buf_size, "%ld", id3->frequency); 405 snprintf(buf, buf_size, "%ld", id3->frequency);
361 return buf; 406 return buf;
362 407
363 case WPS_TOKEN_FILE_FREQUENCY_KHZ: 408 case WPS_TOKEN_FILE_FREQUENCY_KHZ:
409 HANDLE_NULL_ID3_NUM_ZERO;
364 /* ignore remainders < 100, so 22050 Hz becomes just 22k */ 410 /* ignore remainders < 100, so 22050 Hz becomes just 22k */
365 if ((id3->frequency % 1000) < 100) 411 if ((id3->frequency % 1000) < 100)
366 snprintf(buf, buf_size, "%ld", id3->frequency / 1000); 412 snprintf(buf, buf_size, "%ld", id3->frequency / 1000);
@@ -371,6 +417,7 @@ const char *get_token_value(struct gui_wps *gwps,
371 return buf; 417 return buf;
372 418
373 case WPS_TOKEN_FILE_NAME: 419 case WPS_TOKEN_FILE_NAME:
420 if (!id3) return na_str;
374 if (get_dir(buf, buf_size, id3->path, 0)) { 421 if (get_dir(buf, buf_size, id3->path, 0)) {
375 /* Remove extension */ 422 /* Remove extension */
376 char* sep = strrchr(buf, '.'); 423 char* sep = strrchr(buf, '.');
@@ -384,20 +431,24 @@ const char *get_token_value(struct gui_wps *gwps,
384 } 431 }
385 432
386 case WPS_TOKEN_FILE_NAME_WITH_EXTENSION: 433 case WPS_TOKEN_FILE_NAME_WITH_EXTENSION:
434 if (!id3) return na_str;
387 return get_dir(buf, buf_size, id3->path, 0); 435 return get_dir(buf, buf_size, id3->path, 0);
388 436
389 case WPS_TOKEN_FILE_PATH: 437 case WPS_TOKEN_FILE_PATH:
390 return id3->path; 438 return HANDLE_NULL_ID3(id3->path);
391 439
392 case WPS_TOKEN_FILE_SIZE: 440 case WPS_TOKEN_FILE_SIZE:
441 HANDLE_NULL_ID3_NUM_ZERO;
393 snprintf(buf, buf_size, "%ld", id3->filesize / 1024); 442 snprintf(buf, buf_size, "%ld", id3->filesize / 1024);
394 return buf; 443 return buf;
395 444
396 case WPS_TOKEN_FILE_VBR: 445 case WPS_TOKEN_FILE_VBR:
397 return id3->vbr ? "(avg)" : NULL; 446 return (LIKELY(id3) && id3->vbr) ? "(avg)" : NULL;
398 447
399 case WPS_TOKEN_FILE_DIRECTORY: 448 case WPS_TOKEN_FILE_DIRECTORY:
400 return get_dir(buf, buf_size, id3->path, token->value.i); 449 if (LIKELY(id3))
450 return get_dir(buf, buf_size, id3->path, token->value.i);
451 return na_str;
401 452
402 case WPS_TOKEN_BATTERY_PERCENT: 453 case WPS_TOKEN_BATTERY_PERCENT:
403 { 454 {
@@ -664,27 +715,16 @@ const char *get_token_value(struct gui_wps *gwps,
664 return buf; 715 return buf;
665#endif 716#endif
666 717
718
667#ifdef HAVE_TAGCACHE 719#ifdef HAVE_TAGCACHE
668 case WPS_TOKEN_DATABASE_PLAYCOUNT: 720 case WPS_TOKEN_DATABASE_PLAYCOUNT:
669 if (intval) { 721 HANDLE_NULL_ID3_NUM_INTVAL(id3->playcount);
670 *intval = id3->playcount + 1;
671 }
672 snprintf(buf, buf_size, "%ld", id3->playcount);
673 return buf;
674 722
675 case WPS_TOKEN_DATABASE_RATING: 723 case WPS_TOKEN_DATABASE_RATING:
676 if (intval) { 724 HANDLE_NULL_ID3_NUM_INTVAL(id3->rating);
677 *intval = id3->rating + 1;
678 }
679 snprintf(buf, buf_size, "%d", id3->rating);
680 return buf;
681 725
682 case WPS_TOKEN_DATABASE_AUTOSCORE: 726 case WPS_TOKEN_DATABASE_AUTOSCORE:
683 if (intval) 727 HANDLE_NULL_ID3_NUM_INTVAL(id3->score);
684 *intval = id3->score + 1;
685
686 snprintf(buf, buf_size, "%d", id3->score);
687 return buf;
688#endif 728#endif
689 729
690#if (CONFIG_CODEC == SWCODEC) 730#if (CONFIG_CODEC == SWCODEC)
@@ -702,9 +742,13 @@ const char *get_token_value(struct gui_wps *gwps,
702 val = 1; /* off */ 742 val = 1; /* off */
703 else 743 else
704 { 744 {
705 int type = 745 int type;
706 get_replaygain_mode(id3->track_gain_string != NULL, 746 if (LIKELY(id3))
747 type = get_replaygain_mode(id3->track_gain_string != NULL,
707 id3->album_gain_string != NULL); 748 id3->album_gain_string != NULL);
749 else
750 type = -1;
751
708 if (type < 0) 752 if (type < 0)
709 val = 6; /* no tag */ 753 val = 6; /* no tag */
710 else 754 else
@@ -723,6 +767,7 @@ const char *get_token_value(struct gui_wps *gwps,
723 case 6: 767 case 6:
724 return "+0.00 dB"; 768 return "+0.00 dB";
725 break; 769 break;
770 /* due to above, coming here with !id3 shouldn't be possible */
726 case 2: 771 case 2:
727 case 4: 772 case 4:
728 strlcpy(buf, id3->track_gain_string, buf_size); 773 strlcpy(buf, id3->track_gain_string, buf_size);