1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2010 Robert Bieber
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
22 #include "tag_table.h"
25 #define BAR_PARAMS "*|iiiis"
26 /* The tag definition table */
27 static const struct tag_info legal_tags
[] =
29 { SKIN_TOKEN_ALIGN_CENTER
, "ac", "", 0 },
30 { SKIN_TOKEN_ALIGN_LEFT
, "al", "", 0 },
31 { SKIN_TOKEN_ALIGN_LEFT_RTL
, "aL", "", 0 },
32 { SKIN_TOKEN_ALIGN_RIGHT
, "ar", "", 0 },
33 { SKIN_TOKEN_ALIGN_RIGHT_RTL
, "aR", "", 0 },
34 { SKIN_TOKEN_ALIGN_LANGDIRECTION
, "ax", "", 0 },
36 { SKIN_TOKEN_BATTERY_PERCENT
, "bl" , BAR_PARAMS
, SKIN_REFRESH_DYNAMIC
},
37 { SKIN_TOKEN_BATTERY_VOLTS
, "bv", "", SKIN_REFRESH_DYNAMIC
},
38 { SKIN_TOKEN_BATTERY_TIME
, "bt", "", SKIN_REFRESH_DYNAMIC
},
39 { SKIN_TOKEN_BATTERY_SLEEPTIME
, "bs", "", SKIN_REFRESH_DYNAMIC
},
40 { SKIN_TOKEN_BATTERY_CHARGING
, "bc", "", SKIN_REFRESH_DYNAMIC
},
41 { SKIN_TOKEN_BATTERY_CHARGER_CONNECTED
, "bp", "", SKIN_REFRESH_DYNAMIC
},
42 { SKIN_TOKEN_USB_POWERED
, "bu", "", SKIN_REFRESH_DYNAMIC
},
45 { SKIN_TOKEN_RTC_PRESENT
, "cc", "", SKIN_REFRESH_STATIC
},
46 { SKIN_TOKEN_RTC_DAY_OF_MONTH
, "cd", "", SKIN_RTC_REFRESH
},
47 { SKIN_TOKEN_RTC_DAY_OF_MONTH_BLANK_PADDED
, "ce", "", SKIN_RTC_REFRESH
},
48 { SKIN_TOKEN_RTC_12HOUR_CFG
, "cf", "", SKIN_RTC_REFRESH
},
49 { SKIN_TOKEN_RTC_HOUR_24_ZERO_PADDED
, "cH", "", SKIN_RTC_REFRESH
},
50 { SKIN_TOKEN_RTC_HOUR_24
, "ck", "", SKIN_RTC_REFRESH
},
51 { SKIN_TOKEN_RTC_HOUR_12_ZERO_PADDED
, "cI", "", SKIN_RTC_REFRESH
},
52 { SKIN_TOKEN_RTC_HOUR_12
, "cl", "", SKIN_RTC_REFRESH
},
53 { SKIN_TOKEN_RTC_MONTH
, "cm", "", SKIN_RTC_REFRESH
},
54 { SKIN_TOKEN_RTC_MINUTE
, "cM", "", SKIN_RTC_REFRESH
},
55 { SKIN_TOKEN_RTC_SECOND
, "cS", "", SKIN_RTC_REFRESH
},
56 { SKIN_TOKEN_RTC_YEAR_2_DIGITS
, "cy", "", SKIN_RTC_REFRESH
},
57 { SKIN_TOKEN_RTC_YEAR_4_DIGITS
, "cY", "", SKIN_RTC_REFRESH
},
58 { SKIN_TOKEN_RTC_AM_PM_UPPER
, "cP", "", SKIN_RTC_REFRESH
},
59 { SKIN_TOKEN_RTC_AM_PM_LOWER
, "cp", "", SKIN_RTC_REFRESH
},
60 { SKIN_TOKEN_RTC_WEEKDAY_NAME
, "ca", "", SKIN_RTC_REFRESH
},
61 { SKIN_TOKEN_RTC_MONTH_NAME
, "cb", "", SKIN_RTC_REFRESH
},
62 { SKIN_TOKEN_RTC_DAY_OF_WEEK_START_MON
, "cu", "", SKIN_RTC_REFRESH
},
63 { SKIN_TOKEN_RTC_DAY_OF_WEEK_START_SUN
, "cw", "", SKIN_RTC_REFRESH
},
65 { SKIN_TOKEN_FILE_BITRATE
, "fb", "", SKIN_REFRESH_STATIC
},
66 { SKIN_TOKEN_FILE_CODEC
, "fc", "", SKIN_REFRESH_STATIC
},
67 { SKIN_TOKEN_FILE_FREQUENCY
, "ff", "", SKIN_REFRESH_STATIC
},
68 { SKIN_TOKEN_FILE_FREQUENCY_KHZ
, "fk", "", SKIN_REFRESH_STATIC
},
69 { SKIN_TOKEN_FILE_NAME_WITH_EXTENSION
, "fm", "", SKIN_REFRESH_STATIC
},
70 { SKIN_TOKEN_FILE_NAME
, "fn", "", SKIN_REFRESH_STATIC
},
71 { SKIN_TOKEN_FILE_PATH
, "fp", "", SKIN_REFRESH_STATIC
},
72 { SKIN_TOKEN_FILE_SIZE
, "fs", "", SKIN_REFRESH_STATIC
},
73 { SKIN_TOKEN_FILE_VBR
, "fv", "", SKIN_REFRESH_STATIC
},
74 { SKIN_TOKEN_FILE_DIRECTORY
, "d" , "I", SKIN_REFRESH_STATIC
},
76 { SKIN_TOKEN_FILE_BITRATE
, "Fb", "", SKIN_REFRESH_STATIC
},
77 { SKIN_TOKEN_FILE_CODEC
, "Fc", "", SKIN_REFRESH_STATIC
},
78 { SKIN_TOKEN_FILE_FREQUENCY
, "Ff", "", SKIN_REFRESH_STATIC
},
79 { SKIN_TOKEN_FILE_FREQUENCY_KHZ
, "Fk", "", SKIN_REFRESH_STATIC
},
80 { SKIN_TOKEN_FILE_NAME_WITH_EXTENSION
, "Fm", "", SKIN_REFRESH_STATIC
},
81 { SKIN_TOKEN_FILE_NAME
, "Fn", "", SKIN_REFRESH_STATIC
},
82 { SKIN_TOKEN_FILE_PATH
, "Fp", "", SKIN_REFRESH_STATIC
},
83 { SKIN_TOKEN_FILE_SIZE
, "Fs", "", SKIN_REFRESH_STATIC
},
84 { SKIN_TOKEN_FILE_VBR
, "Fv", "", SKIN_REFRESH_STATIC
},
85 { SKIN_TOKEN_FILE_DIRECTORY
, "D" , "I", SKIN_REFRESH_STATIC
},
88 { SKIN_TOKEN_METADATA_ARTIST
, "ia", "", SKIN_REFRESH_STATIC
},
89 { SKIN_TOKEN_METADATA_COMPOSER
, "ic", "", SKIN_REFRESH_STATIC
},
90 { SKIN_TOKEN_METADATA_ALBUM
, "id", "", SKIN_REFRESH_STATIC
},
91 { SKIN_TOKEN_METADATA_ALBUM_ARTIST
, "iA", "", SKIN_REFRESH_STATIC
},
92 { SKIN_TOKEN_METADATA_GROUPING
, "iG", "", SKIN_REFRESH_STATIC
},
93 { SKIN_TOKEN_METADATA_GENRE
, "ig", "", SKIN_REFRESH_STATIC
},
94 { SKIN_TOKEN_METADATA_DISC_NUMBER
, "ik", "", SKIN_REFRESH_STATIC
},
95 { SKIN_TOKEN_METADATA_TRACK_NUMBER
, "in", "", SKIN_REFRESH_STATIC
},
96 { SKIN_TOKEN_METADATA_TRACK_TITLE
, "it", "", SKIN_REFRESH_STATIC
},
97 { SKIN_TOKEN_METADATA_VERSION
, "iv", "", SKIN_REFRESH_STATIC
},
98 { SKIN_TOKEN_METADATA_YEAR
, "iy", "", SKIN_REFRESH_STATIC
},
99 { SKIN_TOKEN_METADATA_COMMENT
, "iC", "", SKIN_REFRESH_STATIC
},
101 { SKIN_TOKEN_METADATA_ARTIST
, "Ia", "", SKIN_REFRESH_STATIC
},
102 { SKIN_TOKEN_METADATA_COMPOSER
, "Ic", "", SKIN_REFRESH_STATIC
},
103 { SKIN_TOKEN_METADATA_ALBUM
, "Id", "", SKIN_REFRESH_STATIC
},
104 { SKIN_TOKEN_METADATA_ALBUM_ARTIST
, "IA", "", SKIN_REFRESH_STATIC
},
105 { SKIN_TOKEN_METADATA_GROUPING
, "IG", "", SKIN_REFRESH_STATIC
},
106 { SKIN_TOKEN_METADATA_GENRE
, "Ig", "", SKIN_REFRESH_STATIC
},
107 { SKIN_TOKEN_METADATA_DISC_NUMBER
, "Ik", "", SKIN_REFRESH_STATIC
},
108 { SKIN_TOKEN_METADATA_TRACK_NUMBER
, "In", "", SKIN_REFRESH_STATIC
},
109 { SKIN_TOKEN_METADATA_TRACK_TITLE
, "It", "", SKIN_REFRESH_STATIC
},
110 { SKIN_TOKEN_METADATA_VERSION
, "Iv", "", SKIN_REFRESH_STATIC
},
111 { SKIN_TOKEN_METADATA_YEAR
, "Iy", "", SKIN_REFRESH_STATIC
},
112 { SKIN_TOKEN_METADATA_COMMENT
, "IC", "", SKIN_REFRESH_STATIC
},
114 { SKIN_TOKEN_SOUND_PITCH
, "Sp", "", SKIN_REFRESH_DYNAMIC
},
115 { SKIN_TOKEN_SOUND_SPEED
, "Ss", "", SKIN_REFRESH_DYNAMIC
},
117 { SKIN_TOKEN_VLED_HDD
, "lh", "", SKIN_REFRESH_DYNAMIC
},
119 { SKIN_TOKEN_MAIN_HOLD
, "mh", "", SKIN_REFRESH_DYNAMIC
},
120 { SKIN_TOKEN_REMOTE_HOLD
, "mr", "", SKIN_REFRESH_DYNAMIC
},
121 { SKIN_TOKEN_REPEAT_MODE
, "mm", "", SKIN_REFRESH_DYNAMIC
},
122 { SKIN_TOKEN_PLAYBACK_STATUS
, "mp", "", SKIN_REFRESH_DYNAMIC
},
123 { SKIN_TOKEN_BUTTON_VOLUME
, "mv", "|D", SKIN_REFRESH_DYNAMIC
},
125 { SKIN_TOKEN_PEAKMETER
, "pm", "", SKIN_REFRESH_PEAK_METER
},
126 { SKIN_TOKEN_PLAYER_PROGRESSBAR
, "pf", "", SKIN_REFRESH_DYNAMIC
|SKIN_REFRESH_PLAYER_PROGRESS
},
127 { SKIN_TOKEN_PROGRESSBAR
, "pb" , BAR_PARAMS
, SKIN_REFRESH_PLAYER_PROGRESS
},
128 { SKIN_TOKEN_VOLUME
, "pv" , BAR_PARAMS
, SKIN_REFRESH_DYNAMIC
},
129 { SKIN_TOKEN_TRACK_ELAPSED_PERCENT
, "px", "", SKIN_REFRESH_DYNAMIC
},
130 { SKIN_TOKEN_TRACK_TIME_ELAPSED
, "pc", "", SKIN_REFRESH_DYNAMIC
},
131 { SKIN_TOKEN_TRACK_TIME_REMAINING
, "pr", "", SKIN_REFRESH_DYNAMIC
},
132 { SKIN_TOKEN_TRACK_LENGTH
, "pt", "", SKIN_REFRESH_STATIC
},
133 { SKIN_TOKEN_TRACK_STARTING
, "pS" , "|D", SKIN_REFRESH_DYNAMIC
},
134 { SKIN_TOKEN_TRACK_ENDING
, "pE" , "|D", SKIN_REFRESH_DYNAMIC
},
135 { SKIN_TOKEN_PLAYLIST_POSITION
, "pp", "", SKIN_REFRESH_STATIC
},
136 { SKIN_TOKEN_PLAYLIST_ENTRIES
, "pe", "", SKIN_REFRESH_STATIC
},
137 { SKIN_TOKEN_PLAYLIST_NAME
, "pn", "", SKIN_REFRESH_STATIC
},
138 { SKIN_TOKEN_PLAYLIST_SHUFFLE
, "ps", "", SKIN_REFRESH_DYNAMIC
},
140 { SKIN_TOKEN_DATABASE_PLAYCOUNT
, "rp", "", SKIN_REFRESH_DYNAMIC
},
141 { SKIN_TOKEN_DATABASE_RATING
, "rr", "", SKIN_REFRESH_DYNAMIC
},
142 { SKIN_TOKEN_DATABASE_AUTOSCORE
, "ra", "", SKIN_REFRESH_DYNAMIC
},
144 { SKIN_TOKEN_REPLAYGAIN
, "rg", "", SKIN_REFRESH_STATIC
},
145 { SKIN_TOKEN_CROSSFADE
, "xf", "", SKIN_REFRESH_DYNAMIC
},
147 { SKIN_TOKEN_HAVE_TUNER
, "tp", "", SKIN_REFRESH_STATIC
},
148 { SKIN_TOKEN_TUNER_TUNED
, "tt", "", SKIN_REFRESH_DYNAMIC
},
149 { SKIN_TOKEN_TUNER_SCANMODE
, "tm", "", SKIN_REFRESH_DYNAMIC
},
150 { SKIN_TOKEN_TUNER_STEREO
, "ts", "", SKIN_REFRESH_DYNAMIC
},
151 { SKIN_TOKEN_TUNER_MINFREQ
, "ta", "", SKIN_REFRESH_STATIC
},
152 { SKIN_TOKEN_TUNER_MAXFREQ
, "tb", "", SKIN_REFRESH_STATIC
},
153 { SKIN_TOKEN_TUNER_CURFREQ
, "tf", "", SKIN_REFRESH_DYNAMIC
},
154 { SKIN_TOKEN_PRESET_ID
, "Ti", "", SKIN_REFRESH_STATIC
},
155 { SKIN_TOKEN_PRESET_NAME
, "Tn", "", SKIN_REFRESH_STATIC
},
156 { SKIN_TOKEN_PRESET_FREQ
, "Tf", "", SKIN_REFRESH_STATIC
},
157 { SKIN_TOKEN_PRESET_COUNT
, "Tc", "", SKIN_REFRESH_STATIC
},
158 { SKIN_TOKEN_HAVE_RDS
, "tx", "", SKIN_REFRESH_STATIC
},
159 { SKIN_TOKEN_RDS_NAME
, "ty", "", SKIN_REFRESH_DYNAMIC
},
160 { SKIN_TOKEN_RDS_TEXT
, "tz", "", SKIN_REFRESH_DYNAMIC
},
162 { SKIN_TOKEN_SUBLINE_SCROLL
, "s", "", SKIN_REFRESH_SCROLL
},
163 { SKIN_TOKEN_SUBLINE_TIMEOUT
, "t" , "D", 0 },
165 { SKIN_TOKEN_ENABLE_THEME
, "we", "", 0|NOBREAK
},
166 { SKIN_TOKEN_DISABLE_THEME
, "wd", "", 0|NOBREAK
},
167 { SKIN_TOKEN_DRAW_INBUILTBAR
, "wi", "", SKIN_REFRESH_STATIC
|NOBREAK
},
169 { SKIN_TOKEN_IMAGE_PRELOAD
, "xl", "SFII|I", 0|NOBREAK
},
170 { SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY
, "xd", "S", 0 },
171 { SKIN_TOKEN_IMAGE_DISPLAY
, "x", "SFII", 0|NOBREAK
},
173 { SKIN_TOKEN_LOAD_FONT
, "Fl" , "IF", 0|NOBREAK
},
174 { SKIN_TOKEN_ALBUMART_LOAD
, "Cl" , "IIII|ss", 0|NOBREAK
},
175 { SKIN_TOKEN_ALBUMART_DISPLAY
, "Cd" , "", SKIN_REFRESH_STATIC
},
176 { SKIN_TOKEN_ALBUMART_FOUND
, "C" , "", SKIN_REFRESH_STATIC
},
178 { SKIN_TOKEN_VIEWPORT_ENABLE
, "Vd" , "S", SKIN_REFRESH_STATIC
},
179 { SKIN_TOKEN_UIVIEWPORT_ENABLE
, "VI" , "S", SKIN_REFRESH_STATIC
},
181 { SKIN_TOKEN_VIEWPORT_CUSTOMLIST
, "Vp" , "ICC", SKIN_REFRESH_DYNAMIC
|NOBREAK
},
182 { SKIN_TOKEN_LIST_TITLE_TEXT
, "Lt" , "", SKIN_REFRESH_DYNAMIC
},
183 { SKIN_TOKEN_LIST_TITLE_ICON
, "Li" , "", SKIN_REFRESH_DYNAMIC
},
185 { SKIN_TOKEN_VIEWPORT_FGCOLOUR
, "Vf" , "s", SKIN_REFRESH_STATIC
|NOBREAK
},
186 { SKIN_TOKEN_VIEWPORT_BGCOLOUR
, "Vb" , "s", SKIN_REFRESH_STATIC
|NOBREAK
},
188 { SKIN_TOKEN_VIEWPORT_CONDITIONAL
, "Vl" , "SIIiii", 0 },
189 { SKIN_TOKEN_UIVIEWPORT_LOAD
, "Vi" , "sIIiii", 0 },
190 { SKIN_TOKEN_VIEWPORT_LOAD
, "V" , "IIiii", 0 },
192 { SKIN_TOKEN_IMAGE_BACKDROP
, "X" , "f", SKIN_REFRESH_STATIC
|NOBREAK
},
194 { SKIN_TOKEN_SETTING
, "St" , "S", SKIN_REFRESH_DYNAMIC
},
195 { SKIN_TOKEN_TRANSLATEDSTRING
, "Sx" , "S", SKIN_REFRESH_STATIC
},
196 { SKIN_TOKEN_LANG_IS_RTL
, "Sr" , "", SKIN_REFRESH_STATIC
},
198 { SKIN_TOKEN_LASTTOUCH
, "Tl" , "|D", SKIN_REFRESH_DYNAMIC
},
199 { SKIN_TOKEN_CURRENT_SCREEN
, "cs", "", SKIN_REFRESH_DYNAMIC
},
200 { SKIN_TOKEN_TOUCHREGION
, "T" , "IIiiS", 0|NOBREAK
},
202 { SKIN_TOKEN_HAVE_RECORDING
, "Rp" , "", SKIN_REFRESH_STATIC
},
203 { SKIN_TOKEN_IS_RECORDING
, "Rr" , "", SKIN_REFRESH_DYNAMIC
},
204 { SKIN_TOKEN_REC_FREQ
, "Rf" , "", SKIN_REFRESH_DYNAMIC
},
205 { SKIN_TOKEN_REC_ENCODER
, "Re" , "", SKIN_REFRESH_DYNAMIC
},
206 { SKIN_TOKEN_REC_BITRATE
, "Rb" , "", SKIN_REFRESH_DYNAMIC
},
207 { SKIN_TOKEN_REC_MONO
, "Rm" , "", SKIN_REFRESH_DYNAMIC
},
208 { SKIN_TOKEN_REC_SECONDS
, "Rs" , "", SKIN_REFRESH_DYNAMIC
},
209 { SKIN_TOKEN_REC_MINUTES
, "Rn" , "", SKIN_REFRESH_DYNAMIC
},
210 { SKIN_TOKEN_REC_HOURS
, "Rh" , "", SKIN_REFRESH_DYNAMIC
},
212 { SKIN_TOKEN_UNKNOWN
, "" , "", 0 }
213 /* Keep this here to mark the end of the table */
216 /* A table of legal escapable characters */
217 static const char legal_escape_characters
[] = "%(,);#<|>";
220 * Just does a straight search through the tag table to find one by
223 const struct tag_info
* find_tag(const char* name
)
226 const struct tag_info
* current
= legal_tags
;
229 * Continue searching so long as we have a non-empty name string
230 * and the name of the current element doesn't match the name
231 * we're searching for
234 while(strcmp(current
->name
, name
) && current
->name
[0] != '\0')
237 if(current
->name
[0] == '\0')
244 /* Searches through the legal escape characters string */
245 int find_escape_character(char lookup
)
247 const char* current
= legal_escape_characters
;
248 while(*current
!= lookup
&& *current
!= '\0')
251 if(*current
== lookup
&& *current
)