From 2d31d77a8ba231cb03ec35863c4c4ce2024f6509 Mon Sep 17 00:00:00 2001 From: Jonathan Gordon Date: Thu, 29 Jul 2010 12:37:48 +0000 Subject: FS#11470 - new skin code, finally svn uses the new parser from the theme editor. This means that a skin that passes the editor WILL pass svn and checkwps (unless the target runs out of skin buffer or something. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@27613 a1c6a512-1295-4272-9138-f99709370657 --- lib/skin_parser/SOURCES | 2 +- lib/skin_parser/skin_buffer.c | 38 +++-- lib/skin_parser/skin_buffer.h | 6 +- lib/skin_parser/skin_debug.c | 40 ++++++ lib/skin_parser/skin_debug.h | 9 +- lib/skin_parser/skin_parser.c | 169 ++++++++++++++++++++-- lib/skin_parser/skin_parser.h | 15 +- lib/skin_parser/skin_scan.c | 8 +- lib/skin_parser/skin_scan.h | 1 - lib/skin_parser/tag_table.c | 325 +++++++++++++++++++++--------------------- lib/skin_parser/tag_table.h | 21 ++- 11 files changed, 434 insertions(+), 200 deletions(-) (limited to 'lib') diff --git a/lib/skin_parser/SOURCES b/lib/skin_parser/SOURCES index 3024797255..37a6e9a03c 100644 --- a/lib/skin_parser/SOURCES +++ b/lib/skin_parser/SOURCES @@ -1,6 +1,6 @@ skin_buffer.c skin_parser.c -#ifndef ROCKBOX +#if !defined(ROCKBOX) || defined(__PCTOOL__) skin_debug.c #endif skin_scan.c diff --git a/lib/skin_parser/skin_buffer.c b/lib/skin_parser/skin_buffer.c index 05cdc0ce03..69d9d273bd 100644 --- a/lib/skin_parser/skin_buffer.c +++ b/lib/skin_parser/skin_buffer.c @@ -24,21 +24,19 @@ #include #include +#include "skin_buffer.h" + #ifdef ROCKBOX -#define SKIN_BUFFER_SIZE (400*1024) /* Excessivly large for now */ -static unsigned char buffer[SKIN_BUFFER_SIZE]; -static unsigned char *buffer_front = NULL; /* start of the free space, - increases with allocation*/ +static size_t buf_size; +static unsigned char *buffer_start = NULL; +static unsigned char *buffer_front = NULL; #endif -void skin_buffer_init(void) +void skin_buffer_init(char* buffer, size_t size) { #if defined(ROCKBOX) - { - /* reset the buffer.... */ - buffer_front = buffer; - //TODO: buf_size = size; - } + buffer_start = buffer_front = buffer; + buf_size = size; #endif } @@ -46,7 +44,9 @@ void skin_buffer_init(void) void* skin_buffer_alloc(size_t size) { void *retval = NULL; -#ifdef ROCKBOX +#ifdef ROCKBOX + if (size > skin_buffer_freespace()) + return NULL; retval = buffer_front; buffer_front += size; /* 32-bit aligned */ @@ -62,10 +62,22 @@ void* skin_buffer_alloc(size_t size) /* get the number of bytes currently being used */ size_t skin_buffer_usage(void) { - return buffer_front - buffer; + return buffer_front - buffer_start; } size_t skin_buffer_freespace(void) { - return SKIN_BUFFER_SIZE - skin_buffer_usage(); + return buf_size - skin_buffer_usage(); +} + +static unsigned char *saved_buffer_pos = NULL; +void skin_buffer_save_position(void) +{ + saved_buffer_pos = buffer_front; +} + +void skin_buffer_restore_position(void) +{ + if (saved_buffer_pos) + buffer_front = saved_buffer_pos; } #endif diff --git a/lib/skin_parser/skin_buffer.h b/lib/skin_parser/skin_buffer.h index ff477da539..1698b8afb2 100644 --- a/lib/skin_parser/skin_buffer.h +++ b/lib/skin_parser/skin_buffer.h @@ -25,11 +25,15 @@ #include #ifndef _SKIN_BUFFFER_H_ #define _SKIN_BUFFFER_H_ -void skin_buffer_init(size_t size); +void skin_buffer_init(char* buffer, size_t size); /* Allocate size bytes from the buffer */ void* skin_buffer_alloc(size_t size); /* get the number of bytes currently being used */ size_t skin_buffer_usage(void); size_t skin_buffer_freespace(void); + +/* save and restore a buffer position incase a skin fails to load */ +void skin_buffer_save_position(void); +void skin_buffer_restore_position(void); #endif diff --git a/lib/skin_parser/skin_debug.c b/lib/skin_parser/skin_debug.c index c03b32e910..88ad209cce 100644 --- a/lib/skin_parser/skin_debug.c +++ b/lib/skin_parser/skin_debug.c @@ -35,6 +35,7 @@ extern char* skin_start; /* Global error variables */ int error_line; int error_col; +char *error_line_start; char* error_message; /* Debugging functions */ @@ -48,6 +49,7 @@ void skin_error(enum skin_errorcode error, char* cursor) cursor--; error_col++; } + error_line_start = cursor+1; error_line = skin_line; @@ -285,4 +287,42 @@ void skin_debug_indent() for(i = 0; i < debug_indent_level; i++) printf(" "); } + #endif + +#define MIN(a,b) ((a...<10 chars>" */ + strncpy(text, error_line_start, 6); + i = 5; + text[i++] = '.'; + text[i++] = '.'; + text[i++] = '.'; + for (j=error_col-10; error_line_start[j] && error_line_start[j] != '\n'; j++) + text[i++] = error_line_start[j]; + text[i] = '\0'; + error_col = 18; + } + printf("%s\n", text); + for (i=0; i #include +#include #include #include #include @@ -37,6 +38,11 @@ int skin_line = 0; char* skin_start = 0; int viewport_line = 0; +#ifdef ROCKBOX +static skin_callback callback = NULL; +static void* callback_data; +#endif + /* Auxiliary parsing functions (not visible at global scope) */ static struct skin_element* skin_parse_viewport(char** document); static struct skin_element* skin_parse_line(char** document); @@ -55,10 +61,23 @@ static int skin_parse_comment(struct skin_element* element, char** document); static struct skin_element* skin_parse_code_as_arg(char** document); +static void skip_whitespace(char** document) +{ + while(**document == ' ' || **document == '\t') + (*document)++; +} +#ifdef ROCKBOX +struct skin_element* skin_parse(const char* document, + skin_callback cb, void* cb_data) + +{ + callback = cb; + callback_data = cb_data; +#else struct skin_element* skin_parse(const char* document) { - +#endif struct skin_element* root = NULL; struct skin_element* last = NULL; @@ -94,7 +113,6 @@ struct skin_element* skin_parse(const char* document) last = last->next; } - return root; } @@ -107,6 +125,8 @@ static struct skin_element* skin_parse_viewport(char** document) struct skin_element* retval = NULL; retval = skin_alloc_element(); + if (!retval) + return NULL; retval->type = VIEWPORT; retval->children_count = 1; retval->line = skin_line; @@ -129,11 +149,18 @@ static struct skin_element* skin_parse_viewport(char** document) skin_line++; } } +#ifdef ROCKBOX + else if (callback) + { + if (callback(retval, callback_data) == CALLBACK_ERROR) + return NULL; + } +#endif retval->children_count = 1; retval->children = skin_alloc_children(1); - - + if (!retval->children) + return NULL; do { @@ -199,7 +226,6 @@ static struct skin_element* skin_parse_viewport(char** document) return NULL; } - /* Making sure last is at the end */ while(last->next) last = last->next; @@ -245,6 +271,8 @@ static struct skin_element* skin_parse_line_optional(char** document, /* A wrapper for the line */ retval = skin_alloc_element(); + if (!retval) + return NULL; retval->type = LINE; retval->line = skin_line; if(*cursor != '\0' && *cursor != '\n' && *cursor != MULTILINESYM @@ -261,7 +289,24 @@ static struct skin_element* skin_parse_line_optional(char** document, } if(retval->children_count > 0) + { retval->children = skin_alloc_children(1); + if (!retval->children) + return NULL; + } + +#ifdef ROCKBOX + if (callback) + { + switch (callback(retval, callback_data)) + { + case CALLBACK_ERROR: + return NULL; + default: + break; + } + } +#endif while(*cursor != '\n' && *cursor != '\0' && *cursor != MULTILINESYM && !((*cursor == ARGLISTSEPERATESYM @@ -275,11 +320,15 @@ static struct skin_element* skin_parse_line_optional(char** document, if(root) { current->next = skin_alloc_element(); + if (!current->next) + return NULL; current = current->next; } else { current = skin_alloc_element(); + if (!current) + return NULL; root = current; } @@ -306,9 +355,10 @@ static struct skin_element* skin_parse_line_optional(char** document, } } + /* Moving up the calling function's pointer */ *document = cursor; - + if(root) retval->children[0] = root; return retval; @@ -328,6 +378,8 @@ static struct skin_element* skin_parse_sublines_optional(char** document, int i; retval = skin_alloc_element(); + if (!retval) + return NULL; retval->type = LINE_ALTERNATOR; retval->next = NULL; retval->line = skin_line; @@ -374,6 +426,8 @@ static struct skin_element* skin_parse_sublines_optional(char** document, /* ...and then we parse them */ retval->children_count = sublines; retval->children = skin_alloc_children(sublines); + if (!retval->children) + return NULL; cursor = *document; for(i = 0; i < sublines; i++) @@ -392,6 +446,13 @@ static struct skin_element* skin_parse_sublines_optional(char** document, } } +#ifdef ROCKBOX + if (callback) + { + if (callback(retval, callback_data) == CALLBACK_ERROR) + return NULL; + } +#endif *document = cursor; return retval; @@ -458,6 +519,14 @@ static int skin_parse_tag(struct skin_element* element, char** document) || (tag_args[0] == '|' && *cursor != ARGLISTOPENSYM) || (star && *cursor != ARGLISTOPENSYM)) { + +#ifdef ROCKBOX + if (callback) + { + if (callback(element, callback_data) == CALLBACK_ERROR) + return 0; + } +#endif *document = cursor; return 1; } @@ -507,6 +576,8 @@ static int skin_parse_tag(struct skin_element* element, char** document) cursor = bookmark; /* Restoring the cursor */ element->params_count = num_args; element->params = skin_alloc_params(num_args); + if (!element->params) + return 0; /* Now we have to actually parse each argument */ for(i = 0; i < num_args; i++) @@ -587,7 +658,6 @@ static int skin_parse_tag(struct skin_element* element, char** document) } if (have_tenth == false) val *= 10; - element->params[i].type = DECIMAL; element->params[i].data.number = val; } @@ -644,7 +714,13 @@ static int skin_parse_tag(struct skin_element* element, char** document) skin_error(INSUFFICIENT_ARGS, cursor); return 0; } - +#ifdef ROCKBOX + if (callback) + { + if (callback(element, callback_data) == CALLBACK_ERROR) + return 0; + } +#endif *document = cursor; return 1; @@ -691,6 +767,8 @@ static int skin_parse_text(struct skin_element* element, char** document, element->line = skin_line; element->next = NULL; element->data = text = skin_alloc_string(length); + if (!element->data) + return 0; for(dest = 0; dest < length; dest++) { @@ -702,6 +780,14 @@ static int skin_parse_text(struct skin_element* element, char** document, cursor++; } text[length] = '\0'; + +#ifdef ROCKBOX + if (callback) + { + if (callback(element, callback_data) == CALLBACK_ERROR) + return 0; + } +#endif *document = cursor; @@ -715,14 +801,40 @@ static int skin_parse_conditional(struct skin_element* element, char** document) char* bookmark; int children = 1; int i; + +#ifdef ROCKBOX + bool feature_available = true; + char *false_branch = NULL; +#endif - element->type = CONDITIONAL; + /* Some conditional tags allow for target feature checking, + * so to handle that call the callback as usual with type == TAG + * then call it a second time with type == CONDITIONAL and check the return + * value */ + element->type = TAG; element->line = skin_line; /* Parsing the tag first */ if(!skin_parse_tag(element, &cursor)) return 0; + element->type = CONDITIONAL; +#ifdef ROCKBOX + if (callback) + { + switch (callback(element, callback_data)) + { + case FEATURE_NOT_AVAILABLE: + feature_available = false; + break; + case CALLBACK_ERROR: + return 0; + default: + break; + } + } +#endif + /* Counting the children */ if(*(cursor++) != ENUMLISTOPENSYM) { @@ -751,16 +863,35 @@ static int skin_parse_conditional(struct skin_element* element, char** document) { children++; cursor++; +#ifdef ROCKBOX + if (false_branch == NULL && !feature_available) + { + false_branch = cursor; + children--; + } +#endif } else { cursor++; } } +#ifdef ROCKBOX + if (*cursor == ENUMLISTCLOSESYM && + false_branch == NULL && !feature_available) + { + false_branch = cursor+1; + children--; + } + /* if we are skipping the true branch fix that up */ + cursor = false_branch ? false_branch : bookmark; +#else cursor = bookmark; - +#endif /* Parsing the children */ element->children = skin_alloc_children(children); + if (!element->children) + return 0; element->children_count = children; for(i = 0; i < children; i++) @@ -809,6 +940,8 @@ static int skin_parse_comment(struct skin_element* element, char** document) element->data = NULL; #else element->data = text = skin_alloc_string(length); + if (!element->data) + return 0; /* We copy from one char past cursor to leave out the # */ memcpy((void*)text, (void*)(cursor + 1), sizeof(char) * (length-1)); @@ -877,6 +1010,8 @@ struct skin_element* skin_alloc_element() { struct skin_element* retval = (struct skin_element*) skin_buffer_alloc(sizeof(struct skin_element)); + if (!retval) + return NULL; retval->type = UNKNOWN; retval->next = NULL; retval->tag = NULL; @@ -886,9 +1021,21 @@ struct skin_element* skin_alloc_element() return retval; } - +/* On a ROCKBOX build we try to save space as much as possible + * so if we can, use a shared param pool which should be more then large + * enough for any tag. params should be used straight away by the callback + * so this is safe. + */ struct skin_tag_parameter* skin_alloc_params(int count) { +#ifdef ROCKBOX + static struct skin_tag_parameter params[MAX_TAG_PARAMS]; + if (count <= MAX_TAG_PARAMS) + { + memset(params, 0, sizeof(params)); + return params; + } +#endif size_t size = sizeof(struct skin_tag_parameter) * count; return (struct skin_tag_parameter*)skin_buffer_alloc(size); diff --git a/lib/skin_parser/skin_parser.h b/lib/skin_parser/skin_parser.h index ad10f90125..8514dfdd0e 100644 --- a/lib/skin_parser/skin_parser.h +++ b/lib/skin_parser/skin_parser.h @@ -115,14 +115,27 @@ struct skin_element struct skin_element* next; }; +enum skin_cb_returnvalue +{ + CALLBACK_ERROR = -666, + FEATURE_NOT_AVAILABLE, + CALLBACK_OK = 0, + /* > 0 reserved for future use */ +}; +typedef int (*skin_callback)(struct skin_element* element, void* data); + /*********************************************************************** ***** Functions ******************************************************* **********************************************************************/ /* Parses a WPS document and returns a list of skin_element structures. */ +#ifdef ROCKBOX +struct skin_element* skin_parse(const char* document, + skin_callback callback, void* callback_data); +#else struct skin_element* skin_parse(const char* document); - +#endif /* Memory management functions */ struct skin_element* skin_alloc_element(void); struct skin_element** skin_alloc_children(int count); diff --git a/lib/skin_parser/skin_scan.c b/lib/skin_parser/skin_scan.c index 6b5c189b9f..d18f2224b3 100644 --- a/lib/skin_parser/skin_scan.c +++ b/lib/skin_parser/skin_scan.c @@ -40,12 +40,6 @@ void skip_comment(char** document) (*document)++; } -void skip_whitespace(char** document) -{ - while(**document == ' ' || **document == '\t') - (*document)++; -} - void skip_arglist(char** document) { if(**document == ARGLISTOPENSYM) @@ -132,6 +126,8 @@ char* scan_string(char** document) /* Copying the string */ cursor = *document; buffer = skin_alloc_string(length); + if (!buffer) + return NULL; buffer[length] = '\0'; for(i = 0; i < length; i++) { diff --git a/lib/skin_parser/skin_scan.h b/lib/skin_parser/skin_scan.h index b1d04a6e34..72d4475767 100644 --- a/lib/skin_parser/skin_scan.h +++ b/lib/skin_parser/skin_scan.h @@ -30,7 +30,6 @@ extern "C" /* Scanning functions */ void skip_comment(char** document); -void skip_whitespace(char** document); void skip_arglist(char** document); void skip_enumlist(char** document); char* scan_string(char** document); diff --git a/lib/skin_parser/tag_table.c b/lib/skin_parser/tag_table.c index dd8df63997..a7e3378d24 100644 --- a/lib/skin_parser/tag_table.c +++ b/lib/skin_parser/tag_table.c @@ -33,182 +33,181 @@ struct tag_info legal_tags[] = { SKIN_TOKEN_ALIGN_RIGHT_RTL, "aR", "", 0 }, { SKIN_TOKEN_ALIGN_LANGDIRECTION, "ax", "", 0 }, - { SKIN_TOKEN_BATTERY_PERCENT, "bl" , BAR_PARAMS, 0 }, - { SKIN_TOKEN_BATTERY_VOLTS, "bv", "", 0 }, - { SKIN_TOKEN_BATTERY_TIME, "bt", "", 0 }, - { SKIN_TOKEN_BATTERY_SLEEPTIME, "bs", "", 0 }, - { SKIN_TOKEN_BATTERY_CHARGING, "bc", "", 0 }, - { SKIN_TOKEN_BATTERY_CHARGER_CONNECTED, "bp", "", 0 }, - { SKIN_TOKEN_USB_POWERED, "bu", "", 0 }, - - - { SKIN_TOKEN_RTC_PRESENT, "cc", "", 0 }, - { SKIN_TOKEN_RTC_DAY_OF_MONTH, "cd", "", 0 }, - { SKIN_TOKEN_RTC_DAY_OF_MONTH_BLANK_PADDED, "ce", "", 0 }, - { SKIN_TOKEN_RTC_12HOUR_CFG, "cf", "", 0 }, - { SKIN_TOKEN_RTC_HOUR_24_ZERO_PADDED, "cH", "", 0 }, - { SKIN_TOKEN_RTC_HOUR_24, "ck", "", 0 }, - { SKIN_TOKEN_RTC_HOUR_12_ZERO_PADDED, "cI", "", 0 }, - { SKIN_TOKEN_RTC_HOUR_12, "cl", "", 0 }, - { SKIN_TOKEN_RTC_MONTH, "cm", "", 0 }, - { SKIN_TOKEN_RTC_MINUTE, "cM", "", 0 }, - { SKIN_TOKEN_RTC_SECOND, "cS", "", 0 }, - { SKIN_TOKEN_RTC_YEAR_2_DIGITS, "cy", "", 0 }, - { SKIN_TOKEN_RTC_YEAR_4_DIGITS, "cY", "", 0 }, - { SKIN_TOKEN_RTC_AM_PM_UPPER, "cP", "", 0 }, - { SKIN_TOKEN_RTC_AM_PM_LOWER, "cp", "", 0 }, - { SKIN_TOKEN_RTC_WEEKDAY_NAME, "ca", "", 0 }, - { SKIN_TOKEN_RTC_MONTH_NAME, "cb", "", 0 }, - { SKIN_TOKEN_RTC_DAY_OF_WEEK_START_MON, "cu", "", 0 }, - { SKIN_TOKEN_RTC_DAY_OF_WEEK_START_SUN, "cw", "", 0 }, + { SKIN_TOKEN_BATTERY_PERCENT, "bl" , BAR_PARAMS, SKIN_REFRESH_DYNAMIC }, + { SKIN_TOKEN_BATTERY_VOLTS, "bv", "", SKIN_REFRESH_DYNAMIC }, + { SKIN_TOKEN_BATTERY_TIME, "bt", "", SKIN_REFRESH_DYNAMIC }, + { SKIN_TOKEN_BATTERY_SLEEPTIME, "bs", "", SKIN_REFRESH_DYNAMIC }, + { SKIN_TOKEN_BATTERY_CHARGING, "bc", "", SKIN_REFRESH_DYNAMIC }, + { SKIN_TOKEN_BATTERY_CHARGER_CONNECTED, "bp", "", SKIN_REFRESH_DYNAMIC }, + { SKIN_TOKEN_USB_POWERED, "bu", "", SKIN_REFRESH_DYNAMIC }, + + + { SKIN_TOKEN_RTC_PRESENT, "cc", "", SKIN_REFRESH_STATIC }, + { SKIN_TOKEN_RTC_DAY_OF_MONTH, "cd", "", SKIN_RTC_REFRESH }, + { SKIN_TOKEN_RTC_DAY_OF_MONTH_BLANK_PADDED, "ce", "", SKIN_RTC_REFRESH }, + { SKIN_TOKEN_RTC_12HOUR_CFG, "cf", "", SKIN_RTC_REFRESH }, + { SKIN_TOKEN_RTC_HOUR_24_ZERO_PADDED, "cH", "", SKIN_RTC_REFRESH }, + { SKIN_TOKEN_RTC_HOUR_24, "ck", "", SKIN_RTC_REFRESH }, + { SKIN_TOKEN_RTC_HOUR_12_ZERO_PADDED, "cI", "", SKIN_RTC_REFRESH }, + { SKIN_TOKEN_RTC_HOUR_12, "cl", "", SKIN_RTC_REFRESH }, + { SKIN_TOKEN_RTC_MONTH, "cm", "", SKIN_RTC_REFRESH }, + { SKIN_TOKEN_RTC_MINUTE, "cM", "", SKIN_RTC_REFRESH }, + { SKIN_TOKEN_RTC_SECOND, "cS", "", SKIN_RTC_REFRESH }, + { SKIN_TOKEN_RTC_YEAR_2_DIGITS, "cy", "", SKIN_RTC_REFRESH }, + { SKIN_TOKEN_RTC_YEAR_4_DIGITS, "cY", "", SKIN_RTC_REFRESH }, + { SKIN_TOKEN_RTC_AM_PM_UPPER, "cP", "", SKIN_RTC_REFRESH }, + { SKIN_TOKEN_RTC_AM_PM_LOWER, "cp", "", SKIN_RTC_REFRESH }, + { SKIN_TOKEN_RTC_WEEKDAY_NAME, "ca", "", SKIN_RTC_REFRESH }, + { SKIN_TOKEN_RTC_MONTH_NAME, "cb", "", SKIN_RTC_REFRESH }, + { SKIN_TOKEN_RTC_DAY_OF_WEEK_START_MON, "cu", "", SKIN_RTC_REFRESH }, + { SKIN_TOKEN_RTC_DAY_OF_WEEK_START_SUN, "cw", "", SKIN_RTC_REFRESH }, - { SKIN_TOKEN_FILE_BITRATE, "fb", "", 0 }, - { SKIN_TOKEN_FILE_CODEC, "fc", "", 0 }, - { SKIN_TOKEN_FILE_FREQUENCY, "ff", "", 0 }, - { SKIN_TOKEN_FILE_FREQUENCY_KHZ, "fk", "", 0 }, - { SKIN_TOKEN_FILE_NAME_WITH_EXTENSION, "fm", "", 0 }, - { SKIN_TOKEN_FILE_NAME, "fn", "", 0 }, - { SKIN_TOKEN_FILE_PATH, "fp", "", 0 }, - { SKIN_TOKEN_FILE_SIZE, "fs", "", 0 }, - { SKIN_TOKEN_FILE_VBR, "fv", "", 0 }, - { SKIN_TOKEN_FILE_DIRECTORY, "d" , "I", 0 }, - - { SKIN_TOKEN_FILE_BITRATE, "Fb", "", 0 }, - { SKIN_TOKEN_FILE_CODEC, "Fc", "", 0 }, - { SKIN_TOKEN_FILE_FREQUENCY, "Ff", "", 0 }, - { SKIN_TOKEN_FILE_FREQUENCY_KHZ, "Fk", "", 0 }, - { SKIN_TOKEN_FILE_NAME_WITH_EXTENSION, "Fm", "", 0 }, - { SKIN_TOKEN_FILE_NAME, "Fn", "", 0 }, - { SKIN_TOKEN_FILE_PATH, "Fp", "", 0 }, - { SKIN_TOKEN_FILE_SIZE, "Fs", "", 0 }, - { SKIN_TOKEN_FILE_VBR, "Fv", "", 0 }, - { SKIN_TOKEN_FILE_DIRECTORY, "D" , "I", 0 }, - - - { SKIN_TOKEN_METADATA_ARTIST, "ia", "", 0 }, - { SKIN_TOKEN_METADATA_COMPOSER, "ic", "", 0 }, - { SKIN_TOKEN_METADATA_ALBUM, "id", "", 0 }, - { SKIN_TOKEN_METADATA_ALBUM_ARTIST, "iA", "", 0 }, - { SKIN_TOKEN_METADATA_GROUPING, "iG", "", 0 }, - { SKIN_TOKEN_METADATA_GENRE, "ig", "", 0 }, - { SKIN_TOKEN_METADATA_DISC_NUMBER, "ik", "", 0 }, - { SKIN_TOKEN_METADATA_TRACK_NUMBER, "in", "", 0 }, - { SKIN_TOKEN_METADATA_TRACK_TITLE, "it", "", 0 }, - { SKIN_TOKEN_METADATA_VERSION, "iv", "", 0 }, - { SKIN_TOKEN_METADATA_YEAR, "iy", "", 0 }, - { SKIN_TOKEN_METADATA_COMMENT, "iC", "", 0 }, - - { SKIN_TOKEN_METADATA_ARTIST, "Ia", "", 0 }, - { SKIN_TOKEN_METADATA_COMPOSER, "Ic", "", 0 }, - { SKIN_TOKEN_METADATA_ALBUM, "Id", "", 0 }, - { SKIN_TOKEN_METADATA_ALBUM_ARTIST, "IA", "", 0 }, - { SKIN_TOKEN_METADATA_GROUPING, "IG", "", 0 }, - { SKIN_TOKEN_METADATA_GENRE, "Ig", "", 0 }, - { SKIN_TOKEN_METADATA_DISC_NUMBER, "Ik", "", 0 }, - { SKIN_TOKEN_METADATA_TRACK_NUMBER, "In", "", 0 }, - { SKIN_TOKEN_METADATA_TRACK_TITLE, "It", "", 0 }, - { SKIN_TOKEN_METADATA_VERSION, "Iv", "", 0 }, - { SKIN_TOKEN_METADATA_YEAR, "Iy", "", 0 }, - { SKIN_TOKEN_METADATA_COMMENT, "IC", "", 0 }, - - { SKIN_TOKEN_SOUND_PITCH, "Sp", "", 0 }, - { SKIN_TOKEN_SOUND_SPEED, "Ss", "", 0 }, - - { SKIN_TOKEN_VLED_HDD, "lh", "", 0 }, - - { SKIN_TOKEN_MAIN_HOLD, "mh", "", 0 }, - { SKIN_TOKEN_REMOTE_HOLD, "mr", "", 0 }, - { SKIN_TOKEN_REPEAT_MODE, "mm", "", 0 }, - { SKIN_TOKEN_PLAYBACK_STATUS, "mp", "", 0 }, - { SKIN_TOKEN_BUTTON_VOLUME, "mv", "|D", 0 }, - - { SKIN_TOKEN_PEAKMETER, "pm", "", 0 }, - { SKIN_TOKEN_PLAYER_PROGRESSBAR, "pf", "", 0 }, - { SKIN_TOKEN_PROGRESSBAR, "pb" , BAR_PARAMS, 0 }, - { SKIN_TOKEN_VOLUME, "pv" , BAR_PARAMS, 0 }, - - { SKIN_TOKEN_TRACK_ELAPSED_PERCENT, "px", "", 0 }, - { SKIN_TOKEN_TRACK_TIME_ELAPSED, "pc", "", 0 }, - { SKIN_TOKEN_TRACK_TIME_REMAINING, "pr", "", 0 }, - { SKIN_TOKEN_TRACK_LENGTH, "pt", "", 0 }, - { SKIN_TOKEN_TRACK_STARTING, "pS" , "|D", 0 }, - { SKIN_TOKEN_TRACK_ENDING, "pE" , "|D", 0 }, - { SKIN_TOKEN_PLAYLIST_POSITION, "pp", "", 0 }, - { SKIN_TOKEN_PLAYLIST_ENTRIES, "pe", "", 0 }, - { SKIN_TOKEN_PLAYLIST_NAME, "pn", "", 0 }, - { SKIN_TOKEN_PLAYLIST_SHUFFLE, "ps", "", 0 }, - - { SKIN_TOKEN_DATABASE_PLAYCOUNT, "rp", "", 0 }, - { SKIN_TOKEN_DATABASE_RATING, "rr", "", 0 }, - { SKIN_TOKEN_DATABASE_AUTOSCORE, "ra", "", 0 }, - - { SKIN_TOKEN_REPLAYGAIN, "rg", "", 0 }, - { SKIN_TOKEN_CROSSFADE, "xf", "", 0 }, - - { SKIN_TOKEN_HAVE_TUNER, "tp", "", 0 }, - { SKIN_TOKEN_TUNER_TUNED, "tt", "", 0 }, - { SKIN_TOKEN_TUNER_SCANMODE, "tm", "", 0 }, - { SKIN_TOKEN_TUNER_STEREO, "ts", "", 0 }, - { SKIN_TOKEN_TUNER_MINFREQ, "ta", "", 0 }, - { SKIN_TOKEN_TUNER_MAXFREQ, "tb", "", 0 }, - { SKIN_TOKEN_TUNER_CURFREQ, "tf", "", 0 }, - { SKIN_TOKEN_PRESET_ID, "Ti", "", 0 }, - { SKIN_TOKEN_PRESET_NAME, "Tn", "", 0 }, - { SKIN_TOKEN_PRESET_FREQ, "Tf", "", 0 }, - { SKIN_TOKEN_PRESET_COUNT, "Tc", "", 0 }, - { SKIN_TOKEN_HAVE_RDS, "tx", "", 0 }, - { SKIN_TOKEN_RDS_NAME, "ty", "", 0 }, - { SKIN_TOKEN_RDS_TEXT, "tz", "", 0 }, - - { SKIN_TOKEN_SUBLINE_SCROLL, "s", "", 0 }, + { SKIN_TOKEN_FILE_BITRATE, "fb", "", SKIN_REFRESH_STATIC }, + { SKIN_TOKEN_FILE_CODEC, "fc", "", SKIN_REFRESH_STATIC }, + { SKIN_TOKEN_FILE_FREQUENCY, "ff", "", SKIN_REFRESH_STATIC }, + { SKIN_TOKEN_FILE_FREQUENCY_KHZ, "fk", "", SKIN_REFRESH_STATIC }, + { SKIN_TOKEN_FILE_NAME_WITH_EXTENSION, "fm", "", SKIN_REFRESH_STATIC }, + { SKIN_TOKEN_FILE_NAME, "fn", "", SKIN_REFRESH_STATIC }, + { SKIN_TOKEN_FILE_PATH, "fp", "", SKIN_REFRESH_STATIC }, + { SKIN_TOKEN_FILE_SIZE, "fs", "", SKIN_REFRESH_STATIC }, + { SKIN_TOKEN_FILE_VBR, "fv", "", SKIN_REFRESH_STATIC }, + { SKIN_TOKEN_FILE_DIRECTORY, "d" , "I", SKIN_REFRESH_STATIC }, + + { SKIN_TOKEN_FILE_BITRATE, "Fb", "", SKIN_REFRESH_STATIC }, + { SKIN_TOKEN_FILE_CODEC, "Fc", "", SKIN_REFRESH_STATIC }, + { SKIN_TOKEN_FILE_FREQUENCY, "Ff", "", SKIN_REFRESH_STATIC }, + { SKIN_TOKEN_FILE_FREQUENCY_KHZ, "Fk", "", SKIN_REFRESH_STATIC }, + { SKIN_TOKEN_FILE_NAME_WITH_EXTENSION, "Fm", "", SKIN_REFRESH_STATIC }, + { SKIN_TOKEN_FILE_NAME, "Fn", "", SKIN_REFRESH_STATIC }, + { SKIN_TOKEN_FILE_PATH, "Fp", "", SKIN_REFRESH_STATIC }, + { SKIN_TOKEN_FILE_SIZE, "Fs", "", SKIN_REFRESH_STATIC }, + { SKIN_TOKEN_FILE_VBR, "Fv", "", SKIN_REFRESH_STATIC }, + { SKIN_TOKEN_FILE_DIRECTORY, "D" , "I", SKIN_REFRESH_STATIC }, + + + { SKIN_TOKEN_METADATA_ARTIST, "ia", "", SKIN_REFRESH_STATIC }, + { SKIN_TOKEN_METADATA_COMPOSER, "ic", "", SKIN_REFRESH_STATIC }, + { SKIN_TOKEN_METADATA_ALBUM, "id", "", SKIN_REFRESH_STATIC }, + { SKIN_TOKEN_METADATA_ALBUM_ARTIST, "iA", "", SKIN_REFRESH_STATIC }, + { SKIN_TOKEN_METADATA_GROUPING, "iG", "", SKIN_REFRESH_STATIC }, + { SKIN_TOKEN_METADATA_GENRE, "ig", "", SKIN_REFRESH_STATIC }, + { SKIN_TOKEN_METADATA_DISC_NUMBER, "ik", "", SKIN_REFRESH_STATIC }, + { SKIN_TOKEN_METADATA_TRACK_NUMBER, "in", "", SKIN_REFRESH_STATIC }, + { SKIN_TOKEN_METADATA_TRACK_TITLE, "it", "", SKIN_REFRESH_STATIC }, + { SKIN_TOKEN_METADATA_VERSION, "iv", "", SKIN_REFRESH_STATIC }, + { SKIN_TOKEN_METADATA_YEAR, "iy", "", SKIN_REFRESH_STATIC }, + { SKIN_TOKEN_METADATA_COMMENT, "iC", "", SKIN_REFRESH_STATIC }, + + { SKIN_TOKEN_METADATA_ARTIST, "Ia", "", SKIN_REFRESH_STATIC }, + { SKIN_TOKEN_METADATA_COMPOSER, "Ic", "", SKIN_REFRESH_STATIC }, + { SKIN_TOKEN_METADATA_ALBUM, "Id", "", SKIN_REFRESH_STATIC }, + { SKIN_TOKEN_METADATA_ALBUM_ARTIST, "IA", "", SKIN_REFRESH_STATIC }, + { SKIN_TOKEN_METADATA_GROUPING, "IG", "", SKIN_REFRESH_STATIC }, + { SKIN_TOKEN_METADATA_GENRE, "Ig", "", SKIN_REFRESH_STATIC }, + { SKIN_TOKEN_METADATA_DISC_NUMBER, "Ik", "", SKIN_REFRESH_STATIC }, + { SKIN_TOKEN_METADATA_TRACK_NUMBER, "In", "", SKIN_REFRESH_STATIC }, + { SKIN_TOKEN_METADATA_TRACK_TITLE, "It", "", SKIN_REFRESH_STATIC }, + { SKIN_TOKEN_METADATA_VERSION, "Iv", "", SKIN_REFRESH_STATIC }, + { SKIN_TOKEN_METADATA_YEAR, "Iy", "", SKIN_REFRESH_STATIC }, + { SKIN_TOKEN_METADATA_COMMENT, "IC", "", SKIN_REFRESH_STATIC }, + + { SKIN_TOKEN_SOUND_PITCH, "Sp", "", SKIN_REFRESH_DYNAMIC }, + { SKIN_TOKEN_SOUND_SPEED, "Ss", "", SKIN_REFRESH_DYNAMIC }, + + { SKIN_TOKEN_VLED_HDD, "lh", "", SKIN_REFRESH_DYNAMIC }, + + { SKIN_TOKEN_MAIN_HOLD, "mh", "", SKIN_REFRESH_DYNAMIC }, + { SKIN_TOKEN_REMOTE_HOLD, "mr", "", SKIN_REFRESH_DYNAMIC }, + { SKIN_TOKEN_REPEAT_MODE, "mm", "", SKIN_REFRESH_DYNAMIC }, + { SKIN_TOKEN_PLAYBACK_STATUS, "mp", "", SKIN_REFRESH_DYNAMIC }, + { SKIN_TOKEN_BUTTON_VOLUME, "mv", "|D", SKIN_REFRESH_DYNAMIC }, + + { SKIN_TOKEN_PEAKMETER, "pm", "", SKIN_REFRESH_PEAK_METER }, + { SKIN_TOKEN_PLAYER_PROGRESSBAR, "pf", "", SKIN_REFRESH_DYNAMIC|SKIN_REFRESH_PLAYER_PROGRESS }, + { SKIN_TOKEN_PROGRESSBAR, "pb" , BAR_PARAMS, SKIN_REFRESH_PLAYER_PROGRESS }, + { SKIN_TOKEN_VOLUME, "pv" , BAR_PARAMS, SKIN_REFRESH_DYNAMIC }, + { SKIN_TOKEN_TRACK_ELAPSED_PERCENT, "px", "", SKIN_REFRESH_DYNAMIC }, + { SKIN_TOKEN_TRACK_TIME_ELAPSED, "pc", "", SKIN_REFRESH_DYNAMIC }, + { SKIN_TOKEN_TRACK_TIME_REMAINING, "pr", "", SKIN_REFRESH_DYNAMIC }, + { SKIN_TOKEN_TRACK_LENGTH, "pt", "", SKIN_REFRESH_STATIC }, + { SKIN_TOKEN_TRACK_STARTING, "pS" , "|D", SKIN_REFRESH_DYNAMIC }, + { SKIN_TOKEN_TRACK_ENDING, "pE" , "|D", SKIN_REFRESH_DYNAMIC }, + { SKIN_TOKEN_PLAYLIST_POSITION, "pp", "", SKIN_REFRESH_STATIC }, + { SKIN_TOKEN_PLAYLIST_ENTRIES, "pe", "", SKIN_REFRESH_STATIC }, + { SKIN_TOKEN_PLAYLIST_NAME, "pn", "", SKIN_REFRESH_STATIC }, + { SKIN_TOKEN_PLAYLIST_SHUFFLE, "ps", "", SKIN_REFRESH_DYNAMIC }, + + { SKIN_TOKEN_DATABASE_PLAYCOUNT, "rp", "", SKIN_REFRESH_DYNAMIC }, + { SKIN_TOKEN_DATABASE_RATING, "rr", "", SKIN_REFRESH_DYNAMIC }, + { SKIN_TOKEN_DATABASE_AUTOSCORE, "ra", "", SKIN_REFRESH_DYNAMIC }, + + { SKIN_TOKEN_REPLAYGAIN, "rg", "", SKIN_REFRESH_STATIC }, + { SKIN_TOKEN_CROSSFADE, "xf", "", SKIN_REFRESH_DYNAMIC }, + + { SKIN_TOKEN_HAVE_TUNER, "tp", "", SKIN_REFRESH_STATIC }, + { SKIN_TOKEN_TUNER_TUNED, "tt", "", SKIN_REFRESH_DYNAMIC }, + { SKIN_TOKEN_TUNER_SCANMODE, "tm", "", SKIN_REFRESH_DYNAMIC }, + { SKIN_TOKEN_TUNER_STEREO, "ts", "", SKIN_REFRESH_DYNAMIC }, + { SKIN_TOKEN_TUNER_MINFREQ, "ta", "", SKIN_REFRESH_STATIC }, + { SKIN_TOKEN_TUNER_MAXFREQ, "tb", "", SKIN_REFRESH_STATIC }, + { SKIN_TOKEN_TUNER_CURFREQ, "tf", "", SKIN_REFRESH_DYNAMIC }, + { SKIN_TOKEN_PRESET_ID, "Ti", "", SKIN_REFRESH_STATIC }, + { SKIN_TOKEN_PRESET_NAME, "Tn", "", SKIN_REFRESH_STATIC }, + { SKIN_TOKEN_PRESET_FREQ, "Tf", "", SKIN_REFRESH_STATIC }, + { SKIN_TOKEN_PRESET_COUNT, "Tc", "", SKIN_REFRESH_STATIC }, + { SKIN_TOKEN_HAVE_RDS, "tx", "", SKIN_REFRESH_STATIC }, + { SKIN_TOKEN_RDS_NAME, "ty", "", SKIN_REFRESH_DYNAMIC }, + { SKIN_TOKEN_RDS_TEXT, "tz", "", SKIN_REFRESH_DYNAMIC }, + + { SKIN_TOKEN_SUBLINE_SCROLL, "s", "", SKIN_REFRESH_SCROLL }, { SKIN_TOKEN_SUBLINE_TIMEOUT, "t" , "D", 0 }, + + { SKIN_TOKEN_ENABLE_THEME, "we", "", 0|NOBREAK }, + { SKIN_TOKEN_DISABLE_THEME, "wd", "", 0|NOBREAK }, + { SKIN_TOKEN_DRAW_INBUILTBAR, "wi", "", SKIN_REFRESH_STATIC|NOBREAK }, - { SKIN_TOKEN_ENABLE_THEME, "we", "", NOBREAK }, - { SKIN_TOKEN_DISABLE_THEME, "wd", "", NOBREAK }, - { SKIN_TOKEN_DRAW_INBUILTBAR, "wi", "", NOBREAK }, - - { SKIN_TOKEN_IMAGE_PRELOAD, "xl", "SFII|I", NOBREAK }, + { SKIN_TOKEN_IMAGE_PRELOAD, "xl", "SFII|I", 0|NOBREAK }, { SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY, "xd", "S", 0 }, - { SKIN_TOKEN_IMAGE_PRELOAD, "x", "SFII", NOBREAK }, + { SKIN_TOKEN_IMAGE_DISPLAY, "x", "SFII", 0|NOBREAK }, - { SKIN_TOKEN_LOAD_FONT, "Fl" , "IF", NOBREAK }, - { SKIN_TOKEN_ALBUMART_LOAD, "Cl" , "IIII|ss", NOBREAK }, - { SKIN_TOKEN_ALBUMART_DISPLAY, "Cd" , "", 0 }, - { SKIN_TOKEN_ALBUMART_FOUND, "C" , "", 0 }, + { SKIN_TOKEN_LOAD_FONT, "Fl" , "IF", 0|NOBREAK }, + { SKIN_TOKEN_ALBUMART_LOAD, "Cl" , "IIII|ss", 0|NOBREAK }, + { SKIN_TOKEN_ALBUMART_DISPLAY, "Cd" , "", SKIN_REFRESH_STATIC }, + { SKIN_TOKEN_ALBUMART_FOUND, "C" , "", SKIN_REFRESH_STATIC }, - { SKIN_TOKEN_VIEWPORT_ENABLE, "Vd" , "S", 0 }, - { SKIN_TOKEN_UIVIEWPORT_ENABLE, "VI" , "S", 0 }, + { SKIN_TOKEN_VIEWPORT_ENABLE, "Vd" , "S", SKIN_REFRESH_STATIC }, + { SKIN_TOKEN_UIVIEWPORT_ENABLE, "VI" , "S", SKIN_REFRESH_STATIC }, - { SKIN_TOKEN_VIEWPORT_CUSTOMLIST, "Vp" , "ICC", NOBREAK }, - { SKIN_TOKEN_LIST_TITLE_TEXT, "Lt" , "", 0 }, - { SKIN_TOKEN_LIST_TITLE_ICON, "Li" , "", 0 }, + { SKIN_TOKEN_VIEWPORT_CUSTOMLIST, "Vp" , "ICC", SKIN_REFRESH_DYNAMIC|NOBREAK }, + { SKIN_TOKEN_LIST_TITLE_TEXT, "Lt" , "", SKIN_REFRESH_DYNAMIC }, + { SKIN_TOKEN_LIST_TITLE_ICON, "Li" , "", SKIN_REFRESH_DYNAMIC }, - { SKIN_TOKEN_VIEWPORT_FGCOLOUR, "Vf" , "S", NOBREAK }, - { SKIN_TOKEN_VIEWPORT_BGCOLOUR, "Vb" , "S", NOBREAK }, + { SKIN_TOKEN_VIEWPORT_FGCOLOUR, "Vf" , "s", SKIN_REFRESH_STATIC|NOBREAK }, + { SKIN_TOKEN_VIEWPORT_BGCOLOUR, "Vb" , "s", SKIN_REFRESH_STATIC|NOBREAK }, { SKIN_TOKEN_VIEWPORT_CONDITIONAL, "Vl" , "SIIiii", 0 }, { SKIN_TOKEN_UIVIEWPORT_LOAD, "Vi" , "sIIiii", 0 }, { SKIN_TOKEN_VIEWPORT_LOAD, "V" , "IIiii", 0 }, - { SKIN_TOKEN_IMAGE_BACKDROP, "X" , "f", NOBREAK }, - - { SKIN_TOKEN_SETTING, "St" , "S", 0 }, - { SKIN_TOKEN_TRANSLATEDSTRING, "Sx" , "S", 0 }, - { SKIN_TOKEN_LANG_IS_RTL, "Sr" , "", 0 }, - - { SKIN_TOKEN_LASTTOUCH, "Tl" , "|D", 0 }, - { SKIN_TOKEN_CURRENT_SCREEN, "cs", "", 0 }, - { SKIN_TOKEN_TOUCHREGION, "T" , "IIiiS", NOBREAK }, - - { SKIN_TOKEN_HAVE_RECORDING, "Rp" , "", 0 }, - { SKIN_TOKEN_IS_RECORDING, "Rr" , "", 0 }, - { SKIN_TOKEN_REC_FREQ, "Rf" , "", 0 }, - { SKIN_TOKEN_REC_ENCODER, "Re" , "", 0 }, - { SKIN_TOKEN_REC_BITRATE, "Rb" , "", 0 }, - { SKIN_TOKEN_REC_MONO, "Rm" , "", 0 }, - { SKIN_TOKEN_REC_SECONDS, "Rs" , "", 0 }, - { SKIN_TOKEN_REC_MINUTES, "Rn" , "", 0 }, - { SKIN_TOKEN_REC_HOURS, "Rh" , "", 0 }, + { SKIN_TOKEN_IMAGE_BACKDROP, "X" , "f", SKIN_REFRESH_STATIC|NOBREAK }, + + { SKIN_TOKEN_SETTING, "St" , "S", SKIN_REFRESH_DYNAMIC }, + { SKIN_TOKEN_TRANSLATEDSTRING, "Sx" , "S", SKIN_REFRESH_STATIC }, + { SKIN_TOKEN_LANG_IS_RTL, "Sr" , "", SKIN_REFRESH_STATIC }, + + { SKIN_TOKEN_LASTTOUCH, "Tl" , "|D", SKIN_REFRESH_DYNAMIC }, + { SKIN_TOKEN_CURRENT_SCREEN, "cs", "", SKIN_REFRESH_DYNAMIC }, + { SKIN_TOKEN_TOUCHREGION, "T" , "IIiiS", 0|NOBREAK }, + + { SKIN_TOKEN_HAVE_RECORDING, "Rp" , "", SKIN_REFRESH_STATIC }, + { SKIN_TOKEN_IS_RECORDING, "Rr" , "", SKIN_REFRESH_DYNAMIC }, + { SKIN_TOKEN_REC_FREQ, "Rf" , "", SKIN_REFRESH_DYNAMIC }, + { SKIN_TOKEN_REC_ENCODER, "Re" , "", SKIN_REFRESH_DYNAMIC }, + { SKIN_TOKEN_REC_BITRATE, "Rb" , "", SKIN_REFRESH_DYNAMIC }, + { SKIN_TOKEN_REC_MONO, "Rm" , "", SKIN_REFRESH_DYNAMIC }, + { SKIN_TOKEN_REC_SECONDS, "Rs" , "", SKIN_REFRESH_DYNAMIC }, + { SKIN_TOKEN_REC_MINUTES, "Rn" , "", SKIN_REFRESH_DYNAMIC }, + { SKIN_TOKEN_REC_HOURS, "Rh" , "", SKIN_REFRESH_DYNAMIC }, { SKIN_TOKEN_UNKNOWN, "" , "", 0 } /* Keep this here to mark the end of the table */ diff --git a/lib/skin_parser/tag_table.h b/lib/skin_parser/tag_table.h index f84d4ac762..dde1487d13 100644 --- a/lib/skin_parser/tag_table.h +++ b/lib/skin_parser/tag_table.h @@ -27,12 +27,31 @@ extern "C" { #endif +#define MAX_TAG_PARAMS 12 + + /* Flag to tell the renderer not to insert a line break */ #define NOBREAK 0x1 +/* constants used in line_type and as refresh_mode for wps_refresh */ +#define SKIN_REFRESH_SHIFT 16 +#define SKIN_REFRESH_STATIC (1u<