summaryrefslogtreecommitdiff
path: root/apps/gui/skin_engine/skin_parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/gui/skin_engine/skin_parser.c')
-rw-r--r--apps/gui/skin_engine/skin_parser.c550
1 files changed, 319 insertions, 231 deletions
diff --git a/apps/gui/skin_engine/skin_parser.c b/apps/gui/skin_engine/skin_parser.c
index 8eef1dedee..ef0f3623e8 100644
--- a/apps/gui/skin_engine/skin_parser.c
+++ b/apps/gui/skin_engine/skin_parser.c
@@ -24,7 +24,9 @@
24#include <string.h> 24#include <string.h>
25#include <stdlib.h> 25#include <stdlib.h>
26#include "config.h" 26#include "config.h"
27#ifndef __PCTOOL__
27#include "core_alloc.h" 28#include "core_alloc.h"
29#endif
28#include "file.h" 30#include "file.h"
29#include "misc.h" 31#include "misc.h"
30#include "plugin.h" 32#include "plugin.h"
@@ -77,12 +79,41 @@
77#define WPS_ERROR_INVALID_PARAM -1 79#define WPS_ERROR_INVALID_PARAM -1
78 80
79#define GLYPHS_TO_CACHE 256 81#define GLYPHS_TO_CACHE 256
82static char* skin_buffer = NULL;
83void 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))
89static char *backdrop_filename;
90#endif
80 91
81static bool isdefault(struct skin_tag_parameter *param) 92static bool isdefault(struct skin_tag_parameter *param)
82{ 93{
83 return param->type == DEFAULT; 94 return param->type == DEFAULT;
84} 95}
85 96
97static inline char*
98get_param_text(struct skin_element *element, int param_number)
99{
100 struct skin_tag_parameter* params = SKINOFFSETTOPTR(skin_buffer, element->params);
101 return SKINOFFSETTOPTR(skin_buffer, params[param_number].data.text);
102}
103
104static inline struct skin_element*
105get_param_code(struct skin_element *element, int param_number)
106{
107 struct skin_tag_parameter* params = SKINOFFSETTOPTR(skin_buffer, element->params);
108 return SKINOFFSETTOPTR(skin_buffer, params[param_number].data.code);
109}
110
111static inline struct skin_tag_parameter*
112get_param(struct skin_element *element, int param_number)
113{
114 struct skin_tag_parameter* params = SKINOFFSETTOPTR(skin_buffer, element->params);
115 return &params[param_number];
116}
86 117
87/* which screen are we parsing for? */ 118/* which screen are we parsing for? */
88static enum screen_type curr_screen; 119static enum screen_type curr_screen;
@@ -90,6 +121,7 @@ static enum screen_type curr_screen;
90/* the current viewport */ 121/* the current viewport */
91static struct skin_element *curr_viewport_element; 122static struct skin_element *curr_viewport_element;
92static struct skin_viewport *curr_vp; 123static struct skin_viewport *curr_vp;
124static struct skin_element *first_viewport;
93 125
94static struct line *curr_line; 126static struct line *curr_line;
95 127
@@ -103,16 +135,19 @@ typedef int (*parse_function)(struct skin_element *element,
103/* add a skin_token_list item to the list chain. ALWAYS appended because some of the 135/* add a skin_token_list item to the list chain. ALWAYS appended because some of the
104 * chains require the order to be kept. 136 * chains require the order to be kept.
105 */ 137 */
106static void add_to_ll_chain(struct skin_token_list **list, struct skin_token_list *item) 138static void add_to_ll_chain(OFFSETTYPE(struct skin_token_list *) *listoffset,
139 struct skin_token_list *item)
107{ 140{
108 if (*list == NULL) 141 struct skin_token_list *list = SKINOFFSETTOPTR(skin_buffer, *listoffset);
109 *list = item; 142 if (list == NULL)
143 {
144 *listoffset = PTRTOSKINOFFSET(skin_buffer, item);
145 }
110 else 146 else
111 { 147 {
112 struct skin_token_list *t = *list; 148 while (SKINOFFSETTOPTR(skin_buffer, list->next))
113 while (t->next) 149 list = SKINOFFSETTOPTR(skin_buffer, list->next);
114 t = t->next; 150 list->next = PTRTOSKINOFFSET(skin_buffer, item);
115 t->next = item;
116 } 151 }
117} 152}
118 153
@@ -123,32 +158,36 @@ void *skin_find_item(const char *label, enum skin_find_what what,
123 struct wps_data *data) 158 struct wps_data *data)
124{ 159{
125 const char *itemlabel = NULL; 160 const char *itemlabel = NULL;
161 char *old_skin_buffer = skin_buffer;
162 char *databuf = get_skin_buffer(data);
126 union { 163 union {
127 struct skin_token_list *linkedlist; 164 struct skin_token_list *linkedlist;
128 struct skin_element *vplist; 165 struct skin_element *vplist;
129 } list = {NULL}; 166 } list = {NULL};
130 bool isvplist = false; 167 bool isvplist = false;
131 void *ret = NULL; 168 void *ret = NULL;
169 if (databuf && databuf != skin_buffer)
170 skin_buffer = get_skin_buffer(data);
132 switch (what) 171 switch (what)
133 { 172 {
134 case SKIN_FIND_UIVP: 173 case SKIN_FIND_UIVP:
135 case SKIN_FIND_VP: 174 case SKIN_FIND_VP:
136 list.vplist = data->tree; 175 list.vplist = SKINOFFSETTOPTR(skin_buffer, data->tree);
137 isvplist = true; 176 isvplist = true;
138 break; 177 break;
139#ifdef HAVE_LCD_BITMAP 178#ifdef HAVE_LCD_BITMAP
140 case SKIN_FIND_IMAGE: 179 case SKIN_FIND_IMAGE:
141 list.linkedlist = data->images; 180 list.linkedlist = SKINOFFSETTOPTR(skin_buffer, data->images);
142 break; 181 break;
143#endif 182#endif
144#ifdef HAVE_TOUCHSCREEN 183#ifdef HAVE_TOUCHSCREEN
145 case SKIN_FIND_TOUCHREGION: 184 case SKIN_FIND_TOUCHREGION:
146 list.linkedlist = data->touchregions; 185 list.linkedlist = SKINOFFSETTOPTR(skin_buffer, data->touchregions);
147 break; 186 break;
148#endif 187#endif
149#ifdef HAVE_SKIN_VARIABLES 188#ifdef HAVE_SKIN_VARIABLES
150 case SKIN_VARIABLE: 189 case SKIN_VARIABLE:
151 list.linkedlist = data->skinvars; 190 list.linkedlist = SKINOFFSETTOPTR(skin_buffer, data->skinvars);
152 break; 191 break;
153#endif 192#endif
154 } 193 }
@@ -156,43 +195,55 @@ void *skin_find_item(const char *label, enum skin_find_what what,
156 while (list.linkedlist) 195 while (list.linkedlist)
157 { 196 {
158 bool skip = false; 197 bool skip = false;
198 struct wps_token *token = NULL;
199 if (!isvplist)
200 token = SKINOFFSETTOPTR(skin_buffer, list.linkedlist->token);
159 switch (what) 201 switch (what)
160 { 202 {
161 case SKIN_FIND_UIVP: 203 case SKIN_FIND_UIVP:
162 case SKIN_FIND_VP: 204 case SKIN_FIND_VP:
163 ret = list.vplist->data; 205 ret = SKINOFFSETTOPTR(skin_buffer, list.vplist->data);
164 itemlabel = ((struct skin_viewport *)ret)->label; 206 if (((struct skin_viewport *)ret)->label == VP_DEFAULT_LABEL)
207 itemlabel = VP_DEFAULT_LABEL_STRING;
208 else
209 itemlabel = SKINOFFSETTOPTR(skin_buffer, ((struct skin_viewport *)ret)->label);
165 skip = !(((struct skin_viewport *)ret)->is_infovp == 210 skip = !(((struct skin_viewport *)ret)->is_infovp ==
166 (what==SKIN_FIND_UIVP)); 211 (what==SKIN_FIND_UIVP));
167 break; 212 break;
168#ifdef HAVE_LCD_BITMAP 213#ifdef HAVE_LCD_BITMAP
169 case SKIN_FIND_IMAGE: 214 case SKIN_FIND_IMAGE:
170 ret = list.linkedlist->token->value.data; 215 ret = SKINOFFSETTOPTR(skin_buffer, token->value.data);
171 itemlabel = ((struct gui_img *)ret)->label; 216 itemlabel = SKINOFFSETTOPTR(skin_buffer, ((struct gui_img *)ret)->label);
172 break; 217 break;
173#endif 218#endif
174#ifdef HAVE_TOUCHSCREEN 219#ifdef HAVE_TOUCHSCREEN
175 case SKIN_FIND_TOUCHREGION: 220 case SKIN_FIND_TOUCHREGION:
176 ret = list.linkedlist->token->value.data; 221 ret = SKINOFFSETTOPTR(skin_buffer, token->value.data);
177 itemlabel = ((struct touchregion *)ret)->label; 222 itemlabel = SKINOFFSETTOPTR(skin_buffer, ((struct touchregion *)ret)->label);
178 break; 223 break;
179#endif 224#endif
180#ifdef HAVE_SKIN_VARIABLES 225#ifdef HAVE_SKIN_VARIABLES
181 case SKIN_VARIABLE: 226 case SKIN_VARIABLE:
182 ret = list.linkedlist->token->value.data; 227 ret = SKINOFFSETTOPTR(skin_buffer, token->value.data);
183 itemlabel = ((struct skin_var *)ret)->label; 228 itemlabel = SKINOFFSETTOPTR(skin_buffer, ((struct skin_var *)ret)->label);
184 break; 229 break;
185#endif 230#endif
186 231
187 } 232 }
188 if (!skip && itemlabel && !strcmp(itemlabel, label)) 233 if (!skip && itemlabel && !strcmp(itemlabel, label))
234 {
235 if (old_skin_buffer != skin_buffer)
236 skin_buffer = old_skin_buffer;
189 return ret; 237 return ret;
238 }
190 239
191 if (isvplist) 240 if (isvplist)
192 list.vplist = list.vplist->next; 241 list.vplist = SKINOFFSETTOPTR(skin_buffer, list.vplist->next);
193 else 242 else
194 list.linkedlist = list.linkedlist->next; 243 list.linkedlist = SKINOFFSETTOPTR(skin_buffer, list.linkedlist->next);
195 } 244 }
245 if (old_skin_buffer != skin_buffer)
246 skin_buffer = old_skin_buffer;
196 return NULL; 247 return NULL;
197} 248}
198 249
@@ -212,10 +263,10 @@ static struct skin_token_list *new_skin_token_list_item(struct wps_token *token,
212 token = (struct wps_token*)skin_buffer_alloc(sizeof(struct wps_token)); 263 token = (struct wps_token*)skin_buffer_alloc(sizeof(struct wps_token));
213 if (!llitem || !token) 264 if (!llitem || !token)
214 return NULL; 265 return NULL;
215 llitem->next = NULL; 266 llitem->next = PTRTOSKINOFFSET(skin_buffer, NULL);
216 llitem->token = token; 267 llitem->token = PTRTOSKINOFFSET(skin_buffer, token);
217 if (token_data) 268 if (token_data)
218 llitem->token->value.data = token_data; 269 token->value.data = PTRTOSKINOFFSET(skin_buffer, token_data);
219 return llitem; 270 return llitem;
220} 271}
221 272
@@ -226,13 +277,12 @@ static int parse_statusbar_tags(struct skin_element* element,
226 (void)element; 277 (void)element;
227 if (token->type == SKIN_TOKEN_DRAW_INBUILTBAR) 278 if (token->type == SKIN_TOKEN_DRAW_INBUILTBAR)
228 { 279 {
229 token->value.data = (void*)&curr_vp->vp; 280 token->value.data = PTRTOSKINOFFSET(skin_buffer, (void*)&curr_vp->vp);
230 } 281 }
231 else 282 else
232 { 283 {
233 struct skin_element *def_vp = wps_data->tree; 284 struct skin_viewport *default_vp = SKINOFFSETTOPTR(skin_buffer, first_viewport->data);
234 struct skin_viewport *default_vp = def_vp->data; 285 if (first_viewport->params_count == 0)
235 if (def_vp->params_count == 0)
236 { 286 {
237 wps_data->wps_sb_tag = true; 287 wps_data->wps_sb_tag = true;
238 wps_data->show_sb_on_wps = (token->type == SKIN_TOKEN_ENABLE_THEME); 288 wps_data->show_sb_on_wps = (token->type == SKIN_TOKEN_ENABLE_THEME);
@@ -279,7 +329,7 @@ static int parse_image_display(struct skin_element *element,
279 struct wps_token *token, 329 struct wps_token *token,
280 struct wps_data *wps_data) 330 struct wps_data *wps_data)
281{ 331{
282 char *label = element->params[0].data.text; 332 char *label = get_param_text(element, 0);
283 char sublabel = '\0'; 333 char sublabel = '\0';
284 int subimage; 334 int subimage;
285 struct gui_img *img; 335 struct gui_img *img;
@@ -297,9 +347,9 @@ static int parse_image_display(struct skin_element *element,
297 { 347 {
298 return WPS_ERROR_INVALID_PARAM; 348 return WPS_ERROR_INVALID_PARAM;
299 } 349 }
300 id->label = label; 350 id->label = img->label;
301 id->offset = 0; 351 id->offset = 0;
302 id->token = NULL; 352 id->token = PTRTOSKINOFFSET(skin_buffer, NULL);
303 if (img->using_preloaded_icons) 353 if (img->using_preloaded_icons)
304 { 354 {
305 token->type = SKIN_TOKEN_IMAGE_DISPLAY_LISTICON; 355 token->type = SKIN_TOKEN_IMAGE_DISPLAY_LISTICON;
@@ -307,13 +357,13 @@ static int parse_image_display(struct skin_element *element,
307 357
308 if (element->params_count > 1) 358 if (element->params_count > 1)
309 { 359 {
310 if (element->params[1].type == CODE) 360 if (get_param(element, 1)->type == CODE)
311 id->token = element->params[1].data.code->data; 361 id->token = get_param_code(element, 1)->data;
312 /* specify a number. 1 being the first subimage (i.e top) NOT 0 */ 362 /* specify a number. 1 being the first subimage (i.e top) NOT 0 */
313 else if (element->params[1].type == INTEGER) 363 else if (get_param(element, 1)->type == INTEGER)
314 id->subimage = element->params[1].data.number - 1; 364 id->subimage = get_param(element, 1)->data.number - 1;
315 if (element->params_count > 2) 365 if (element->params_count > 2)
316 id->offset = element->params[2].data.number; 366 id->offset = get_param(element, 2)->data.number;
317 } 367 }
318 else 368 else
319 { 369 {
@@ -326,7 +376,7 @@ static int parse_image_display(struct skin_element *element,
326 id->subimage = 0; 376 id->subimage = 0;
327 } 377 }
328 } 378 }
329 token->value.data = id; 379 token->value.data = PTRTOSKINOFFSET(skin_buffer, id);
330 return 0; 380 return 0;
331} 381}
332 382
@@ -344,10 +394,10 @@ static int parse_image_load(struct skin_element *element,
344 or %xl(n,filename.bmp,x,y,num_subimages) 394 or %xl(n,filename.bmp,x,y,num_subimages)
345 */ 395 */
346 396
347 id = element->params[0].data.text; 397 id = get_param_text(element, 0);
348 filename = element->params[1].data.text; 398 filename = get_param_text(element, 1);
349 x = element->params[2].data.number; 399 x = get_param(element, 2)->data.number;
350 y = element->params[3].data.number; 400 y = get_param(element, 3)->data.number;
351 401
352 /* check the image number and load state */ 402 /* check the image number and load state */
353 if(skin_find_item(id, SKIN_FIND_IMAGE, wps_data)) 403 if(skin_find_item(id, SKIN_FIND_IMAGE, wps_data))
@@ -360,7 +410,7 @@ static int parse_image_load(struct skin_element *element,
360 return WPS_ERROR_INVALID_PARAM; 410 return WPS_ERROR_INVALID_PARAM;
361 /* save a pointer to the filename */ 411 /* save a pointer to the filename */
362 img->bm.data = (char*)filename; 412 img->bm.data = (char*)filename;
363 img->label = id; 413 img->label = PTRTOSKINOFFSET(skin_buffer, (void*)id);
364 img->x = x; 414 img->x = x;
365 img->y = y; 415 img->y = y;
366 img->num_subimages = 1; 416 img->num_subimages = 1;
@@ -370,7 +420,7 @@ static int parse_image_load(struct skin_element *element,
370 img->buflib_handle = -1; 420 img->buflib_handle = -1;
371 421
372 /* save current viewport */ 422 /* save current viewport */
373 img->vp = &curr_vp->vp; 423 img->vp = PTRTOSKINOFFSET(skin_buffer, &curr_vp->vp);
374 424
375 if (token->type == SKIN_TOKEN_IMAGE_DISPLAY) 425 if (token->type == SKIN_TOKEN_IMAGE_DISPLAY)
376 { 426 {
@@ -378,7 +428,7 @@ static int parse_image_load(struct skin_element *element,
378 } 428 }
379 else if (element->params_count == 5) 429 else if (element->params_count == 5)
380 { 430 {
381 img->num_subimages = element->params[4].data.number; 431 img->num_subimages = get_param(element, 4)->data.number;
382 if (img->num_subimages <= 0) 432 if (img->num_subimages <= 0)
383 return WPS_ERROR_INVALID_PARAM; 433 return WPS_ERROR_INVALID_PARAM;
384 } 434 }
@@ -408,13 +458,13 @@ static int parse_font_load(struct skin_element *element,
408 struct wps_data *wps_data) 458 struct wps_data *wps_data)
409{ 459{
410 (void)wps_data; (void)token; 460 (void)wps_data; (void)token;
411 int id = element->params[0].data.number; 461 int id = get_param(element, 0)->data.number;
412 char *filename = element->params[1].data.text; 462 char *filename = get_param_text(element, 1);
413 int glyphs; 463 int glyphs;
414 char *ptr; 464 char *ptr;
415 465
416 if(element->params_count > 2) 466 if(element->params_count > 2)
417 glyphs = element->params[2].data.number; 467 glyphs = get_param(element, 2)->data.number;
418 else 468 else
419 glyphs = GLYPHS_TO_CACHE; 469 glyphs = GLYPHS_TO_CACHE;
420 if (id < 2) 470 if (id < 2)
@@ -452,12 +502,12 @@ static int parse_playlistview(struct skin_element *element,
452 (struct playlistviewer *)skin_buffer_alloc(sizeof(struct playlistviewer)); 502 (struct playlistviewer *)skin_buffer_alloc(sizeof(struct playlistviewer));
453 if (!viewer) 503 if (!viewer)
454 return WPS_ERROR_INVALID_PARAM; 504 return WPS_ERROR_INVALID_PARAM;
455 viewer->vp = &curr_vp->vp; 505 viewer->vp = PTRTOSKINOFFSET(skin_buffer, &curr_vp->vp);
456 viewer->show_icons = true; 506 viewer->show_icons = true;
457 viewer->start_offset = element->params[0].data.number; 507 viewer->start_offset = get_param(element, 0)->data.number;
458 viewer->line = element->params[1].data.code; 508 viewer->line = PTRTOSKINOFFSET(skin_buffer, get_param_code(element, 1));
459 509
460 token->value.data = (void*)viewer; 510 token->value.data = PTRTOSKINOFFSET(skin_buffer, (void*)viewer);
461 511
462 return 0; 512 return 0;
463} 513}
@@ -474,12 +524,12 @@ static int parse_viewport_gradient_setup(struct skin_element *element,
474 cfg = (struct gradient_config *)skin_buffer_alloc(sizeof(struct gradient_config)); 524 cfg = (struct gradient_config *)skin_buffer_alloc(sizeof(struct gradient_config));
475 if (!cfg) 525 if (!cfg)
476 return 1; 526 return 1;
477 if (!parse_color(curr_screen, element->params[0].data.text, &cfg->start) || 527 if (!parse_color(curr_screen, get_param_text(element, 0), &cfg->start) ||
478 !parse_color(curr_screen, element->params[1].data.text, &cfg->end)) 528 !parse_color(curr_screen, get_param_text(element, 1), &cfg->end))
479 return 1; 529 return 1;
480 if (element->params_count > 2) 530 if (element->params_count > 2)
481 { 531 {
482 if (!parse_color(curr_screen, element->params[2].data.text, &cfg->text)) 532 if (!parse_color(curr_screen, get_param_text(element, 2), &cfg->text))
483 return 1; 533 return 1;
484 } 534 }
485 else 535 else
@@ -487,7 +537,7 @@ static int parse_viewport_gradient_setup(struct skin_element *element,
487 cfg->text = curr_vp->vp.fg_pattern; 537 cfg->text = curr_vp->vp.fg_pattern;
488 } 538 }
489 539
490 token->value.data = cfg; 540 token->value.data = PTRTOSKINOFFSET(skin_buffer, cfg);
491 return 0; 541 return 0;
492} 542}
493#endif 543#endif
@@ -500,14 +550,14 @@ static int parse_listitem(struct skin_element *element,
500 struct listitem *li = (struct listitem *)skin_buffer_alloc(sizeof(struct listitem)); 550 struct listitem *li = (struct listitem *)skin_buffer_alloc(sizeof(struct listitem));
501 if (!li) 551 if (!li)
502 return 1; 552 return 1;
503 token->value.data = li; 553 token->value.data = PTRTOSKINOFFSET(skin_buffer, li);
504 if (element->params_count == 0) 554 if (element->params_count == 0)
505 li->offset = 0; 555 li->offset = 0;
506 else 556 else
507 { 557 {
508 li->offset = element->params[0].data.number; 558 li->offset = get_param(element, 0)->data.number;
509 if (element->params_count > 1) 559 if (element->params_count > 1)
510 li->wrap = strcasecmp(element->params[1].data.text, "nowrap") != 0; 560 li->wrap = strcasecmp(get_param_text(element, 1), "nowrap") != 0;
511 else 561 else
512 li->wrap = true; 562 li->wrap = true;
513 } 563 }
@@ -526,17 +576,17 @@ static int parse_listitemviewport(struct skin_element *element,
526 return -1; 576 return -1;
527 cfg->data = wps_data; 577 cfg->data = wps_data;
528 cfg->tile = false; 578 cfg->tile = false;
529 cfg->label = element->params[0].data.text; 579 cfg->label = get_param_text(element, 0);
530 cfg->width = -1; 580 cfg->width = -1;
531 cfg->height = -1; 581 cfg->height = -1;
532 if (!isdefault(&element->params[1])) 582 if (!isdefault(get_param(element, 1)))
533 cfg->width = element->params[1].data.number; 583 cfg->width = get_param(element, 1)->data.number;
534 if (!isdefault(&element->params[2])) 584 if (!isdefault(get_param(element, 2)))
535 cfg->height = element->params[2].data.number; 585 cfg->height = get_param(element, 2)->data.number;
536 if (element->params_count > 3 && 586 if (element->params_count > 3 &&
537 !strcmp(element->params[3].data.text, "tile")) 587 !strcmp(get_param_text(element, 3), "tile"))
538 cfg->tile = true; 588 cfg->tile = true;
539 token->value.data = (void*)cfg; 589 token->value.data = PTRTOSKINOFFSET(skin_buffer, (void*)cfg);
540#endif 590#endif
541 return 0; 591 return 0;
542} 592}
@@ -548,7 +598,7 @@ static int parse_viewporttextstyle(struct skin_element *element,
548{ 598{
549 (void)wps_data; 599 (void)wps_data;
550 int style; 600 int style;
551 char *mode = element->params[0].data.text; 601 char *mode = get_param_text(element, 0);
552 unsigned colour; 602 unsigned colour;
553 603
554 if (!strcmp(mode, "invert")) 604 if (!strcmp(mode, "invert"))
@@ -558,7 +608,7 @@ static int parse_viewporttextstyle(struct skin_element *element,
558 else if (!strcmp(mode, "colour") || !strcmp(mode, "color")) 608 else if (!strcmp(mode, "colour") || !strcmp(mode, "color"))
559 { 609 {
560 if (element->params_count < 2 || 610 if (element->params_count < 2 ||
561 !parse_color(curr_screen, element->params[1].data.text, &colour)) 611 !parse_color(curr_screen, get_param_text(element, 1), &colour))
562 return 1; 612 return 1;
563 style = STYLE_COLORED|(STYLE_COLOR_MASK&colour); 613 style = STYLE_COLORED|(STYLE_COLOR_MASK&colour);
564 } 614 }
@@ -571,7 +621,7 @@ static int parse_viewporttextstyle(struct skin_element *element,
571 else /* atoi() instead of using a number in the parser is because [si] 621 else /* atoi() instead of using a number in the parser is because [si]
572 * will select the number for something which looks like a colour 622 * will select the number for something which looks like a colour
573 * making the "colour" case (above) harder to parse */ 623 * making the "colour" case (above) harder to parse */
574 num_lines = atoi(element->params[1].data.text); 624 num_lines = atoi(get_param_text(element, 1));
575 style = STYLE_GRADIENT|NUMLN_PACK(num_lines)|CURLN_PACK(0); 625 style = STYLE_GRADIENT|NUMLN_PACK(num_lines)|CURLN_PACK(0);
576 } 626 }
577#endif 627#endif
@@ -590,7 +640,7 @@ static int parse_viewportcolour(struct skin_element *element,
590 struct wps_data *wps_data) 640 struct wps_data *wps_data)
591{ 641{
592 (void)wps_data; 642 (void)wps_data;
593 struct skin_tag_parameter *param = element->params; 643 struct skin_tag_parameter *param = get_param(element, 0);
594 struct viewport_colour *colour = 644 struct viewport_colour *colour =
595 (struct viewport_colour *)skin_buffer_alloc(sizeof(struct viewport_colour)); 645 (struct viewport_colour *)skin_buffer_alloc(sizeof(struct viewport_colour));
596 if (!colour) 646 if (!colour)
@@ -602,11 +652,12 @@ static int parse_viewportcolour(struct skin_element *element,
602 } 652 }
603 else 653 else
604 { 654 {
605 if (!parse_color(curr_screen, param->data.text, &colour->colour)) 655 if (!parse_color(curr_screen, SKINOFFSETTOPTR(skin_buffer, param->data.text),
656 &colour->colour))
606 return -1; 657 return -1;
607 } 658 }
608 colour->vp = &curr_vp->vp; 659 colour->vp = PTRTOSKINOFFSET(skin_buffer, &curr_vp->vp);
609 token->value.data = colour; 660 token->value.data = PTRTOSKINOFFSET(skin_buffer, colour);
610 if (element->line == curr_viewport_element->line) 661 if (element->line == curr_viewport_element->line)
611 { 662 {
612 if (token->type == SKIN_TOKEN_VIEWPORT_FGCOLOUR) 663 if (token->type == SKIN_TOKEN_VIEWPORT_FGCOLOUR)
@@ -634,18 +685,18 @@ static int parse_image_special(struct skin_element *element,
634 char *filename; 685 char *filename;
635 if (token->type == SKIN_TOKEN_IMAGE_BACKDROP) 686 if (token->type == SKIN_TOKEN_IMAGE_BACKDROP)
636 { 687 {
637 if (isdefault(&element->params[0])) 688 if (isdefault(get_param(element, 0)))
638 { 689 {
639 filename = "-"; 690 filename = "-";
640 } 691 }
641 else 692 else
642 { 693 {
643 filename = element->params[0].data.text; 694 filename = get_param_text(element, 0);
644 /* format: %X(filename.bmp) or %X(d) */ 695 /* format: %X(filename.bmp) or %X(d) */
645 if (!strcmp(filename, "d")) 696 if (!strcmp(filename, "d"))
646 filename = NULL; 697 filename = NULL;
647 } 698 }
648 wps_data->backdrop = filename; 699 backdrop_filename = filename;
649 } 700 }
650#endif 701#endif
651 702
@@ -665,7 +716,7 @@ static int parse_setting_and_lang(struct skin_element *element,
665 * If that ever changes remove the #ifndef __PCTOOL__'s here 716 * If that ever changes remove the #ifndef __PCTOOL__'s here
666 */ 717 */
667 (void)wps_data; 718 (void)wps_data;
668 char *temp = element->params[0].data.text; 719 char *temp = get_param_text(element, 0);
669 int i; 720 int i;
670 721
671 if (token->type == SKIN_TOKEN_TRANSLATEDSTRING) 722 if (token->type == SKIN_TOKEN_TRANSLATEDSTRING)
@@ -692,12 +743,12 @@ static int parse_logical_if(struct skin_element *element,
692 struct wps_data *wps_data) 743 struct wps_data *wps_data)
693{ 744{
694 (void)wps_data; 745 (void)wps_data;
695 char *op = element->params[1].data.text; 746 char *op = get_param_text(element, 1);
696 struct logical_if *lif = skin_buffer_alloc(sizeof(struct logical_if)); 747 struct logical_if *lif = skin_buffer_alloc(sizeof(struct logical_if));
697 if (!lif) 748 if (!lif)
698 return -1; 749 return -1;
699 token->value.data = lif; 750 token->value.data = PTRTOSKINOFFSET(skin_buffer, lif);
700 lif->token = element->params[0].data.code->data; 751 lif->token = get_param_code(element, 0)->data;
701 752
702 if (!strncmp(op, "=", 1)) 753 if (!strncmp(op, "=", 1))
703 lif->op = IF_EQUALS; 754 lif->op = IF_EQUALS;
@@ -712,9 +763,9 @@ static int parse_logical_if(struct skin_element *element,
712 else if (!strncmp(op, "<", 1)) 763 else if (!strncmp(op, "<", 1))
713 lif->op = IF_LESSTHAN; 764 lif->op = IF_LESSTHAN;
714 765
715 memcpy(&lif->operand, &element->params[2], sizeof(lif->operand)); 766 memcpy(&lif->operand, get_param(element, 2), sizeof(lif->operand));
716 if (element->params_count > 3) 767 if (element->params_count > 3)
717 lif->num_options = element->params[3].data.number; 768 lif->num_options = get_param(element, 3)->data.number;
718 else 769 else
719 lif->num_options = TOKEN_VALUE_ONLY; 770 lif->num_options = TOKEN_VALUE_ONLY;
720 return 0; 771 return 0;
@@ -743,7 +794,7 @@ static int parse_timeout_tag(struct skin_element *element,
743 } 794 }
744 } 795 }
745 else 796 else
746 val = element->params[0].data.number; 797 val = get_param(element, 0)->data.number;
747 token->value.i = val * TIMEOUT_UNIT; 798 token->value.i = val * TIMEOUT_UNIT;
748 return 0; 799 return 0;
749} 800}
@@ -756,13 +807,13 @@ static int parse_substring_tag(struct skin_element* element,
756 struct substring *ss = (struct substring*)skin_buffer_alloc(sizeof(struct substring)); 807 struct substring *ss = (struct substring*)skin_buffer_alloc(sizeof(struct substring));
757 if (!ss) 808 if (!ss)
758 return 1; 809 return 1;
759 ss->start = element->params[0].data.number; 810 ss->start = get_param(element, 0)->data.number;
760 if (element->params[1].type == DEFAULT) 811 if (get_param(element, 1)->type == DEFAULT)
761 ss->length = -1; 812 ss->length = -1;
762 else 813 else
763 ss->length = element->params[1].data.number; 814 ss->length = get_param(element, 1)->data.number;
764 ss->token = element->params[2].data.code->data; 815 ss->token = get_param_code(element, 2)->data;
765 token->value.data = ss; 816 token->value.data = PTRTOSKINOFFSET(skin_buffer, ss);
766 return 0; 817 return 0;
767} 818}
768 819
@@ -773,7 +824,7 @@ static int parse_progressbar_tag(struct skin_element* element,
773#ifdef HAVE_LCD_BITMAP 824#ifdef HAVE_LCD_BITMAP
774 struct progressbar *pb; 825 struct progressbar *pb;
775 struct viewport *vp = &curr_vp->vp; 826 struct viewport *vp = &curr_vp->vp;
776 struct skin_tag_parameter *param = element->params; 827 struct skin_tag_parameter *param = get_param(element, 0);
777 int curr_param = 0; 828 int curr_param = 0;
778 char *image_filename = NULL; 829 char *image_filename = NULL;
779 830
@@ -782,17 +833,17 @@ static int parse_progressbar_tag(struct skin_element* element,
782 return 0; /* nothing to do */ 833 return 0; /* nothing to do */
783 pb = (struct progressbar*)skin_buffer_alloc(sizeof(struct progressbar)); 834 pb = (struct progressbar*)skin_buffer_alloc(sizeof(struct progressbar));
784 835
785 token->value.data = pb; 836 token->value.data = PTRTOSKINOFFSET(skin_buffer, pb);
786 837
787 if (!pb) 838 if (!pb)
788 return WPS_ERROR_INVALID_PARAM; 839 return WPS_ERROR_INVALID_PARAM;
789 pb->vp = vp; 840 pb->vp = PTRTOSKINOFFSET(skin_buffer, vp);
790 pb->follow_lang_direction = follow_lang_direction > 0; 841 pb->follow_lang_direction = follow_lang_direction > 0;
791 pb->nofill = false; 842 pb->nofill = false;
792 pb->nobar = false; 843 pb->nobar = false;
793 pb->image = NULL; 844 pb->image = PTRTOSKINOFFSET(skin_buffer, NULL);
794 pb->slider = NULL; 845 pb->slider = PTRTOSKINOFFSET(skin_buffer, NULL);
795 pb->backdrop = NULL; 846 pb->backdrop = PTRTOSKINOFFSET(skin_buffer, NULL);
796 pb->invert_fill_direction = false; 847 pb->invert_fill_direction = false;
797 pb->horizontal = true; 848 pb->horizontal = true;
798 849
@@ -849,7 +900,7 @@ static int parse_progressbar_tag(struct skin_element* element,
849 /* optional params, first is the image filename if it isnt recognised as a keyword */ 900 /* optional params, first is the image filename if it isnt recognised as a keyword */
850 901
851 curr_param = 4; 902 curr_param = 4;
852 if (isdefault(&element->params[curr_param])) 903 if (isdefault(get_param(element, curr_param)))
853 { 904 {
854 param++; 905 param++;
855 curr_param++; 906 curr_param++;
@@ -858,75 +909,79 @@ static int parse_progressbar_tag(struct skin_element* element,
858 pb->horizontal = pb->width > pb->height; 909 pb->horizontal = pb->width > pb->height;
859 while (curr_param < element->params_count) 910 while (curr_param < element->params_count)
860 { 911 {
912 char* text;
861 param++; 913 param++;
862 if (!strcmp(param->data.text, "invert")) 914 text = SKINOFFSETTOPTR(skin_buffer, param->data.text);
915 if (!strcmp(text, "invert"))
863 pb->invert_fill_direction = true; 916 pb->invert_fill_direction = true;
864 else if (!strcmp(param->data.text, "nofill")) 917 else if (!strcmp(text, "nofill"))
865 pb->nofill = true; 918 pb->nofill = true;
866 else if (!strcmp(param->data.text, "nobar")) 919 else if (!strcmp(text, "nobar"))
867 pb->nobar = true; 920 pb->nobar = true;
868 else if (!strcmp(param->data.text, "slider")) 921 else if (!strcmp(text, "slider"))
869 { 922 {
870 if (curr_param+1 < element->params_count) 923 if (curr_param+1 < element->params_count)
871 { 924 {
872 curr_param++; 925 curr_param++;
873 param++; 926 param++;
874 pb->slider = skin_find_item(param->data.text, 927 text = SKINOFFSETTOPTR(skin_buffer, param->data.text);
875 SKIN_FIND_IMAGE, wps_data); 928 pb->slider = PTRTOSKINOFFSET(skin_buffer,
929 skin_find_item(text, SKIN_FIND_IMAGE, wps_data));
876 } 930 }
877 else /* option needs the next param */ 931 else /* option needs the next param */
878 return -1; 932 return -1;
879 } 933 }
880 else if (!strcmp(param->data.text, "image")) 934 else if (!strcmp(text, "image"))
881 { 935 {
882 if (curr_param+1 < element->params_count) 936 if (curr_param+1 < element->params_count)
883 { 937 {
884 curr_param++; 938 curr_param++;
885 param++; 939 param++;
886 image_filename = param->data.text; 940 image_filename = SKINOFFSETTOPTR(skin_buffer, param->data.text);
887
888 } 941 }
889 else /* option needs the next param */ 942 else /* option needs the next param */
890 return -1; 943 return -1;
891 } 944 }
892 else if (!strcmp(param->data.text, "backdrop")) 945 else if (!strcmp(text, "backdrop"))
893 { 946 {
894 if (curr_param+1 < element->params_count) 947 if (curr_param+1 < element->params_count)
895 { 948 {
896 curr_param++; 949 curr_param++;
897 param++; 950 param++;
898 pb->backdrop = skin_find_item(param->data.text, 951 text = SKINOFFSETTOPTR(skin_buffer, param->data.text);
899 SKIN_FIND_IMAGE, wps_data); 952 pb->backdrop = PTRTOSKINOFFSET(skin_buffer,
953 skin_find_item(text, SKIN_FIND_IMAGE, wps_data));
900 954
901 } 955 }
902 else /* option needs the next param */ 956 else /* option needs the next param */
903 return -1; 957 return -1;
904 } 958 }
905 else if (!strcmp(param->data.text, "vertical")) 959 else if (!strcmp(text, "vertical"))
906 { 960 {
907 pb->horizontal = false; 961 pb->horizontal = false;
908 if (isdefault(&element->params[3])) 962 if (isdefault(get_param(element, 3)))
909 pb->height = vp->height - pb->y; 963 pb->height = vp->height - pb->y;
910 } 964 }
911 else if (!strcmp(param->data.text, "horizontal")) 965 else if (!strcmp(text, "horizontal"))
912 pb->horizontal = true; 966 pb->horizontal = true;
913 else if (curr_param == 4) 967 else if (curr_param == 4)
914 image_filename = param->data.text; 968 image_filename = text;
915 969
916 curr_param++; 970 curr_param++;
917 } 971 }
918 972
919 if (image_filename) 973 if (image_filename)
920 { 974 {
921 pb->image = skin_find_item(image_filename, SKIN_FIND_IMAGE, wps_data); 975 pb->image = PTRTOSKINOFFSET(skin_buffer,
922 if (!pb->image) /* load later */ 976 skin_find_item(image_filename, SKIN_FIND_IMAGE, wps_data));
977 if (!SKINOFFSETTOPTR(skin_buffer, pb->image)) /* load later */
923 { 978 {
924 struct gui_img* img = (struct gui_img*)skin_buffer_alloc(sizeof(struct gui_img)); 979 struct gui_img* img = (struct gui_img*)skin_buffer_alloc(sizeof(struct gui_img));
925 if (!img) 980 if (!img)
926 return WPS_ERROR_INVALID_PARAM; 981 return WPS_ERROR_INVALID_PARAM;
927 /* save a pointer to the filename */ 982 /* save a pointer to the filename */
928 img->bm.data = (char*)image_filename; 983 img->bm.data = (char*)image_filename;
929 img->label = image_filename; 984 img->label = PTRTOSKINOFFSET(skin_buffer, image_filename);
930 img->x = 0; 985 img->x = 0;
931 img->y = 0; 986 img->y = 0;
932 img->num_subimages = 1; 987 img->num_subimages = 1;
@@ -934,13 +989,13 @@ static int parse_progressbar_tag(struct skin_element* element,
934 img->display = -1; 989 img->display = -1;
935 img->using_preloaded_icons = false; 990 img->using_preloaded_icons = false;
936 img->buflib_handle = -1; 991 img->buflib_handle = -1;
937 img->vp = &curr_vp->vp; 992 img->vp = PTRTOSKINOFFSET(skin_buffer, &curr_vp->vp);
938 struct skin_token_list *item = 993 struct skin_token_list *item =
939 (struct skin_token_list *)new_skin_token_list_item(NULL, img); 994 (struct skin_token_list *)new_skin_token_list_item(NULL, img);
940 if (!item) 995 if (!item)
941 return WPS_ERROR_INVALID_PARAM; 996 return WPS_ERROR_INVALID_PARAM;
942 add_to_ll_chain(&wps_data->images, item); 997 add_to_ll_chain(&wps_data->images, item);
943 pb->image = img; 998 pb->image = PTRTOSKINOFFSET(skin_buffer, img);
944 } 999 }
945 } 1000 }
946 1001
@@ -993,12 +1048,12 @@ static int parse_albumart_load(struct skin_element* element,
993 aa->xalign = WPS_ALBUMART_ALIGN_CENTER; /* default */ 1048 aa->xalign = WPS_ALBUMART_ALIGN_CENTER; /* default */
994 aa->yalign = WPS_ALBUMART_ALIGN_CENTER; /* default */ 1049 aa->yalign = WPS_ALBUMART_ALIGN_CENTER; /* default */
995 1050
996 aa->x = element->params[0].data.number; 1051 aa->x = get_param(element, 0)->data.number;
997 aa->y = element->params[1].data.number; 1052 aa->y = get_param(element, 1)->data.number;
998 aa->width = element->params[2].data.number; 1053 aa->width = get_param(element, 2)->data.number;
999 aa->height = element->params[3].data.number; 1054 aa->height = get_param(element, 3)->data.number;
1000 1055
1001 aa->vp = &curr_vp->vp; 1056 aa->vp = PTRTOSKINOFFSET(skin_buffer, &curr_vp->vp);
1002 aa->draw_handle = -1; 1057 aa->draw_handle = -1;
1003 1058
1004 /* if we got here, we parsed everything ok .. ! */ 1059 /* if we got here, we parsed everything ok .. ! */
@@ -1016,7 +1071,7 @@ static int parse_albumart_load(struct skin_element* element,
1016 aa->x = LCD_WIDTH - (aa->x + aa->width); 1071 aa->x = LCD_WIDTH - (aa->x + aa->width);
1017 1072
1018 aa->state = WPS_ALBUMART_LOAD; 1073 aa->state = WPS_ALBUMART_LOAD;
1019 wps_data->albumart = aa; 1074 wps_data->albumart = PTRTOSKINOFFSET(skin_buffer, aa);
1020 1075
1021 dimensions.width = aa->width; 1076 dimensions.width = aa->width;
1022 dimensions.height = aa->height; 1077 dimensions.height = aa->height;
@@ -1026,9 +1081,9 @@ static int parse_albumart_load(struct skin_element* element,
1026 if (0 <= albumart_slot) 1081 if (0 <= albumart_slot)
1027 wps_data->playback_aa_slot = albumart_slot; 1082 wps_data->playback_aa_slot = albumart_slot;
1028 1083
1029 if (element->params_count > 4 && !isdefault(&element->params[4])) 1084 if (element->params_count > 4 && !isdefault(get_param(element, 4)))
1030 { 1085 {
1031 switch (*element->params[4].data.text) 1086 switch (*get_param_text(element, 4))
1032 { 1087 {
1033 case 'l': 1088 case 'l':
1034 case 'L': 1089 case 'L':
@@ -1050,9 +1105,9 @@ static int parse_albumart_load(struct skin_element* element,
1050 break; 1105 break;
1051 } 1106 }
1052 } 1107 }
1053 if (element->params_count > 5 && !isdefault(&element->params[5])) 1108 if (element->params_count > 5 && !isdefault(get_param(element, 5)))
1054 { 1109 {
1055 switch (*element->params[5].data.text) 1110 switch (*get_param_text(element, 5))
1056 { 1111 {
1057 case 't': 1112 case 't':
1058 case 'T': 1113 case 'T':
@@ -1082,7 +1137,7 @@ static struct skin_var* find_or_add_var(const char* label,
1082 ret = (struct skin_var*)skin_buffer_alloc(sizeof(struct skin_var)); 1137 ret = (struct skin_var*)skin_buffer_alloc(sizeof(struct skin_var));
1083 if (!ret) 1138 if (!ret)
1084 return NULL; 1139 return NULL;
1085 ret->label = label; 1140 ret->label = PTRTOSKINOFFSET(skin_buffer, label);
1086 ret->value = 1; 1141 ret->value = 1;
1087 ret->last_changed = 0xffff; 1142 ret->last_changed = 0xffff;
1088 struct skin_token_list *item = new_skin_token_list_item(NULL, ret); 1143 struct skin_token_list *item = new_skin_token_list_item(NULL, ret);
@@ -1096,14 +1151,14 @@ static int parse_skinvar( struct skin_element *element,
1096 struct wps_token *token, 1151 struct wps_token *token,
1097 struct wps_data *wps_data) 1152 struct wps_data *wps_data)
1098{ 1153{
1099 const char* label = element->params[0].data.text; 1154 const char* label = get_param_text(element, 0);
1100 struct skin_var* var = find_or_add_var(label, wps_data); 1155 struct skin_var* var = find_or_add_var(label, wps_data);
1101 if (!var) 1156 if (!var)
1102 return WPS_ERROR_INVALID_PARAM; 1157 return WPS_ERROR_INVALID_PARAM;
1103 switch (token->type) 1158 switch (token->type)
1104 { 1159 {
1105 case SKIN_TOKEN_VAR_GETVAL: 1160 case SKIN_TOKEN_VAR_GETVAL:
1106 token->value.data = var; 1161 token->value.data = PTRTOSKINOFFSET(skin_buffer, var);
1107 break; 1162 break;
1108 case SKIN_TOKEN_VAR_SET: 1163 case SKIN_TOKEN_VAR_SET:
1109 { 1164 {
@@ -1112,23 +1167,23 @@ static int parse_skinvar( struct skin_element *element,
1112 sizeof(struct skin_var_changer)); 1167 sizeof(struct skin_var_changer));
1113 if (!data) 1168 if (!data)
1114 return WPS_ERROR_INVALID_PARAM; 1169 return WPS_ERROR_INVALID_PARAM;
1115 data->var = var; 1170 data->var = PTRTOSKINOFFSET(skin_buffer, var);
1116 data->newval = element->params[2].data.number; 1171 data->newval = get_param(element, 2)->data.number;
1117 data->max = 0; 1172 data->max = 0;
1118 if (!strcmp(element->params[1].data.text, "set")) 1173 if (!strcmp(get_param_text(element, 1), "set"))
1119 data->direct = true; 1174 data->direct = true;
1120 else if (!strcmp(element->params[1].data.text, "inc")) 1175 else if (!strcmp(get_param_text(element, 1), "inc"))
1121 { 1176 {
1122 data->direct = false; 1177 data->direct = false;
1123 } 1178 }
1124 else if (!strcmp(element->params[1].data.text, "dec")) 1179 else if (!strcmp(get_param_text(element, 1), "dec"))
1125 { 1180 {
1126 data->direct = false; 1181 data->direct = false;
1127 data->newval *= -1; 1182 data->newval *= -1;
1128 } 1183 }
1129 if (element->params_count > 3) 1184 if (element->params_count > 3)
1130 data->max = element->params[3].data.number; 1185 data->max = get_param(element, 3)->data.number;
1131 token->value.data = data; 1186 token->value.data = PTRTOSKINOFFSET(skin_buffer, data);
1132 } 1187 }
1133 break; 1188 break;
1134 case SKIN_TOKEN_VAR_TIMEOUT: 1189 case SKIN_TOKEN_VAR_TIMEOUT:
@@ -1138,12 +1193,12 @@ static int parse_skinvar( struct skin_element *element,
1138 sizeof(struct skin_var_lastchange)); 1193 sizeof(struct skin_var_lastchange));
1139 if (!data) 1194 if (!data)
1140 return WPS_ERROR_INVALID_PARAM; 1195 return WPS_ERROR_INVALID_PARAM;
1141 data->var = var; 1196 data->var = PTRTOSKINOFFSET(skin_buffer, var);
1142 data->timeout = 10; 1197 data->timeout = 10;
1143 if (element->params_count > 1) 1198 if (element->params_count > 1)
1144 data->timeout = element->params[1].data.number; 1199 data->timeout = get_param(element, 1)->data.number;
1145 data->timeout *= TIMEOUT_UNIT; 1200 data->timeout *= TIMEOUT_UNIT;
1146 token->value.data = data; 1201 token->value.data = PTRTOSKINOFFSET(skin_buffer, data);
1147 } 1202 }
1148 break; 1203 break;
1149 default: /* kill the warning */ 1204 default: /* kill the warning */
@@ -1161,23 +1216,25 @@ static int parse_lasttouch(struct skin_element *element,
1161 (struct touchregion_lastpress*)skin_buffer_alloc( 1216 (struct touchregion_lastpress*)skin_buffer_alloc(
1162 sizeof(struct touchregion_lastpress)); 1217 sizeof(struct touchregion_lastpress));
1163 int i; 1218 int i;
1219 struct touchregion *region = NULL;
1164 if (!data) 1220 if (!data)
1165 return WPS_ERROR_INVALID_PARAM; 1221 return WPS_ERROR_INVALID_PARAM;
1166 data->region = NULL; 1222
1167 data->timeout = 10; 1223 data->timeout = 10;
1168 1224
1169 for (i=0; i<element->params_count; i++) 1225 for (i=0; i<element->params_count; i++)
1170 { 1226 {
1171 if (element->params[i].type == STRING) 1227 if (get_param(element, i)->type == STRING)
1172 data->region = skin_find_item(element->params[i].data.text, 1228 region = skin_find_item(get_param_text(element, i),
1173 SKIN_FIND_TOUCHREGION, wps_data); 1229 SKIN_FIND_TOUCHREGION, wps_data);
1174 else if (element->params[i].type == INTEGER || 1230 else if (get_param(element, i)->type == INTEGER ||
1175 element->params[i].type == DECIMAL) 1231 get_param(element, i)->type == DECIMAL)
1176 data->timeout = element->params[i].data.number; 1232 data->timeout = get_param(element, i)->data.number;
1177 } 1233 }
1178 1234
1235 data->region = PTRTOSKINOFFSET(skin_buffer, region);
1179 data->timeout *= TIMEOUT_UNIT; 1236 data->timeout *= TIMEOUT_UNIT;
1180 token->value.data = data; 1237 token->value.data = PTRTOSKINOFFSET(skin_buffer, data);
1181 return 0; 1238 return 0;
1182} 1239}
1183 1240
@@ -1221,7 +1278,7 @@ static int touchregion_setup_setting(struct skin_element *element, int param_no,
1221{ 1278{
1222#ifndef __PCTOOL__ 1279#ifndef __PCTOOL__
1223 int p = param_no; 1280 int p = param_no;
1224 char *name = element->params[p++].data.text; 1281 char *name = get_param_text(element, p++);
1225 int j; 1282 int j;
1226 1283
1227 region->setting_data.setting = find_setting_by_cfgname(name, &j); 1284 region->setting_data.setting = find_setting_by_cfgname(name, &j);
@@ -1237,11 +1294,11 @@ static int touchregion_setup_setting(struct skin_element *element, int param_no,
1237 if (element->params_count < p+1) 1294 if (element->params_count < p+1)
1238 return -1; 1295 return -1;
1239 1296
1240 text = element->params[p++].data.text; 1297 text = get_param_text(element, p++);
1241 switch (settings[j].flags&F_T_MASK) 1298 switch (settings[j].flags&F_T_MASK)
1242 { 1299 {
1243 case F_T_CUSTOM: 1300 case F_T_CUSTOM:
1244 setting->value.text = text; 1301 setting->value.text = PTRTOSKINOFFSET(skin_buffer, text);
1245 break; 1302 break;
1246 case F_T_INT: 1303 case F_T_INT:
1247 case F_T_UINT: 1304 case F_T_UINT:
@@ -1301,34 +1358,34 @@ static int parse_touchregion(struct skin_element *element,
1301 /* should probably do some bounds checking here with the viewport... but later */ 1358 /* should probably do some bounds checking here with the viewport... but later */
1302 region->action = ACTION_NONE; 1359 region->action = ACTION_NONE;
1303 1360
1304 if (element->params[0].type == STRING) 1361 if (get_param(element, 0)->type == STRING)
1305 { 1362 {
1306 region->label = element->params[0].data.text; 1363 region->label = PTRTOSKINOFFSET(skin_buffer, get_param_text(element, 0));
1307 p = 1; 1364 p = 1;
1308 /* "[SI]III[SI]|SS" is the param list. There MUST be 4 numbers 1365 /* "[SI]III[SI]|SS" is the param list. There MUST be 4 numbers
1309 * followed by at least one string. Verify that here */ 1366 * followed by at least one string. Verify that here */
1310 if (element->params_count < 6 || 1367 if (element->params_count < 6 ||
1311 element->params[4].type != INTEGER) 1368 get_param(element, 4)->type != INTEGER)
1312 return WPS_ERROR_INVALID_PARAM; 1369 return WPS_ERROR_INVALID_PARAM;
1313 } 1370 }
1314 else 1371 else
1315 { 1372 {
1316 region->label = NULL; 1373 region->label = PTRTOSKINOFFSET(skin_buffer, NULL);
1317 p = 0; 1374 p = 0;
1318 } 1375 }
1319 1376
1320 region->x = element->params[p++].data.number; 1377 region->x = get_param(element, p++)->data.number;
1321 region->y = element->params[p++].data.number; 1378 region->y = get_param(element, p++)->data.number;
1322 region->width = element->params[p++].data.number; 1379 region->width = get_param(element, p++)->data.number;
1323 region->height = element->params[p++].data.number; 1380 region->height = get_param(element, p++)->data.number;
1324 region->wvp = curr_vp; 1381 region->wvp = PTRTOSKINOFFSET(skin_buffer, curr_vp);
1325 region->armed = false; 1382 region->armed = false;
1326 region->reverse_bar = false; 1383 region->reverse_bar = false;
1327 region->value = 0; 1384 region->value = 0;
1328 region->last_press = 0xffff; 1385 region->last_press = 0xffff;
1329 region->press_length = PRESS; 1386 region->press_length = PRESS;
1330 region->allow_while_locked = false; 1387 region->allow_while_locked = false;
1331 action = element->params[p++].data.text; 1388 action = get_param_text(element, p++);
1332 1389
1333 /* figure out the action */ 1390 /* figure out the action */
1334 if(!strcmp(pb_string, action)) 1391 if(!strcmp(pb_string, action))
@@ -1364,7 +1421,7 @@ static int parse_touchregion(struct skin_element *element,
1364 } 1421 }
1365 while (p < element->params_count) 1422 while (p < element->params_count)
1366 { 1423 {
1367 char* param = element->params[p++].data.text; 1424 char* param = get_param_text(element, p++);
1368 if (!strcmp(param, "allow_while_locked")) 1425 if (!strcmp(param, "allow_while_locked"))
1369 region->allow_while_locked = true; 1426 region->allow_while_locked = true;
1370 else if (!strcmp(param, "reverse_bar")) 1427 else if (!strcmp(param, "reverse_bar"))
@@ -1438,24 +1495,30 @@ static bool check_feature_tag(const int type)
1438 */ 1495 */
1439void skin_data_free_buflib_allocs(struct wps_data *wps_data) 1496void skin_data_free_buflib_allocs(struct wps_data *wps_data)
1440{ 1497{
1441 (void)wps_data; 1498 if (wps_data->wps_loaded)
1499 skin_buffer = get_skin_buffer(wps_data);
1442#ifdef HAVE_LCD_BITMAP 1500#ifdef HAVE_LCD_BITMAP
1443#ifndef __PCTOOL__ 1501#ifndef __PCTOOL__
1444 struct skin_token_list *list = wps_data->images; 1502 struct skin_token_list *list = SKINOFFSETTOPTR(skin_buffer, wps_data->images);
1503 int *font_ids = SKINOFFSETTOPTR(skin_buffer, wps_data->font_ids);
1445 while (list) 1504 while (list)
1446 { 1505 {
1447 struct gui_img *img = (struct gui_img*)list->token->value.data; 1506 struct wps_token *token = SKINOFFSETTOPTR(skin_buffer, list->token);
1507 struct gui_img *img = (struct gui_img*)SKINOFFSETTOPTR(skin_buffer, token->value.data);
1448 if (img->buflib_handle > 0) 1508 if (img->buflib_handle > 0)
1449 core_free(img->buflib_handle); 1509 core_free(img->buflib_handle);
1450 list = list->next; 1510 list = SKINOFFSETTOPTR(skin_buffer, list->next);
1451 } 1511 }
1452 wps_data->images = NULL; 1512 wps_data->images = PTRTOSKINOFFSET(skin_buffer, NULL);
1453 if (wps_data->font_ids != NULL) 1513 if (font_ids != NULL)
1454 { 1514 {
1455 while (wps_data->font_count > 0) 1515 while (wps_data->font_count > 0)
1456 font_unload(wps_data->font_ids[--wps_data->font_count]); 1516 font_unload(font_ids[--wps_data->font_count]);
1457 } 1517 }
1458 wps_data->font_ids = NULL; 1518 wps_data->font_ids = PTRTOSKINOFFSET(skin_buffer, NULL);
1519 if (wps_data->buflib_handle > 0)
1520 core_free(wps_data->buflib_handle);
1521 wps_data->buflib_handle = -1;
1459#endif 1522#endif
1460#endif 1523#endif
1461} 1524}
@@ -1469,22 +1532,22 @@ static void skin_data_reset(struct wps_data *wps_data)
1469{ 1532{
1470 skin_data_free_buflib_allocs(wps_data); 1533 skin_data_free_buflib_allocs(wps_data);
1471#ifdef HAVE_LCD_BITMAP 1534#ifdef HAVE_LCD_BITMAP
1472 wps_data->images = NULL; 1535 wps_data->images = INVALID_OFFSET;
1473#endif 1536#endif
1474 wps_data->tree = NULL; 1537 wps_data->tree = INVALID_OFFSET;
1475#if LCD_DEPTH > 1 || defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1 1538#if LCD_DEPTH > 1 || defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1
1476 if (wps_data->backdrop_id >= 0) 1539 if (wps_data->backdrop_id >= 0)
1477 skin_backdrop_unload(wps_data->backdrop_id); 1540 skin_backdrop_unload(wps_data->backdrop_id);
1478 wps_data->backdrop = NULL; 1541 backdrop_filename = NULL;
1479#endif 1542#endif
1480#ifdef HAVE_TOUCHSCREEN 1543#ifdef HAVE_TOUCHSCREEN
1481 wps_data->touchregions = NULL; 1544 wps_data->touchregions = INVALID_OFFSET;
1482#endif 1545#endif
1483#ifdef HAVE_SKIN_VARIABLES 1546#ifdef HAVE_SKIN_VARIABLES
1484 wps_data->skinvars = NULL; 1547 wps_data->skinvars = INVALID_OFFSET;
1485#endif 1548#endif
1486#ifdef HAVE_ALBUMART 1549#ifdef HAVE_ALBUMART
1487 wps_data->albumart = NULL; 1550 wps_data->albumart = INVALID_OFFSET;
1488 if (wps_data->playback_aa_slot >= 0) 1551 if (wps_data->playback_aa_slot >= 0)
1489 { 1552 {
1490 playback_release_aa_slot(wps_data->playback_aa_slot); 1553 playback_release_aa_slot(wps_data->playback_aa_slot);
@@ -1560,10 +1623,8 @@ static int load_skin_bmp(struct wps_data *wps_data, struct bitmap *bitmap, char*
1560 handle = core_alloc_ex(bitmap->data, buf_size, &buflib_ops); 1623 handle = core_alloc_ex(bitmap->data, buf_size, &buflib_ops);
1561 if (handle < 0) 1624 if (handle < 0)
1562 { 1625 {
1563#ifndef APPLICATION
1564 DEBUGF("Not enough skin buffer: need %zd more.\n", 1626 DEBUGF("Not enough skin buffer: need %zd more.\n",
1565 buf_size - skin_buffer_freespace()); 1627 buf_size - skin_buffer_freespace());
1566#endif
1567 close(fd); 1628 close(fd);
1568 return handle; 1629 return handle;
1569 } 1630 }
@@ -1600,16 +1661,17 @@ static bool load_skin_bitmaps(struct wps_data *wps_data, char *bmpdir)
1600 bool retval = true; /* return false if a single image failed to load */ 1661 bool retval = true; /* return false if a single image failed to load */
1601 1662
1602 /* regular images */ 1663 /* regular images */
1603 list = wps_data->images; 1664 list = SKINOFFSETTOPTR(skin_buffer, wps_data->images);
1604 while (list) 1665 while (list)
1605 { 1666 {
1606 struct gui_img *img = (struct gui_img*)list->token->value.data; 1667 struct wps_token *token = SKINOFFSETTOPTR(skin_buffer, list->token);
1668 struct gui_img *img = (struct gui_img*)SKINOFFSETTOPTR(skin_buffer, token->value.data);
1607 if (img->bm.data) 1669 if (img->bm.data)
1608 { 1670 {
1609 if (img->using_preloaded_icons) 1671 if (img->using_preloaded_icons)
1610 { 1672 {
1611 img->loaded = true; 1673 img->loaded = true;
1612 list->token->type = SKIN_TOKEN_IMAGE_DISPLAY_LISTICON; 1674 token->type = SKIN_TOKEN_IMAGE_DISPLAY_LISTICON;
1613 } 1675 }
1614 else 1676 else
1615 { 1677 {
@@ -1621,11 +1683,11 @@ static bool load_skin_bitmaps(struct wps_data *wps_data, char *bmpdir)
1621 retval = false; 1683 retval = false;
1622 } 1684 }
1623 } 1685 }
1624 list = list->next; 1686 list = SKINOFFSETTOPTR(skin_buffer, list->next);
1625 } 1687 }
1626 1688
1627#if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)) 1689#if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1))
1628 wps_data->backdrop_id = skin_backdrop_assign(wps_data->backdrop, bmpdir, curr_screen); 1690 wps_data->backdrop_id = skin_backdrop_assign(backdrop_filename, bmpdir, curr_screen);
1629#endif /* has backdrop support */ 1691#endif /* has backdrop support */
1630 return retval; 1692 return retval;
1631} 1693}
@@ -1639,11 +1701,12 @@ static bool skin_load_fonts(struct wps_data *data)
1639 struct skin_element *vp_list; 1701 struct skin_element *vp_list;
1640 int font_id; 1702 int font_id;
1641 /* walk though each viewport and assign its font */ 1703 /* walk though each viewport and assign its font */
1642 for(vp_list = data->tree; vp_list; vp_list = vp_list->next) 1704 for(vp_list = SKINOFFSETTOPTR(skin_buffer, data->tree);
1705 vp_list; vp_list = SKINOFFSETTOPTR(skin_buffer, vp_list->next))
1643 { 1706 {
1644 /* first, find the viewports that have a non-sys/ui-font font */ 1707 /* first, find the viewports that have a non-sys/ui-font font */
1645 struct skin_viewport *skin_vp = 1708 struct skin_viewport *skin_vp =
1646 (struct skin_viewport*)vp_list->data; 1709 SKINOFFSETTOPTR(skin_buffer, vp_list->data);
1647 struct viewport *vp = &skin_vp->vp; 1710 struct viewport *vp = &skin_vp->vp;
1648 1711
1649 font_id = skin_vp->parsed_fontid; 1712 font_id = skin_vp->parsed_fontid;
@@ -1699,19 +1762,28 @@ static bool skin_load_fonts(struct wps_data *data)
1699 /* finally, assign the font_id to the viewport */ 1762 /* finally, assign the font_id to the viewport */
1700 vp->font = font->id; 1763 vp->font = font->id;
1701 } 1764 }
1702 data->font_ids = skin_buffer_alloc(font_count * sizeof(int)); 1765 if (font_count)
1703 if (!success || data->font_ids == NULL)
1704 { 1766 {
1705 while (font_count > 0) 1767 int *font_ids = skin_buffer_alloc(font_count * sizeof(int));
1768 if (!success || font_ids == NULL)
1706 { 1769 {
1707 if(id_array[--font_count] != -1) 1770 while (font_count > 0)
1708 font_unload(id_array[font_count]); 1771 {
1772 if(id_array[--font_count] != -1)
1773 font_unload(id_array[font_count]);
1774 }
1775 data->font_ids = PTRTOSKINOFFSET(skin_buffer, NULL);
1776 return false;
1709 } 1777 }
1710 data->font_ids = NULL; 1778 memcpy(font_ids, id_array, sizeof(int)*font_count);
1711 return false; 1779 data->font_count = font_count;
1780 data->font_ids = PTRTOSKINOFFSET(skin_buffer, font_ids);
1781 }
1782 else
1783 {
1784 data->font_count = 0;
1785 data->font_ids = PTRTOSKINOFFSET(skin_buffer, NULL);
1712 } 1786 }
1713 memcpy(data->font_ids, id_array, sizeof(int)*font_count);
1714 data->font_count = font_count;
1715 return success; 1787 return success;
1716} 1788}
1717 1789
@@ -1726,13 +1798,15 @@ static int convert_viewport(struct wps_data *data, struct skin_element* element)
1726 return CALLBACK_ERROR; 1798 return CALLBACK_ERROR;
1727 1799
1728 skin_vp->hidden_flags = 0; 1800 skin_vp->hidden_flags = 0;
1729 skin_vp->label = NULL; 1801 skin_vp->label = PTRTOSKINOFFSET(skin_buffer, NULL);
1730 skin_vp->is_infovp = false; 1802 skin_vp->is_infovp = false;
1731 skin_vp->parsed_fontid = 1; 1803 skin_vp->parsed_fontid = 1;
1732 element->data = skin_vp; 1804 element->data = PTRTOSKINOFFSET(skin_buffer, skin_vp);
1733 curr_vp = skin_vp; 1805 curr_vp = skin_vp;
1734 curr_viewport_element = element; 1806 curr_viewport_element = element;
1735 1807 if (!first_viewport)
1808 first_viewport = element;
1809
1736 viewport_set_defaults(&skin_vp->vp, curr_screen); 1810 viewport_set_defaults(&skin_vp->vp, curr_screen);
1737 1811
1738#if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)) 1812#if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1))
@@ -1746,11 +1820,11 @@ static int convert_viewport(struct wps_data *data, struct skin_element* element)
1746#endif 1820#endif
1747 1821
1748 1822
1749 struct skin_tag_parameter *param = element->params; 1823 struct skin_tag_parameter *param = get_param(element, 0);
1750 if (element->params_count == 0) /* default viewport */ 1824 if (element->params_count == 0) /* default viewport */
1751 { 1825 {
1752 if (!data->tree) /* first viewport in the skin */ 1826 if (data->tree < 0) /* first viewport in the skin */
1753 data->tree = element; 1827 data->tree = PTRTOSKINOFFSET(skin_buffer, element);
1754 skin_vp->label = VP_DEFAULT_LABEL; 1828 skin_vp->label = VP_DEFAULT_LABEL;
1755 return CALLBACK_OK; 1829 return CALLBACK_OK;
1756 } 1830 }
@@ -1848,6 +1922,7 @@ static int skin_element_callback(struct skin_element* element, void* data)
1848 token = (struct wps_token*)skin_buffer_alloc(sizeof(struct wps_token)); 1922 token = (struct wps_token*)skin_buffer_alloc(sizeof(struct wps_token));
1849 memset(token, 0, sizeof(*token)); 1923 memset(token, 0, sizeof(*token));
1850 token->type = element->tag->type; 1924 token->type = element->tag->type;
1925 token->value.data = INVALID_OFFSET;
1851 1926
1852 if (element->tag->flags&SKIN_RTC_REFRESH) 1927 if (element->tag->flags&SKIN_RTC_REFRESH)
1853 { 1928 {
@@ -1860,7 +1935,7 @@ static int skin_element_callback(struct skin_element* element, void* data)
1860 else 1935 else
1861 curr_line->update_mode |= element->tag->flags&SKIN_REFRESH_ALL; 1936 curr_line->update_mode |= element->tag->flags&SKIN_REFRESH_ALL;
1862 1937
1863 element->data = token; 1938 element->data = PTRTOSKINOFFSET(skin_buffer, token);
1864 1939
1865 /* Some tags need special handling for the tag, so add them here */ 1940 /* Some tags need special handling for the tag, so add them here */
1866 switch (token->type) 1941 switch (token->type)
@@ -1909,7 +1984,7 @@ static int skin_element_callback(struct skin_element* element, void* data)
1909 break; 1984 break;
1910#endif 1985#endif
1911 case SKIN_TOKEN_FILE_DIRECTORY: 1986 case SKIN_TOKEN_FILE_DIRECTORY:
1912 token->value.i = element->params[0].data.number; 1987 token->value.i = get_param(element, 0)->data.number;
1913 break; 1988 break;
1914#if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)) 1989#if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1))
1915 case SKIN_TOKEN_VIEWPORT_FGCOLOUR: 1990 case SKIN_TOKEN_VIEWPORT_FGCOLOUR:
@@ -1941,7 +2016,7 @@ static int skin_element_callback(struct skin_element* element, void* data)
1941 break; 2016 break;
1942 case SKIN_TOKEN_VIEWPORT_ENABLE: 2017 case SKIN_TOKEN_VIEWPORT_ENABLE:
1943 case SKIN_TOKEN_UIVIEWPORT_ENABLE: 2018 case SKIN_TOKEN_UIVIEWPORT_ENABLE:
1944 token->value.data = element->params[0].data.text; 2019 token->value.data = get_param(element, 0)->data.text;
1945 break; 2020 break;
1946 case SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY: 2021 case SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY:
1947 function = parse_image_display; 2022 function = parse_image_display;
@@ -1964,8 +2039,11 @@ static int skin_element_callback(struct skin_element* element, void* data)
1964#endif 2039#endif
1965#ifdef HAVE_ALBUMART 2040#ifdef HAVE_ALBUMART
1966 case SKIN_TOKEN_ALBUMART_DISPLAY: 2041 case SKIN_TOKEN_ALBUMART_DISPLAY:
1967 if (wps_data->albumart) 2042 if (SKINOFFSETTOPTR(skin_buffer, wps_data->albumart))
1968 wps_data->albumart->vp = &curr_vp->vp; 2043 {
2044 struct skin_albumart *aa = SKINOFFSETTOPTR(skin_buffer, wps_data->albumart);
2045 aa->vp = PTRTOSKINOFFSET(skin_buffer, &curr_vp->vp);
2046 }
1969 break; 2047 break;
1970 case SKIN_TOKEN_ALBUMART_LOAD: 2048 case SKIN_TOKEN_ALBUMART_LOAD:
1971 function = parse_albumart_load; 2049 function = parse_albumart_load;
@@ -2002,7 +2080,7 @@ static int skin_element_callback(struct skin_element* element, void* data)
2002 (struct line *)skin_buffer_alloc(sizeof(struct line)); 2080 (struct line *)skin_buffer_alloc(sizeof(struct line));
2003 line->update_mode = SKIN_REFRESH_STATIC; 2081 line->update_mode = SKIN_REFRESH_STATIC;
2004 curr_line = line; 2082 curr_line = line;
2005 element->data = line; 2083 element->data = PTRTOSKINOFFSET(skin_buffer, line);
2006 } 2084 }
2007 break; 2085 break;
2008 case LINE_ALTERNATOR: 2086 case LINE_ALTERNATOR:
@@ -2013,7 +2091,7 @@ static int skin_element_callback(struct skin_element* element, void* data)
2013#ifndef __PCTOOL__ 2091#ifndef __PCTOOL__
2014 alternator->next_change_tick = current_tick; 2092 alternator->next_change_tick = current_tick;
2015#endif 2093#endif
2016 element->data = alternator; 2094 element->data = PTRTOSKINOFFSET(skin_buffer, alternator);
2017 } 2095 }
2018 break; 2096 break;
2019 case CONDITIONAL: 2097 case CONDITIONAL:
@@ -2022,7 +2100,7 @@ static int skin_element_callback(struct skin_element* element, void* data)
2022 (struct conditional *)skin_buffer_alloc(sizeof(struct conditional)); 2100 (struct conditional *)skin_buffer_alloc(sizeof(struct conditional));
2023 conditional->last_value = -1; 2101 conditional->last_value = -1;
2024 conditional->token = element->data; 2102 conditional->token = element->data;
2025 element->data = conditional; 2103 element->data = PTRTOSKINOFFSET(skin_buffer, conditional);
2026 if (!check_feature_tag(element->tag->type)) 2104 if (!check_feature_tag(element->tag->type))
2027 { 2105 {
2028 return FEATURE_NOT_AVAILABLE; 2106 return FEATURE_NOT_AVAILABLE;
@@ -2051,11 +2129,12 @@ bool skin_data_load(enum screen_type screen, struct wps_data *wps_data,
2051 struct mp3entry *curtrack; 2129 struct mp3entry *curtrack;
2052 long offset; 2130 long offset;
2053 struct skin_albumart old_aa = {.state = WPS_ALBUMART_NONE}; 2131 struct skin_albumart old_aa = {.state = WPS_ALBUMART_NONE};
2054 if (wps_data->albumart) 2132 struct skin_albumart *aa = SKINOFFSETTOPTR(skin_buffer, wps_data->albumart);
2133 if (aa)
2055 { 2134 {
2056 old_aa.state = wps_data->albumart->state; 2135 old_aa.state = aa->state;
2057 old_aa.height = wps_data->albumart->height; 2136 old_aa.height = aa->height;
2058 old_aa.width = wps_data->albumart->width; 2137 old_aa.width = aa->width;
2059 } 2138 }
2060#endif 2139#endif
2061#ifdef HAVE_LCD_BITMAP 2140#ifdef HAVE_LCD_BITMAP
@@ -2074,12 +2153,20 @@ bool skin_data_load(enum screen_type screen, struct wps_data *wps_data,
2074#endif 2153#endif
2075 2154
2076 2155
2156 /* get buffer space from the plugin buffer */
2157 size_t buffersize = 0;
2158 wps_buffer = (char *)plugin_get_buffer(&buffersize);
2159
2160 if (!wps_buffer)
2161 return false;
2162
2077 skin_data_reset(wps_data); 2163 skin_data_reset(wps_data);
2078 wps_data->wps_loaded = false; 2164 wps_data->wps_loaded = false;
2079 curr_screen = screen; 2165 curr_screen = screen;
2080 curr_line = NULL; 2166 curr_line = NULL;
2081 curr_vp = NULL; 2167 curr_vp = NULL;
2082 curr_viewport_element = NULL; 2168 curr_viewport_element = NULL;
2169 first_viewport = NULL;
2083 2170
2084 if (isfile) 2171 if (isfile)
2085 { 2172 {
@@ -2087,14 +2174,6 @@ bool skin_data_load(enum screen_type screen, struct wps_data *wps_data,
2087 2174
2088 if (fd < 0) 2175 if (fd < 0)
2089 return false; 2176 return false;
2090
2091 /* get buffer space from the plugin buffer */
2092 size_t buffersize = 0;
2093 wps_buffer = (char *)plugin_get_buffer(&buffersize);
2094
2095 if (!wps_buffer)
2096 return false;
2097
2098 /* copy the file's content to the buffer for parsing, 2177 /* copy the file's content to the buffer for parsing,
2099 ensuring that every line ends with a newline char. */ 2178 ensuring that every line ends with a newline char. */
2100 unsigned int start = 0; 2179 unsigned int start = 0;
@@ -2110,25 +2189,26 @@ bool skin_data_load(enum screen_type screen, struct wps_data *wps_data,
2110 close(fd); 2189 close(fd);
2111 if (start <= 0) 2190 if (start <= 0)
2112 return false; 2191 return false;
2192 skin_buffer = &wps_buffer[start];
2193 buffersize -= start;
2113 } 2194 }
2114 else 2195 else
2115 { 2196 {
2197 skin_buffer = wps_buffer;
2116 wps_buffer = (char*)buf; 2198 wps_buffer = (char*)buf;
2117 } 2199 }
2200 skin_buffer = (void *)(((unsigned long)skin_buffer + 3) & ~3);
2201 buffersize -= 3;
2118#if LCD_DEPTH > 1 || defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1 2202#if LCD_DEPTH > 1 || defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1
2119 wps_data->backdrop = "-"; 2203 backdrop_filename = "-";
2120 wps_data->backdrop_id = -1; 2204 wps_data->backdrop_id = -1;
2121#endif 2205#endif
2122 /* parse the skin source */ 2206 /* parse the skin source */
2123#ifndef APPLICATION 2207 skin_buffer_init(skin_buffer, buffersize);
2124 skin_buffer_save_position(); 2208 struct skin_element *tree = skin_parse(wps_buffer, skin_element_callback, wps_data);
2125#endif 2209 wps_data->tree = PTRTOSKINOFFSET(skin_buffer, tree);
2126 wps_data->tree = skin_parse(wps_buffer, skin_element_callback, wps_data); 2210 if (!SKINOFFSETTOPTR(skin_buffer, wps_data->tree)) {
2127 if (!wps_data->tree) {
2128 skin_data_reset(wps_data); 2211 skin_data_reset(wps_data);
2129#ifndef APPLICATION
2130 skin_buffer_restore_position();
2131#endif
2132 return false; 2212 return false;
2133 } 2213 }
2134 2214
@@ -2149,9 +2229,6 @@ bool skin_data_load(enum screen_type screen, struct wps_data *wps_data,
2149 !skin_load_fonts(wps_data)) 2229 !skin_load_fonts(wps_data))
2150 { 2230 {
2151 skin_data_reset(wps_data); 2231 skin_data_reset(wps_data);
2152#ifndef APPLICATION
2153 skin_buffer_restore_position();
2154#endif
2155 return false; 2232 return false;
2156 } 2233 }
2157#endif 2234#endif
@@ -2159,7 +2236,7 @@ bool skin_data_load(enum screen_type screen, struct wps_data *wps_data,
2159 status = audio_status(); 2236 status = audio_status();
2160 if (status & AUDIO_STATUS_PLAY) 2237 if (status & AUDIO_STATUS_PLAY)
2161 { 2238 {
2162 struct skin_albumart *aa = wps_data->albumart; 2239 struct skin_albumart *aa = SKINOFFSETTOPTR(skin_buffer, wps_data->albumart);
2163 if (aa && ((aa->state && !old_aa.state) || 2240 if (aa && ((aa->state && !old_aa.state) ||
2164 (aa->state && 2241 (aa->state &&
2165 (((old_aa.height != aa->height) || 2242 (((old_aa.height != aa->height) ||
@@ -2173,7 +2250,18 @@ bool skin_data_load(enum screen_type screen, struct wps_data *wps_data,
2173 } 2250 }
2174 } 2251 }
2175#endif 2252#endif
2176 wps_data->wps_loaded = true; 2253#ifndef __PCTOOL__
2254 wps_data->buflib_handle = core_alloc(isfile ? buf : "failsafe skin",
2255 skin_buffer_usage());
2256 if (wps_data->buflib_handle >= 0)
2257 {
2258 wps_data->wps_loaded = true;
2259 memcpy(core_get_data(wps_data->buflib_handle), skin_buffer,
2260 skin_buffer_usage());
2261 }
2262#else
2263 wps_data->wps_loaded = wps_data->tree >= 0;
2264#endif
2177#ifdef DEBUG_SKIN_ENGINE 2265#ifdef DEBUG_SKIN_ENGINE
2178 // if (isfile && debug_wps) 2266 // if (isfile && debug_wps)
2179 // debug_skin_usage(); 2267 // debug_skin_usage();