summaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
authorThomas Martitz <kugel@rockbox.org>2009-10-16 19:14:37 +0000
committerThomas Martitz <kugel@rockbox.org>2009-10-16 19:14:37 +0000
commita72ffe7bb533302dbf4e6c7c4f1e4bd4078d3ed6 (patch)
treef15618b2c0e00cbb25d4e3ab900db3c799768bc6 /apps
parent9072a4558cb1db2b82ca3b001f6b95b5afda16c8 (diff)
downloadrockbox-a72ffe7bb533302dbf4e6c7c4f1e4bd4078d3ed6.tar.gz
rockbox-a72ffe7bb533302dbf4e6c7c4f1e4bd4078d3ed6.tar.bz2
rockbox-a72ffe7bb533302dbf4e6c7c4f1e4bd4078d3ed6.zip
Make the skin engine behave sane if the skin's id3 pointer is NULL (the one in struct wps_state), so that skins don't need audio to be played before being displayed (needed for upcoming custom statusbar).
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@23208 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps')
-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,
struct screen *display = gwps->display;
struct wps_state *state = gwps->state;
struct progressbar *pb = wps_vp->pb;
+ struct mp3entry *id3 = state->id3;
int y = pb->y;
if (y < 0)
@@ -156,27 +157,37 @@ static void draw_progressbar(struct gui_wps *gwps,
y = (-y -1)*line_height + (0 > center ? 0 : center);
}
+ int elapsed, length;
+ if (id3)
+ {
+ elapsed = id3->elapsed;
+ length = id3->length;
+ }
+ else
+ {
+ elapsed = 0;
+ length = 0;
+ }
+
if (pb->have_bitmap_pb)
gui_bitmap_scrollbar_draw(display, pb->bm,
- pb->x, y, pb->width, pb->bm.height,
- state->id3->length ? state->id3->length : 1, 0,
- state->id3->length ? state->id3->elapsed
- + state->ff_rewind_count : 0,
- HORIZONTAL);
+ pb->x, y, pb->width, pb->bm.height,
+ length ? length : 1, 0,
+ length ? elapsed + state->ff_rewind_count : 0,
+ HORIZONTAL);
else
gui_scrollbar_draw(display, pb->x, y, pb->width, pb->height,
- state->id3->length ? state->id3->length : 1, 0,
- state->id3->length ? state->id3->elapsed
- + state->ff_rewind_count : 0,
- HORIZONTAL);
+ length ? length : 1, 0,
+ length ? elapsed + state->ff_rewind_count : 0,
+ HORIZONTAL);
#ifdef AB_REPEAT_ENABLE
- if ( ab_repeat_mode_enabled() && state->id3->length != 0 )
- ab_draw_markers(display, state->id3->length,
+ if ( ab_repeat_mode_enabled() && length != 0 )
+ ab_draw_markers(display, length,
pb->x, pb->x + pb->width, y, pb->height);
#endif
- if (state->id3->cuesheet)
- cue_draw_markers(display, state->id3->cuesheet, state->id3->length,
+ if (id3 && id3->cuesheet)
+ cue_draw_markers(display, state->id3->cuesheet, length,
pb->x, pb->x + pb->width, y+1, pb->height-2);
}
@@ -266,12 +277,20 @@ static bool draw_player_progress(struct gui_wps *gwps)
int pos = 0;
int i;
- if (!state->id3)
- return false;
+ int elapsed, length;
+ if (LIKELY(state->id3))
+ {
+ elapsed = state->id3->elapsed;
+ length = state->id3->length;
+ }
+ else
+ {
+ elapsed = 0;
+ length = 0;
+ }
- if (state->id3->length)
- pos = 36 * (state->id3->elapsed + state->ff_rewind_count)
- / state->id3->length;
+ if (length)
+ pos = 36 * (elapsed + state->ff_rewind_count) / length;
for (i = 0; i < 7; i++, pos -= 5)
{
@@ -314,12 +333,24 @@ static void draw_player_fullbar(struct gui_wps *gwps, char* buf, int buf_size)
int digit, i, j;
bool softchar;
- if (!state->id3 || buf_size < 34) /* worst case: 11x UTF-8 char + \0 */
+ int elapsed, length;
+ if (LIKELY(state->id3))
+ {
+ elapsed = id3->elapsed;
+ length = id3->length;
+ }
+ else
+ {
+ elapsed = 0;
+ length = 0;
+ }
+
+ if (buf_size < 34) /* worst case: 11x UTF-8 char + \0 */
return;
- time = state->id3->elapsed + state->ff_rewind_count;
- if (state->id3->length)
- pos = 55 * time / state->id3->length;
+ time = elapsed + state->ff_rewind_count;
+ if (length)
+ pos = 55 * time / length;
memset(timestr, 0, sizeof(timestr));
format_time(timestr, sizeof(timestr)-2, time);
@@ -879,14 +910,8 @@ static bool skin_redraw(struct gui_wps *gwps, unsigned refresh_mode)
{
struct wps_data *data = gwps->data;
struct screen *display = gwps->display;
- struct wps_state *state = gwps->state;
-
- if (!data || !state || !display)
- return false;
-
- struct mp3entry *id3 = state->id3;
- if (!id3)
+ if (!data || !display || !gwps->state)
return false;
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 @@
static char* get_codectype(const struct mp3entry* id3)
{
- if (id3->codectype < AFMT_NUM_CODECS) {
+ if (id3 && id3->codectype < AFMT_NUM_CODECS) {
return (char*)audio_formats[id3->codectype].label;
} else {
return NULL;
@@ -119,6 +119,27 @@ static char* get_dir(char* buf, int buf_size, const char* path, int level)
and the original value of *intval, inclusive).
When not treating a conditional/enum, intval should be NULL.
*/
+
+/* a few convinience macros for the id3 == NULL case
+ * depends on a few variable names in get_token_value() */
+
+#define HANDLE_NULL_ID3(id3field) (LIKELY(id3) ? (id3field) : na_str)
+
+#define HANDLE_NULL_ID3_NUM_ZERO { if (UNLIKELY(!id3)) return zero_str; }
+
+#define HANDLE_NULL_ID3_NUM_INTVAL(id3field) \
+ do { \
+ if (intval) { \
+ *intval = (LIKELY(id3) ? (id3field) + 1 : 0); \
+ } \
+ if (LIKELY(id3)) \
+ { \
+ snprintf(buf, buf_size, "%ld", (id3field)); \
+ return buf; \
+ } \
+ return zero_str; \
+ } while (0)
+
const char *get_token_value(struct gui_wps *gwps,
struct wps_token *token,
char *buf, int buf_size,
@@ -129,6 +150,9 @@ const char *get_token_value(struct gui_wps *gwps,
struct wps_data *data = gwps->data;
struct wps_state *state = gwps->state;
+ int elapsed, length;
+ static const char * const na_str = "n/a";
+ static const char * const zero_str = "0";
if (!data || !state)
return NULL;
@@ -140,8 +164,16 @@ const char *get_token_value(struct gui_wps *gwps,
else
id3 = state->id3;
- if (!id3)
- return NULL;
+ if (id3)
+ {
+ elapsed = id3->elapsed;
+ length = id3->length;
+ }
+ else
+ {
+ elapsed = 0;
+ length = 0;
+ }
#if CONFIG_RTC
struct tm* tm = NULL;
@@ -180,17 +212,17 @@ const char *get_token_value(struct gui_wps *gwps,
case WPS_TOKEN_TRACK_TIME_ELAPSED:
format_time(buf, buf_size,
- id3->elapsed + state->ff_rewind_count);
+ elapsed + state->ff_rewind_count);
return buf;
case WPS_TOKEN_TRACK_TIME_REMAINING:
format_time(buf, buf_size,
- id3->length - id3->elapsed -
+ length - elapsed -
state->ff_rewind_count);
return buf;
case WPS_TOKEN_TRACK_LENGTH:
- format_time(buf, buf_size, id3->length);
+ format_time(buf, buf_size, length);
return buf;
case WPS_TOKEN_PLAYLIST_ENTRIES:
@@ -237,92 +269,102 @@ const char *get_token_value(struct gui_wps *gwps,
return buf;
case WPS_TOKEN_TRACK_ELAPSED_PERCENT:
- if (id3->length <= 0)
+ if (length <= 0)
return NULL;
if (intval)
{
- *intval = limit * (id3->elapsed + state->ff_rewind_count)
- / id3->length + 1;
+ *intval = limit * (elapsed + state->ff_rewind_count)
+ / length + 1;
}
snprintf(buf, buf_size, "%d",
- 100*(id3->elapsed + state->ff_rewind_count) / id3->length);
+ 100*(elapsed + state->ff_rewind_count) / length);
return buf;
case WPS_TOKEN_METADATA_ARTIST:
- return id3->artist;
+ return HANDLE_NULL_ID3(id3->artist);
case WPS_TOKEN_METADATA_COMPOSER:
- return id3->composer;
+ return HANDLE_NULL_ID3(id3->composer);
case WPS_TOKEN_METADATA_ALBUM:
- return id3->album;
+ return HANDLE_NULL_ID3(id3->album);
case WPS_TOKEN_METADATA_ALBUM_ARTIST:
- return id3->albumartist;
+ return HANDLE_NULL_ID3(id3->albumartist);
case WPS_TOKEN_METADATA_GROUPING:
- return id3->grouping;
+ return HANDLE_NULL_ID3(id3->grouping);
case WPS_TOKEN_METADATA_GENRE:
- return id3->genre_string;
+ return HANDLE_NULL_ID3(id3->genre_string);
case WPS_TOKEN_METADATA_DISC_NUMBER:
- if (id3->disc_string)
- return id3->disc_string;
- if (id3->discnum) {
- snprintf(buf, buf_size, "%d", id3->discnum);
- return buf;
+ if (LIKELY(id3)) {
+ if (id3->disc_string)
+ return id3->disc_string;
+ if (id3->discnum) {
+ snprintf(buf, buf_size, "%d", id3->discnum);
+ return buf;
+ }
}
return NULL;
case WPS_TOKEN_METADATA_TRACK_NUMBER:
- if (id3->track_string)
- return id3->track_string;
+ if (LIKELY(id3)) {
+ if (id3->track_string)
+ return id3->track_string;
- if (id3->tracknum) {
- snprintf(buf, buf_size, "%d", id3->tracknum);
- return buf;
+ if (id3->tracknum) {
+ snprintf(buf, buf_size, "%d", id3->tracknum);
+ return buf;
+ }
}
return NULL;
case WPS_TOKEN_METADATA_TRACK_TITLE:
- return id3->title;
+ return HANDLE_NULL_ID3(id3->title);
case WPS_TOKEN_METADATA_VERSION:
- switch (id3->id3version)
+ if (LIKELY(id3))
{
- case ID3_VER_1_0:
- return "1";
+ switch (id3->id3version)
+ {
+ case ID3_VER_1_0:
+ return "1";
- case ID3_VER_1_1:
- return "1.1";
+ case ID3_VER_1_1:
+ return "1.1";
- case ID3_VER_2_2:
- return "2.2";
+ case ID3_VER_2_2:
+ return "2.2";
- case ID3_VER_2_3:
- return "2.3";
+ case ID3_VER_2_3:
+ return "2.3";
- case ID3_VER_2_4:
- return "2.4";
+ case ID3_VER_2_4:
+ return "2.4";
- default:
- return NULL;
+ default:
+ break;
+ }
}
+ return NULL;
case WPS_TOKEN_METADATA_YEAR:
- if( id3->year_string )
- return id3->year_string;
+ if (LIKELY(id3)) {
+ if( id3->year_string )
+ return id3->year_string;
- if (id3->year) {
- snprintf(buf, buf_size, "%d", id3->year);
- return buf;
+ if (id3->year) {
+ snprintf(buf, buf_size, "%d", id3->year);
+ return buf;
+ }
}
return NULL;
case WPS_TOKEN_METADATA_COMMENT:
- return id3->comment;
+ return HANDLE_NULL_ID3(id3->comment);
#ifdef HAVE_ALBUMART
case WPS_TOKEN_ALBUMART_FOUND:
@@ -340,7 +382,7 @@ const char *get_token_value(struct gui_wps *gwps,
#endif
case WPS_TOKEN_FILE_BITRATE:
- if(id3->bitrate)
+ if(id3 && id3->bitrate)
snprintf(buf, buf_size, "%d", id3->bitrate);
else
return "?";
@@ -349,7 +391,9 @@ const char *get_token_value(struct gui_wps *gwps,
case WPS_TOKEN_FILE_CODEC:
if (intval)
{
- if(id3->codectype == AFMT_UNKNOWN)
+ if (UNLIKELY(!id3))
+ *intval = 0;
+ else if(id3->codectype == AFMT_UNKNOWN)
*intval = AFMT_NUM_CODECS;
else
*intval = id3->codectype;
@@ -357,10 +401,12 @@ const char *get_token_value(struct gui_wps *gwps,
return get_codectype(id3);
case WPS_TOKEN_FILE_FREQUENCY:
+ HANDLE_NULL_ID3_NUM_ZERO;
snprintf(buf, buf_size, "%ld", id3->frequency);
return buf;
case WPS_TOKEN_FILE_FREQUENCY_KHZ:
+ HANDLE_NULL_ID3_NUM_ZERO;
/* ignore remainders < 100, so 22050 Hz becomes just 22k */
if ((id3->frequency % 1000) < 100)
snprintf(buf, buf_size, "%ld", id3->frequency / 1000);
@@ -371,6 +417,7 @@ const char *get_token_value(struct gui_wps *gwps,
return buf;
case WPS_TOKEN_FILE_NAME:
+ if (!id3) return na_str;
if (get_dir(buf, buf_size, id3->path, 0)) {
/* Remove extension */
char* sep = strrchr(buf, '.');
@@ -384,20 +431,24 @@ const char *get_token_value(struct gui_wps *gwps,
}
case WPS_TOKEN_FILE_NAME_WITH_EXTENSION:
+ if (!id3) return na_str;
return get_dir(buf, buf_size, id3->path, 0);
case WPS_TOKEN_FILE_PATH:
- return id3->path;
+ return HANDLE_NULL_ID3(id3->path);
case WPS_TOKEN_FILE_SIZE:
+ HANDLE_NULL_ID3_NUM_ZERO;
snprintf(buf, buf_size, "%ld", id3->filesize / 1024);
return buf;
case WPS_TOKEN_FILE_VBR:
- return id3->vbr ? "(avg)" : NULL;
+ return (LIKELY(id3) && id3->vbr) ? "(avg)" : NULL;
case WPS_TOKEN_FILE_DIRECTORY:
- return get_dir(buf, buf_size, id3->path, token->value.i);
+ if (LIKELY(id3))
+ return get_dir(buf, buf_size, id3->path, token->value.i);
+ return na_str;
case WPS_TOKEN_BATTERY_PERCENT:
{
@@ -664,27 +715,16 @@ const char *get_token_value(struct gui_wps *gwps,
return buf;
#endif
+
#ifdef HAVE_TAGCACHE
case WPS_TOKEN_DATABASE_PLAYCOUNT:
- if (intval) {
- *intval = id3->playcount + 1;
- }
- snprintf(buf, buf_size, "%ld", id3->playcount);
- return buf;
+ HANDLE_NULL_ID3_NUM_INTVAL(id3->playcount);
case WPS_TOKEN_DATABASE_RATING:
- if (intval) {
- *intval = id3->rating + 1;
- }
- snprintf(buf, buf_size, "%d", id3->rating);
- return buf;
+ HANDLE_NULL_ID3_NUM_INTVAL(id3->rating);
case WPS_TOKEN_DATABASE_AUTOSCORE:
- if (intval)
- *intval = id3->score + 1;
-
- snprintf(buf, buf_size, "%d", id3->score);
- return buf;
+ HANDLE_NULL_ID3_NUM_INTVAL(id3->score);
#endif
#if (CONFIG_CODEC == SWCODEC)
@@ -702,9 +742,13 @@ const char *get_token_value(struct gui_wps *gwps,
val = 1; /* off */
else
{
- int type =
- get_replaygain_mode(id3->track_gain_string != NULL,
+ int type;
+ if (LIKELY(id3))
+ type = get_replaygain_mode(id3->track_gain_string != NULL,
id3->album_gain_string != NULL);
+ else
+ type = -1;
+
if (type < 0)
val = 6; /* no tag */
else
@@ -723,6 +767,7 @@ const char *get_token_value(struct gui_wps *gwps,
case 6:
return "+0.00 dB";
break;
+ /* due to above, coming here with !id3 shouldn't be possible */
case 2:
case 4:
strlcpy(buf, id3->track_gain_string, buf_size);