diff options
author | Jonathan Gordon <rockbox@jdgordon.info> | 2012-05-16 22:28:59 +1000 |
---|---|---|
committer | Jonathan Gordon <rockbox@jdgordon.info> | 2012-05-16 22:33:40 +1000 |
commit | 7909bf039f6e5984b5a037d3de69128f02408223 (patch) | |
tree | bbb8cf36a77b408b76247010258fcc3e9f4d654b /apps/gui/skin_engine/skin_parser.c | |
parent | 027ebaf46330b8e7df1a09974ee16f644edccacb (diff) | |
download | rockbox-7909bf039f6e5984b5a037d3de69128f02408223.tar.gz rockbox-7909bf039f6e5984b5a037d3de69128f02408223.zip |
(hopefully) Fix FS#12639 and other skin related buflib corruption issues.
Kudos to funman for figuring out the problem - skin_find_item() rather
stupidly uses the global skin_buffer variable in skin_parser.c which is
fine in the parser EXCEPT it gets changed in skin_render when the sbs
is being redrawn while another skin is loading, so fix this by makeing
skin_find_item() use a local data pointer so a skin_render() during
parsing won't break anything.
Change-Id: I80e1c0efe569c18225e5772159c18ebb21e07332
Diffstat (limited to 'apps/gui/skin_engine/skin_parser.c')
-rw-r--r-- | apps/gui/skin_engine/skin_parser.c | 45 |
1 files changed, 18 insertions, 27 deletions
diff --git a/apps/gui/skin_engine/skin_parser.c b/apps/gui/skin_engine/skin_parser.c index 92615ac7ee..e364cf1c76 100644 --- a/apps/gui/skin_engine/skin_parser.c +++ b/apps/gui/skin_engine/skin_parser.c | |||
@@ -80,11 +80,6 @@ | |||
80 | #define WPS_ERROR_INVALID_PARAM -1 | 80 | #define WPS_ERROR_INVALID_PARAM -1 |
81 | 81 | ||
82 | static char* skin_buffer = NULL; | 82 | static char* skin_buffer = NULL; |
83 | void skinparser_set_buffer(char* pointer) | ||
84 | { | ||
85 | skin_buffer = pointer; | ||
86 | } | ||
87 | |||
88 | #if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)) | 83 | #if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)) |
89 | static char *backdrop_filename; | 84 | static char *backdrop_filename; |
90 | #endif | 85 | #endif |
@@ -158,7 +153,6 @@ void *skin_find_item(const char *label, enum skin_find_what what, | |||
158 | struct wps_data *data) | 153 | struct wps_data *data) |
159 | { | 154 | { |
160 | const char *itemlabel = NULL; | 155 | const char *itemlabel = NULL; |
161 | char *old_skin_buffer = skin_buffer; | ||
162 | char *databuf = get_skin_buffer(data); | 156 | char *databuf = get_skin_buffer(data); |
163 | union { | 157 | union { |
164 | struct skin_token_list *linkedlist; | 158 | struct skin_token_list *linkedlist; |
@@ -166,28 +160,28 @@ void *skin_find_item(const char *label, enum skin_find_what what, | |||
166 | } list = {NULL}; | 160 | } list = {NULL}; |
167 | bool isvplist = false; | 161 | bool isvplist = false; |
168 | void *ret = NULL; | 162 | void *ret = NULL; |
169 | if (databuf && databuf != skin_buffer) | 163 | if (!databuf) |
170 | skin_buffer = get_skin_buffer(data); | 164 | databuf = skin_buffer; |
171 | switch (what) | 165 | switch (what) |
172 | { | 166 | { |
173 | case SKIN_FIND_UIVP: | 167 | case SKIN_FIND_UIVP: |
174 | case SKIN_FIND_VP: | 168 | case SKIN_FIND_VP: |
175 | list.vplist = SKINOFFSETTOPTR(skin_buffer, data->tree); | 169 | list.vplist = SKINOFFSETTOPTR(databuf, data->tree); |
176 | isvplist = true; | 170 | isvplist = true; |
177 | break; | 171 | break; |
178 | #ifdef HAVE_LCD_BITMAP | 172 | #ifdef HAVE_LCD_BITMAP |
179 | case SKIN_FIND_IMAGE: | 173 | case SKIN_FIND_IMAGE: |
180 | list.linkedlist = SKINOFFSETTOPTR(skin_buffer, data->images); | 174 | list.linkedlist = SKINOFFSETTOPTR(databuf, data->images); |
181 | break; | 175 | break; |
182 | #endif | 176 | #endif |
183 | #ifdef HAVE_TOUCHSCREEN | 177 | #ifdef HAVE_TOUCHSCREEN |
184 | case SKIN_FIND_TOUCHREGION: | 178 | case SKIN_FIND_TOUCHREGION: |
185 | list.linkedlist = SKINOFFSETTOPTR(skin_buffer, data->touchregions); | 179 | list.linkedlist = SKINOFFSETTOPTR(databuf, data->touchregions); |
186 | break; | 180 | break; |
187 | #endif | 181 | #endif |
188 | #ifdef HAVE_SKIN_VARIABLES | 182 | #ifdef HAVE_SKIN_VARIABLES |
189 | case SKIN_VARIABLE: | 183 | case SKIN_VARIABLE: |
190 | list.linkedlist = SKINOFFSETTOPTR(skin_buffer, data->skinvars); | 184 | list.linkedlist = SKINOFFSETTOPTR(databuf, data->skinvars); |
191 | break; | 185 | break; |
192 | #endif | 186 | #endif |
193 | } | 187 | } |
@@ -198,54 +192,50 @@ void *skin_find_item(const char *label, enum skin_find_what what, | |||
198 | #ifdef HAVE_LCD_BITMAP | 192 | #ifdef HAVE_LCD_BITMAP |
199 | struct wps_token *token = NULL; | 193 | struct wps_token *token = NULL; |
200 | if (!isvplist) | 194 | if (!isvplist) |
201 | token = SKINOFFSETTOPTR(skin_buffer, list.linkedlist->token); | 195 | token = SKINOFFSETTOPTR(databuf, list.linkedlist->token); |
202 | #endif | 196 | #endif |
203 | switch (what) | 197 | switch (what) |
204 | { | 198 | { |
205 | case SKIN_FIND_UIVP: | 199 | case SKIN_FIND_UIVP: |
206 | case SKIN_FIND_VP: | 200 | case SKIN_FIND_VP: |
207 | ret = SKINOFFSETTOPTR(skin_buffer, list.vplist->data); | 201 | ret = SKINOFFSETTOPTR(databuf, list.vplist->data); |
208 | if (((struct skin_viewport *)ret)->label == VP_DEFAULT_LABEL) | 202 | if (((struct skin_viewport *)ret)->label == VP_DEFAULT_LABEL) |
209 | itemlabel = VP_DEFAULT_LABEL_STRING; | 203 | itemlabel = VP_DEFAULT_LABEL_STRING; |
210 | else | 204 | else |
211 | itemlabel = SKINOFFSETTOPTR(skin_buffer, ((struct skin_viewport *)ret)->label); | 205 | itemlabel = SKINOFFSETTOPTR(databuf, ((struct skin_viewport *)ret)->label); |
212 | skip = !(((struct skin_viewport *)ret)->is_infovp == | 206 | skip = !(((struct skin_viewport *)ret)->is_infovp == |
213 | (what==SKIN_FIND_UIVP)); | 207 | (what==SKIN_FIND_UIVP)); |
214 | break; | 208 | break; |
215 | #ifdef HAVE_LCD_BITMAP | 209 | #ifdef HAVE_LCD_BITMAP |
216 | case SKIN_FIND_IMAGE: | 210 | case SKIN_FIND_IMAGE: |
217 | ret = SKINOFFSETTOPTR(skin_buffer, token->value.data); | 211 | ret = SKINOFFSETTOPTR(databuf, token->value.data); |
218 | itemlabel = SKINOFFSETTOPTR(skin_buffer, ((struct gui_img *)ret)->label); | 212 | itemlabel = SKINOFFSETTOPTR(databuf, ((struct gui_img *)ret)->label); |
219 | break; | 213 | break; |
220 | #endif | 214 | #endif |
221 | #ifdef HAVE_TOUCHSCREEN | 215 | #ifdef HAVE_TOUCHSCREEN |
222 | case SKIN_FIND_TOUCHREGION: | 216 | case SKIN_FIND_TOUCHREGION: |
223 | ret = SKINOFFSETTOPTR(skin_buffer, token->value.data); | 217 | ret = SKINOFFSETTOPTR(databuf, token->value.data); |
224 | itemlabel = SKINOFFSETTOPTR(skin_buffer, ((struct touchregion *)ret)->label); | 218 | itemlabel = SKINOFFSETTOPTR(databuf, ((struct touchregion *)ret)->label); |
225 | break; | 219 | break; |
226 | #endif | 220 | #endif |
227 | #ifdef HAVE_SKIN_VARIABLES | 221 | #ifdef HAVE_SKIN_VARIABLES |
228 | case SKIN_VARIABLE: | 222 | case SKIN_VARIABLE: |
229 | ret = SKINOFFSETTOPTR(skin_buffer, token->value.data); | 223 | ret = SKINOFFSETTOPTR(databuf, token->value.data); |
230 | itemlabel = SKINOFFSETTOPTR(skin_buffer, ((struct skin_var *)ret)->label); | 224 | itemlabel = SKINOFFSETTOPTR(databuf, ((struct skin_var *)ret)->label); |
231 | break; | 225 | break; |
232 | #endif | 226 | #endif |
233 | 227 | ||
234 | } | 228 | } |
235 | if (!skip && itemlabel && !strcmp(itemlabel, label)) | 229 | if (!skip && itemlabel && !strcmp(itemlabel, label)) |
236 | { | 230 | { |
237 | if (old_skin_buffer != skin_buffer) | ||
238 | skin_buffer = old_skin_buffer; | ||
239 | return ret; | 231 | return ret; |
240 | } | 232 | } |
241 | 233 | ||
242 | if (isvplist) | 234 | if (isvplist) |
243 | list.vplist = SKINOFFSETTOPTR(skin_buffer, list.vplist->next); | 235 | list.vplist = SKINOFFSETTOPTR(databuf, list.vplist->next); |
244 | else | 236 | else |
245 | list.linkedlist = SKINOFFSETTOPTR(skin_buffer, list.linkedlist->next); | 237 | list.linkedlist = SKINOFFSETTOPTR(databuf, list.linkedlist->next); |
246 | } | 238 | } |
247 | if (old_skin_buffer != skin_buffer) | ||
248 | skin_buffer = old_skin_buffer; | ||
249 | return NULL; | 239 | return NULL; |
250 | } | 240 | } |
251 | 241 | ||
@@ -2330,5 +2320,6 @@ bool skin_data_load(enum screen_type screen, struct wps_data *wps_data, | |||
2330 | #else | 2320 | #else |
2331 | wps_data->wps_loaded = wps_data->tree >= 0; | 2321 | wps_data->wps_loaded = wps_data->tree >= 0; |
2332 | #endif | 2322 | #endif |
2323 | skin_buffer = NULL; | ||
2333 | return true; | 2324 | return true; |
2334 | } | 2325 | } |