mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-11-17 09:02:38 -05:00
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
This commit is contained in:
parent
9072a4558c
commit
a72ffe7bb5
2 changed files with 167 additions and 97 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue