summaryrefslogtreecommitdiff
path: root/apps/gui
diff options
context:
space:
mode:
authorJonathan Gordon <rockbox@jdgordon.info>2011-11-15 14:11:08 +0000
committerJonathan Gordon <rockbox@jdgordon.info>2011-11-15 14:11:08 +0000
commit9e07ef2b0adb8fca7e5a9e516397e533653f8836 (patch)
tree0a283550421917e52ee04068b84a464976f0c4f2 /apps/gui
parent101693fd3047fb64e766580e80635a424fa25c4d (diff)
downloadrockbox-9e07ef2b0adb8fca7e5a9e516397e533653f8836.tar.gz
rockbox-9e07ef2b0adb8fca7e5a9e516397e533653f8836.zip
Use buflib for all skin engine allocations.
Massive thanks to Michael Chicoine and other testers for finding the early bugs. This removes all skin memory limitations git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30991 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/gui')
-rw-r--r--apps/gui/bitmap/list-skinned.c21
-rw-r--r--apps/gui/skin_engine/skin_display.c47
-rw-r--r--apps/gui/skin_engine/skin_engine.c26
-rw-r--r--apps/gui/skin_engine/skin_parser.c550
-rw-r--r--apps/gui/skin_engine/skin_render.c209
-rw-r--r--apps/gui/skin_engine/skin_tokens.c52
-rw-r--r--apps/gui/skin_engine/skin_tokens.h49
-rw-r--r--apps/gui/skin_engine/skin_touchsupport.c33
-rw-r--r--apps/gui/skin_engine/wps_internals.h166
-rw-r--r--apps/gui/statusbar-skinned.c21
-rw-r--r--apps/gui/statusbar-skinned.h2
-rw-r--r--apps/gui/wps.c2
12 files changed, 643 insertions, 535 deletions
diff --git a/apps/gui/bitmap/list-skinned.c b/apps/gui/bitmap/list-skinned.c
index 208b2df681..444d49148f 100644
--- a/apps/gui/bitmap/list-skinned.c
+++ b/apps/gui/bitmap/list-skinned.c
@@ -175,22 +175,23 @@ bool skinlist_draw(struct screen *display, struct gui_synclist *list)
175 for (cur_line = 0; cur_line < display_lines; cur_line++) 175 for (cur_line = 0; cur_line < display_lines; cur_line++)
176 { 176 {
177 struct skin_element* viewport; 177 struct skin_element* viewport;
178 struct skin_viewport* skin_viewport; 178 struct skin_viewport* skin_viewport = NULL;
179 if (list_start_item+cur_line+1 > list->nb_items) 179 if (list_start_item+cur_line+1 > list->nb_items)
180 break; 180 break;
181 current_drawing_line = list_start_item+cur_line; 181 current_drawing_line = list_start_item+cur_line;
182 is_selected = list->show_selection_marker && 182 is_selected = list->show_selection_marker &&
183 list_start_item+cur_line == list->selected_item; 183 list_start_item+cur_line == list->selected_item;
184 184
185 for (viewport = listcfg[screen]->data->tree; 185 for (viewport = SKINOFFSETTOPTR(get_skin_buffer(wps.data), listcfg[screen]->data->tree);
186 viewport; 186 viewport;
187 viewport = viewport->next) 187 viewport = SKINOFFSETTOPTR(get_skin_buffer(wps.data), viewport->next))
188 { 188 {
189 int origional_x, origional_y; 189 int origional_x, origional_y;
190 int origional_w, origional_h; 190 int origional_w, origional_h;
191 char *viewport_label = SKINOFFSETTOPTR(get_skin_buffer(wps.data), skin_viewport->label);
191 skin_viewport = (struct skin_viewport*)viewport->data; 192 skin_viewport = (struct skin_viewport*)viewport->data;
192 if (viewport->children == 0 || !skin_viewport->label || 193 if (viewport->children == 0 || !viewport_label ||
193 (skin_viewport->label && strcmp(label, skin_viewport->label)) 194 (skin_viewport->label && strcmp(label, viewport_label))
194 ) 195 )
195 continue; 196 continue;
196 if (is_selected) 197 if (is_selected)
@@ -220,15 +221,17 @@ bool skinlist_draw(struct screen *display, struct gui_synclist *list)
220 display->set_viewport(&skin_viewport->vp); 221 display->set_viewport(&skin_viewport->vp);
221#ifdef HAVE_LCD_BITMAP 222#ifdef HAVE_LCD_BITMAP
222 /* Set images to not to be displayed */ 223 /* Set images to not to be displayed */
223 struct skin_token_list *imglist = wps.data->images; 224 struct skin_token_list *imglist = SKINOFFSETTOPTR(get_skin_buffer(wps.data), wps.data->images);
224 while (imglist) 225 while (imglist)
225 { 226 {
226 struct gui_img *img = (struct gui_img *)imglist->token->value.data; 227 struct wps_token *token = SKINOFFSETTOPTR(get_skin_buffer(wps.data), imglist->token);
228 struct gui_img *img = SKINOFFSETTOPTR(get_skin_buffer(wps.data), token->value.data);
227 img->display = -1; 229 img->display = -1;
228 imglist = imglist->next; 230 imglist = SKINOFFSETTOPTR(get_skin_buffer(wps.data), imglist->next);
229 } 231 }
230#endif 232#endif
231 skin_render_viewport(viewport->children[0], 233 struct skin_element** children = SKINOFFSETTOPTR(get_skin_buffer(wps.data), viewport->children);
234 skin_render_viewport(children[0],
232 &wps, skin_viewport, SKIN_REFRESH_ALL); 235 &wps, skin_viewport, SKIN_REFRESH_ALL);
233#ifdef HAVE_LCD_BITMAP 236#ifdef HAVE_LCD_BITMAP
234 wps_display_images(&wps, &skin_viewport->vp); 237 wps_display_images(&wps, &skin_viewport->vp);
diff --git a/apps/gui/skin_engine/skin_display.c b/apps/gui/skin_engine/skin_display.c
index d2dbb56f64..1114c09a72 100644
--- a/apps/gui/skin_engine/skin_display.c
+++ b/apps/gui/skin_engine/skin_display.c
@@ -102,7 +102,7 @@ void skin_statusbar_changed(struct gui_wps *skin)
102 struct wps_data *data = skin->data; 102 struct wps_data *data = skin->data;
103 const struct screen *display = skin->display; 103 const struct screen *display = skin->display;
104 const int screen = display->screen_type; 104 const int screen = display->screen_type;
105 struct skin_viewport *svp = skin_find_item(VP_DEFAULT_LABEL, SKIN_FIND_VP, data); 105 struct skin_viewport *svp = skin_find_item(VP_DEFAULT_LABEL_STRING, SKIN_FIND_VP, data);
106 106
107 struct viewport *vp = &svp->vp; 107 struct viewport *vp = &svp->vp;
108 viewport_set_defaults(vp, screen); 108 viewport_set_defaults(vp, screen);
@@ -131,7 +131,7 @@ void skin_statusbar_changed(struct gui_wps *skin)
131void draw_progressbar(struct gui_wps *gwps, int line, struct progressbar *pb) 131void draw_progressbar(struct gui_wps *gwps, int line, struct progressbar *pb)
132{ 132{
133 struct screen *display = gwps->display; 133 struct screen *display = gwps->display;
134 struct viewport *vp = pb->vp; 134 struct viewport *vp = SKINOFFSETTOPTR(get_skin_buffer(gwps->data), pb->vp);
135 struct wps_state *state = skin_get_global_state(); 135 struct wps_state *state = skin_get_global_state();
136 struct mp3entry *id3 = state->id3; 136 struct mp3entry *id3 = state->id3;
137 int x = pb->x, y = pb->y, width = pb->width, height = pb->height; 137 int x = pb->x, y = pb->y, width = pb->width, height = pb->height;
@@ -226,9 +226,9 @@ void draw_progressbar(struct gui_wps *gwps, int line, struct progressbar *pb)
226 flags |= INNER_NOFILL; 226 flags |= INNER_NOFILL;
227 } 227 }
228 228
229 if (pb->slider) 229 if (SKINOFFSETTOPTR(get_skin_buffer(gwps->data), pb->slider))
230 { 230 {
231 struct gui_img *img = pb->slider; 231 struct gui_img *img = SKINOFFSETTOPTR(get_skin_buffer(gwps->data), pb->slider);
232 /* clear the slider */ 232 /* clear the slider */
233 screen_clear_area(display, x, y, width, height); 233 screen_clear_area(display, x, y, width, height);
234 234
@@ -245,9 +245,9 @@ void draw_progressbar(struct gui_wps *gwps, int line, struct progressbar *pb)
245 } 245 }
246 } 246 }
247 247
248 if (pb->backdrop) 248 if (SKINOFFSETTOPTR(get_skin_buffer(gwps->data), pb->backdrop))
249 { 249 {
250 struct gui_img *img = pb->backdrop; 250 struct gui_img *img = SKINOFFSETTOPTR(get_skin_buffer(gwps->data), pb->backdrop);
251 img->bm.data = core_get_data(img->buflib_handle); 251 img->bm.data = core_get_data(img->buflib_handle);
252 display->bmp_part(&img->bm, 0, 0, x, y, width, height); 252 display->bmp_part(&img->bm, 0, 0, x, y, width, height);
253 flags |= DONT_CLEAR_EXCESS; 253 flags |= DONT_CLEAR_EXCESS;
@@ -255,11 +255,12 @@ void draw_progressbar(struct gui_wps *gwps, int line, struct progressbar *pb)
255 255
256 if (!pb->nobar) 256 if (!pb->nobar)
257 { 257 {
258 if (pb->image) 258 struct gui_img *img = SKINOFFSETTOPTR(get_skin_buffer(gwps->data), pb->image);
259 if (img)
259 { 260 {
260 char *img_data = core_get_data(pb->image->buflib_handle); 261 char *img_data = core_get_data(img->buflib_handle);
261 pb->image->bm.data = img_data; 262 img->bm.data = img_data;
262 gui_bitmap_scrollbar_draw(display, &pb->image->bm, 263 gui_bitmap_scrollbar_draw(display, &img->bm,
263 x, y, width, height, 264 x, y, width, height,
264 length, 0, end, flags); 265 length, 0, end, flags);
265 } 266 }
@@ -268,11 +269,11 @@ void draw_progressbar(struct gui_wps *gwps, int line, struct progressbar *pb)
268 length, 0, end, flags); 269 length, 0, end, flags);
269 } 270 }
270 271
271 if (pb->slider) 272 if (SKINOFFSETTOPTR(get_skin_buffer(gwps->data), pb->slider))
272 { 273 {
273 int xoff = 0, yoff = 0; 274 int xoff = 0, yoff = 0;
274 int w = width, h = height; 275 int w = width, h = height;
275 struct gui_img *img = pb->slider; 276 struct gui_img *img = SKINOFFSETTOPTR(get_skin_buffer(gwps->data), pb->slider);
276 img->bm.data = core_get_data(img->buflib_handle); 277 img->bm.data = core_get_data(img->buflib_handle);
277 278
278 if (flags&HORIZONTAL) 279 if (flags&HORIZONTAL)
@@ -347,11 +348,12 @@ void wps_display_images(struct gui_wps *gwps, struct viewport* vp)
347 348
348 struct wps_data *data = gwps->data; 349 struct wps_data *data = gwps->data;
349 struct screen *display = gwps->display; 350 struct screen *display = gwps->display;
350 struct skin_token_list *list = data->images; 351 struct skin_token_list *list = SKINOFFSETTOPTR(get_skin_buffer(data), data->images);
351 352
352 while (list) 353 while (list)
353 { 354 {
354 struct gui_img *img = (struct gui_img*)list->token->value.data; 355 struct wps_token *token = SKINOFFSETTOPTR(get_skin_buffer(data), list->token);
356 struct gui_img *img = (struct gui_img*)SKINOFFSETTOPTR(get_skin_buffer(data), token->value.data);
355 if (img->using_preloaded_icons && img->display >= 0) 357 if (img->using_preloaded_icons && img->display >= 0)
356 { 358 {
357 screen_put_icon(display, img->x, img->y, img->display); 359 screen_put_icon(display, img->x, img->y, img->display);
@@ -362,20 +364,21 @@ void wps_display_images(struct gui_wps *gwps, struct viewport* vp)
362 { 364 {
363 wps_draw_image(gwps, img, img->display); 365 wps_draw_image(gwps, img, img->display);
364 } 366 }
365 else if (img->always_display && img->vp == vp) 367 else if (img->always_display && SKINOFFSETTOPTR(get_skin_buffer(data), img->vp) == vp)
366 { 368 {
367 wps_draw_image(gwps, img, 0); 369 wps_draw_image(gwps, img, 0);
368 } 370 }
369 } 371 }
370 list = list->next; 372 list = SKINOFFSETTOPTR(get_skin_buffer(data), list->next);
371 } 373 }
372#ifdef HAVE_ALBUMART 374#ifdef HAVE_ALBUMART
373 /* now draw the AA */ 375 /* now draw the AA */
374 if (data->albumart && data->albumart->vp == vp 376 struct skin_albumart *aa = SKINOFFSETTOPTR(get_skin_buffer(data), data->albumart);
375 && data->albumart->draw_handle >= 0) 377 if (aa && SKINOFFSETTOPTR(get_skin_buffer(data), aa->vp) == vp
378 && aa->draw_handle >= 0)
376 { 379 {
377 draw_album_art(gwps, data->albumart->draw_handle, false); 380 draw_album_art(gwps, aa->draw_handle, false);
378 data->albumart->draw_handle = -1; 381 aa->draw_handle = -1;
379 } 382 }
380#endif 383#endif
381 384
@@ -398,8 +401,8 @@ int evaluate_conditional(struct gui_wps *gwps, int offset,
398 401
399 int intval = num_options < 2 ? 2 : num_options; 402 int intval = num_options < 2 ? 2 : num_options;
400 /* get_token_value needs to know the number of options in the enum */ 403 /* get_token_value needs to know the number of options in the enum */
401 value = get_token_value(gwps, conditional->token, offset, 404 value = get_token_value(gwps, SKINOFFSETTOPTR(get_skin_buffer(gwps->data), conditional->token),
402 result, sizeof(result), &intval); 405 offset, result, sizeof(result), &intval);
403 406
404 /* intval is now the number of the enum option we want to read, 407 /* intval is now the number of the enum option we want to read,
405 starting from 1. If intval is -1, we check if value is empty. */ 408 starting from 1. If intval is -1, we check if value is empty. */
diff --git a/apps/gui/skin_engine/skin_engine.c b/apps/gui/skin_engine/skin_engine.c
index bd875fe9e4..75862faab0 100644
--- a/apps/gui/skin_engine/skin_engine.c
+++ b/apps/gui/skin_engine/skin_engine.c
@@ -41,19 +41,10 @@
41static bool skins_initialising = true; 41static bool skins_initialising = true;
42 42
43/* App uses the host malloc to manage the buffer */ 43/* App uses the host malloc to manage the buffer */
44#ifdef APPLICATION
45#define skin_buffer NULL
46void theme_init_buffer(void) 44void theme_init_buffer(void)
47{ 45{
48 skins_initialising = false; 46 skins_initialising = false;
49} 47}
50#else
51static char skin_buffer[SKIN_BUFFER_SIZE];
52void theme_init_buffer(void)
53{
54 skins_initialising = false;
55}
56#endif
57 48
58void skin_data_free_buflib_allocs(struct wps_data *wps_data); 49void skin_data_free_buflib_allocs(struct wps_data *wps_data);
59char* wps_default_skin(enum screen_type screen); 50char* wps_default_skin(enum screen_type screen);
@@ -95,8 +86,20 @@ void gui_sync_skin_init(void)
95 skins[j][i].gui_wps.display = &screens[i]; 86 skins[j][i].gui_wps.display = &screens[i];
96 memset(skins[j][i].gui_wps.data, 0, sizeof(struct wps_data)); 87 memset(skins[j][i].gui_wps.data, 0, sizeof(struct wps_data));
97 skins[j][i].data.wps_loaded = false; 88 skins[j][i].data.wps_loaded = false;
89 skins[j][i].data.buflib_handle = -1;
90 skins[j][i].data.tree = -1;
91#ifdef HAVE_TOUCHSCREEN
92 skins[j][i].data.touchregions = -1;
93#endif
94#ifdef HAVE_SKIN_VARIABLES
95 skins[j][i].data.skinvars = -1;
96#endif
97#ifdef HAVE_LCD_BITMAP
98 skins[j][i].data.font_ids = -1;
99 skins[j][i].data.images = -1;
100#endif
98#ifdef HAVE_ALBUMART 101#ifdef HAVE_ALBUMART
99 skins[j][i].data.albumart = NULL; 102 skins[j][i].data.albumart = -1;
100 skins[j][i].data.playback_aa_slot = -1; 103 skins[j][i].data.playback_aa_slot = -1;
101#endif 104#endif
102 } 105 }
@@ -113,8 +116,6 @@ void skin_unload_all(void)
113 skin_data_free_buflib_allocs(&skins[j][i].data); 116 skin_data_free_buflib_allocs(&skins[j][i].data);
114 } 117 }
115 118
116 skin_buffer_init(skin_buffer, SKIN_BUFFER_SIZE);
117
118#ifdef HAVE_LCD_BITMAP 119#ifdef HAVE_LCD_BITMAP
119 skin_backdrop_init(); 120 skin_backdrop_init();
120#endif 121#endif
@@ -245,7 +246,6 @@ struct gui_wps *skin_get_gwps(enum skinnable_screens skin, enum screen_type scre
245 cpu_boost(false); 246 cpu_boost(false);
246 loading_a_sbs = false; 247 loading_a_sbs = false;
247 } 248 }
248
249 return &skins[skin][screen].gui_wps; 249 return &skins[skin][screen].gui_wps;
250} 250}
251 251
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();
diff --git a/apps/gui/skin_engine/skin_render.c b/apps/gui/skin_engine/skin_render.c
index 4d41a6f9b7..e408caaa1e 100644
--- a/apps/gui/skin_engine/skin_render.c
+++ b/apps/gui/skin_engine/skin_render.c
@@ -27,6 +27,7 @@
27#include "strlcat.h" 27#include "strlcat.h"
28 28
29#include "config.h" 29#include "config.h"
30#include "core_alloc.h"
30#include "kernel.h" 31#include "kernel.h"
31#ifdef HAVE_ALBUMART 32#ifdef HAVE_ALBUMART
32#include "albumart.h" 33#include "albumart.h"
@@ -81,6 +82,18 @@ static void skin_render_playlistviewer(struct playlistviewer* viewer,
81 unsigned long refresh_type); 82 unsigned long refresh_type);
82#endif 83#endif
83 84
85static char* skin_buffer;
86/* hack alert: fix skin_parser.c's skin_buffer pointer */
87void skinparser_set_buffer(char* pointer);
88
89static inline struct skin_element*
90get_child(OFFSETTYPE(struct skin_element**) children, int child)
91{
92 OFFSETTYPE(struct skin_element*) *kids = SKINOFFSETTOPTR(skin_buffer, children);
93 return SKINOFFSETTOPTR(skin_buffer, kids[child]);
94}
95
96
84static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info, 97static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
85 struct skin_element *element, struct viewport* vp) 98 struct skin_element *element, struct viewport* vp)
86{ 99{
@@ -88,7 +101,7 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
88 (void)vp; /* silence warnings */ 101 (void)vp; /* silence warnings */
89 (void)info; 102 (void)info;
90#endif 103#endif
91 struct wps_token *token = (struct wps_token *)element->data; 104 struct wps_token *token = (struct wps_token *)SKINOFFSETTOPTR(skin_buffer, element->data);
92 105
93#ifdef HAVE_LCD_BITMAP 106#ifdef HAVE_LCD_BITMAP
94 struct wps_data *data = gwps->data; 107 struct wps_data *data = gwps->data;
@@ -99,14 +112,16 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
99#if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)) 112#if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1))
100 case SKIN_TOKEN_VIEWPORT_FGCOLOUR: 113 case SKIN_TOKEN_VIEWPORT_FGCOLOUR:
101 { 114 {
102 struct viewport_colour *col = token->value.data; 115 struct viewport_colour *col = SKINOFFSETTOPTR(skin_buffer, token->value.data);
103 col->vp->fg_pattern = col->colour; 116 struct viewport *vp = SKINOFFSETTOPTR(skin_buffer, col->vp);
117 vp->fg_pattern = col->colour;
104 } 118 }
105 break; 119 break;
106 case SKIN_TOKEN_VIEWPORT_BGCOLOUR: 120 case SKIN_TOKEN_VIEWPORT_BGCOLOUR:
107 { 121 {
108 struct viewport_colour *col = token->value.data; 122 struct viewport_colour *col = SKINOFFSETTOPTR(skin_buffer, token->value.data);
109 col->vp->bg_pattern = col->colour; 123 struct viewport *vp = SKINOFFSETTOPTR(skin_buffer, col->vp);
124 vp->bg_pattern = col->colour;
110 } 125 }
111 break; 126 break;
112 case SKIN_TOKEN_VIEWPORT_TEXTSTYLE: 127 case SKIN_TOKEN_VIEWPORT_TEXTSTYLE:
@@ -116,7 +131,7 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
116#ifdef HAVE_LCD_COLOR 131#ifdef HAVE_LCD_COLOR
117 case SKIN_TOKEN_VIEWPORT_GRADIENT_SETUP: 132 case SKIN_TOKEN_VIEWPORT_GRADIENT_SETUP:
118 { 133 {
119 struct gradient_config *cfg = token->value.data; 134 struct gradient_config *cfg = SKINOFFSETTOPTR(skin_buffer, token->value.data);
120 vp->lss_pattern = cfg->start; 135 vp->lss_pattern = cfg->start;
121 vp->lse_pattern = cfg->end; 136 vp->lse_pattern = cfg->end;
122 vp->lst_pattern = cfg->text; 137 vp->lst_pattern = cfg->text;
@@ -125,14 +140,18 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
125#endif 140#endif
126 case SKIN_TOKEN_VIEWPORT_ENABLE: 141 case SKIN_TOKEN_VIEWPORT_ENABLE:
127 { 142 {
128 char *label = token->value.data; 143 char *label = SKINOFFSETTOPTR(skin_buffer, token->value.data);
129 char temp = VP_DRAW_HIDEABLE; 144 char temp = VP_DRAW_HIDEABLE;
130 struct skin_element *viewport = gwps->data->tree; 145 struct skin_element *viewport = SKINOFFSETTOPTR(skin_buffer, gwps->data->tree);
131 while (viewport) 146 while (viewport)
132 { 147 {
133 struct skin_viewport *skinvp = (struct skin_viewport*)viewport->data; 148 struct skin_viewport *skinvp = SKINOFFSETTOPTR(skin_buffer, viewport->data);
134 if (skinvp->label && !skinvp->is_infovp && 149
135 !strcmp(skinvp->label, label)) 150 char *vplabel = SKINOFFSETTOPTR(skin_buffer, skinvp->label);
151 if (skinvp->label == VP_DEFAULT_LABEL)
152 vplabel = VP_DEFAULT_LABEL_STRING;
153 if (vplabel && !skinvp->is_infovp &&
154 !strcmp(vplabel, label))
136 { 155 {
137 if (skinvp->hidden_flags&VP_DRAW_HIDDEN) 156 if (skinvp->hidden_flags&VP_DRAW_HIDDEN)
138 { 157 {
@@ -140,7 +159,7 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
140 } 159 }
141 skinvp->hidden_flags = temp; 160 skinvp->hidden_flags = temp;
142 } 161 }
143 viewport = viewport->next; 162 viewport = SKINOFFSETTOPTR(skin_buffer, viewport->next);
144 } 163 }
145 } 164 }
146 break; 165 break;
@@ -148,11 +167,10 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
148 case SKIN_TOKEN_LIST_ITEM_CFG: 167 case SKIN_TOKEN_LIST_ITEM_CFG:
149 if (do_refresh) 168 if (do_refresh)
150 skinlist_set_cfg(gwps->display->screen_type, 169 skinlist_set_cfg(gwps->display->screen_type,
151 token->value.data); 170 SKINOFFSETTOPTR(skin_buffer, token->value.data));
152 break; 171 break;
153 case SKIN_TOKEN_UIVIEWPORT_ENABLE: 172 case SKIN_TOKEN_UIVIEWPORT_ENABLE:
154 sb_set_info_vp(gwps->display->screen_type, 173 sb_set_info_vp(gwps->display->screen_type, token->value.data);
155 token->value.data);
156 break; 174 break;
157 case SKIN_TOKEN_PEAKMETER: 175 case SKIN_TOKEN_PEAKMETER:
158 data->peak_meter_enabled = true; 176 data->peak_meter_enabled = true;
@@ -173,7 +191,7 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
173 case SKIN_TOKEN_TUNER_RSSI_BAR: 191 case SKIN_TOKEN_TUNER_RSSI_BAR:
174 case SKIN_TOKEN_LIST_SCROLLBAR: 192 case SKIN_TOKEN_LIST_SCROLLBAR:
175 { 193 {
176 struct progressbar *bar = (struct progressbar*)token->value.data; 194 struct progressbar *bar = (struct progressbar*)SKINOFFSETTOPTR(skin_buffer, token->value.data);
177 if (do_refresh) 195 if (do_refresh)
178 draw_progressbar(gwps, info->line_number, bar); 196 draw_progressbar(gwps, info->line_number, bar);
179 } 197 }
@@ -183,12 +201,12 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
183 case SKIN_TOKEN_IMAGE_DISPLAY_LISTICON: 201 case SKIN_TOKEN_IMAGE_DISPLAY_LISTICON:
184 case SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY: 202 case SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY:
185 { 203 {
186 struct image_display *id = token->value.data; 204 struct image_display *id = SKINOFFSETTOPTR(skin_buffer, token->value.data);
187 const char* label = id->label; 205 const char* label = SKINOFFSETTOPTR(skin_buffer, id->label);
188 struct gui_img *img = skin_find_item(label,SKIN_FIND_IMAGE, data); 206 struct gui_img *img = skin_find_item(label,SKIN_FIND_IMAGE, data);
189 if (img && img->loaded) 207 if (img && img->loaded)
190 { 208 {
191 if (id->token == NULL) 209 if (SKINOFFSETTOPTR(skin_buffer, id->token) == NULL)
192 { 210 {
193 img->display = id->subimage; 211 img->display = id->subimage;
194 } 212 }
@@ -197,8 +215,8 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
197 char buf[16]; 215 char buf[16];
198 const char *out; 216 const char *out;
199 int a = img->num_subimages; 217 int a = img->num_subimages;
200 out = get_token_value(gwps, id->token, info->offset, 218 out = get_token_value(gwps, SKINOFFSETTOPTR(skin_buffer, id->token),
201 buf, sizeof(buf), &a); 219 info->offset, buf, sizeof(buf), &a);
202 220
203 /* NOTE: get_token_value() returns values starting at 1! */ 221 /* NOTE: get_token_value() returns values starting at 1! */
204 if (a == -1) 222 if (a == -1)
@@ -224,29 +242,32 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
224 } 242 }
225#ifdef HAVE_ALBUMART 243#ifdef HAVE_ALBUMART
226 case SKIN_TOKEN_ALBUMART_DISPLAY: 244 case SKIN_TOKEN_ALBUMART_DISPLAY:
245 {
246 struct skin_albumart *aa = SKINOFFSETTOPTR(skin_buffer, data->albumart);
227 /* now draw the AA */ 247 /* now draw the AA */
228 if (do_refresh && data->albumart) 248 if (do_refresh && aa)
229 { 249 {
230 int handle = playback_current_aa_hid(data->playback_aa_slot); 250 int handle = playback_current_aa_hid(data->playback_aa_slot);
231#if CONFIG_TUNER 251#if CONFIG_TUNER
232 if (in_radio_screen() || (get_radio_status() != FMRADIO_OFF)) 252 if (in_radio_screen() || (get_radio_status() != FMRADIO_OFF))
233 { 253 {
234 struct dim dim = {data->albumart->width, data->albumart->height}; 254 struct dim dim = {aa->width, aa->height};
235 handle = radio_get_art_hid(&dim); 255 handle = radio_get_art_hid(&dim);
236 } 256 }
237#endif 257#endif
238 data->albumart->draw_handle = handle; 258 aa->draw_handle = handle;
239 } 259 }
240 break; 260 break;
261 }
241#endif 262#endif
242 case SKIN_TOKEN_DRAW_INBUILTBAR: 263 case SKIN_TOKEN_DRAW_INBUILTBAR:
243 gui_statusbar_draw(&(statusbars.statusbars[gwps->display->screen_type]), 264 gui_statusbar_draw(&(statusbars.statusbars[gwps->display->screen_type]),
244 info->refresh_type == SKIN_REFRESH_ALL, 265 info->refresh_type == SKIN_REFRESH_ALL,
245 token->value.data); 266 SKINOFFSETTOPTR(skin_buffer, token->value.data));
246 break; 267 break;
247 case SKIN_TOKEN_VIEWPORT_CUSTOMLIST: 268 case SKIN_TOKEN_VIEWPORT_CUSTOMLIST:
248 if (do_refresh) 269 if (do_refresh)
249 skin_render_playlistviewer(token->value.data, gwps, 270 skin_render_playlistviewer(SKINOFFSETTOPTR(skin_buffer, token->value.data), gwps,
250 info->skin_vp, info->refresh_type); 271 info->skin_vp, info->refresh_type);
251 break; 272 break;
252 273
@@ -255,23 +276,24 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
255 case SKIN_TOKEN_VAR_SET: 276 case SKIN_TOKEN_VAR_SET:
256 if (do_refresh) 277 if (do_refresh)
257 { 278 {
258 struct skin_var_changer *data = token->value.data; 279 struct skin_var_changer *data = SKINOFFSETTOPTR(skin_buffer, token->value.data);
280 struct skin_var *var = SKINOFFSETTOPTR(skin_buffer, data->var);
259 if (data->direct) 281 if (data->direct)
260 data->var->value = data->newval; 282 var->value = data->newval;
261 else 283 else
262 { 284 {
263 data->var->value += data->newval; 285 var->value += data->newval;
264 if (data->max) 286 if (data->max)
265 { 287 {
266 if (data->var->value > data->max) 288 if (var->value > data->max)
267 data->var->value = 1; 289 var->value = 1;
268 else if (data->var->value < 1) 290 else if (var->value < 1)
269 data->var->value = data->max; 291 var->value = data->max;
270 } 292 }
271 } 293 }
272 if (data->var->value < 1) 294 if (var->value < 1)
273 data->var->value = 1; 295 var->value = 1;
274 data->var->last_changed = current_tick; 296 var->last_changed = current_tick;
275 } 297 }
276 break; 298 break;
277#endif 299#endif
@@ -289,7 +311,7 @@ static void do_tags_in_hidden_conditional(struct skin_element* branch,
289#ifdef HAVE_LCD_BITMAP 311#ifdef HAVE_LCD_BITMAP
290 struct gui_wps *gwps = info->gwps; 312 struct gui_wps *gwps = info->gwps;
291 struct wps_data *data = gwps->data; 313 struct wps_data *data = gwps->data;
292#endif 314#endif
293 /* Tags here are ones which need to be "turned off" or cleared 315 /* Tags here are ones which need to be "turned off" or cleared
294 * if they are in a conditional branch which isnt being used */ 316 * if they are in a conditional branch which isnt being used */
295 if (branch->type == LINE_ALTERNATOR) 317 if (branch->type == LINE_ALTERNATOR)
@@ -297,12 +319,12 @@ static void do_tags_in_hidden_conditional(struct skin_element* branch,
297 int i; 319 int i;
298 for (i=0; i<branch->children_count; i++) 320 for (i=0; i<branch->children_count; i++)
299 { 321 {
300 do_tags_in_hidden_conditional(branch->children[i], info); 322 do_tags_in_hidden_conditional(get_child(branch->children, i), info);
301 } 323 }
302 } 324 }
303 else if (branch->type == LINE && branch->children_count) 325 else if (branch->type == LINE && branch->children_count)
304 { 326 {
305 struct skin_element *child = branch->children[0]; 327 struct skin_element *child = get_child(branch->children, 0);
306#if defined(HAVE_LCD_BITMAP) || defined(HAVE_ALBUMART) 328#if defined(HAVE_LCD_BITMAP) || defined(HAVE_ALBUMART)
307 struct wps_token *token; 329 struct wps_token *token;
308#endif 330#endif
@@ -313,25 +335,25 @@ static void do_tags_in_hidden_conditional(struct skin_element* branch,
313 int i; 335 int i;
314 for (i=0; i<child->children_count; i++) 336 for (i=0; i<child->children_count; i++)
315 { 337 {
316 do_tags_in_hidden_conditional(child->children[i], info); 338 do_tags_in_hidden_conditional(get_child(child->children, i), info);
317 } 339 }
318 child = child->next; 340 child = SKINOFFSETTOPTR(skin_buffer, child->next);
319 continue; 341 continue;
320 } 342 }
321 else if (child->type != TAG || !child->data) 343 else if (child->type != TAG || !SKINOFFSETTOPTR(skin_buffer, child->data))
322 { 344 {
323 child = child->next; 345 child = SKINOFFSETTOPTR(skin_buffer, child->next);
324 continue; 346 continue;
325 } 347 }
326#if defined(HAVE_LCD_BITMAP) || defined(HAVE_ALBUMART) 348#if defined(HAVE_LCD_BITMAP) || defined(HAVE_ALBUMART)
327 token = (struct wps_token *)child->data; 349 token = (struct wps_token *)SKINOFFSETTOPTR(skin_buffer, child->data);
328#endif 350#endif
329#ifdef HAVE_LCD_BITMAP 351#ifdef HAVE_LCD_BITMAP
330 /* clear all pictures in the conditional and nested ones */ 352 /* clear all pictures in the conditional and nested ones */
331 if (token->type == SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY) 353 if (token->type == SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY)
332 { 354 {
333 struct image_display *id = token->value.data; 355 struct image_display *id = SKINOFFSETTOPTR(skin_buffer, token->value.data);
334 struct gui_img *img = skin_find_item(id->label, 356 struct gui_img *img = skin_find_item(SKINOFFSETTOPTR(skin_buffer, id->label),
335 SKIN_FIND_IMAGE, data); 357 SKIN_FIND_IMAGE, data);
336 clear_image_pos(gwps, img); 358 clear_image_pos(gwps, img);
337 } 359 }
@@ -341,14 +363,18 @@ static void do_tags_in_hidden_conditional(struct skin_element* branch,
341 } 363 }
342 else if (token->type == SKIN_TOKEN_VIEWPORT_ENABLE) 364 else if (token->type == SKIN_TOKEN_VIEWPORT_ENABLE)
343 { 365 {
344 char *label = token->value.data; 366 char *label = SKINOFFSETTOPTR(skin_buffer, token->value.data);
345 struct skin_element *viewport; 367 struct skin_element *viewport;
346 for (viewport = data->tree; 368 for (viewport = SKINOFFSETTOPTR(skin_buffer, data->tree);
347 viewport; 369 viewport;
348 viewport = viewport->next) 370 viewport = SKINOFFSETTOPTR(skin_buffer, viewport->next))
349 { 371 {
350 struct skin_viewport *skin_viewport = (struct skin_viewport*)viewport->data; 372 struct skin_viewport *skin_viewport = SKINOFFSETTOPTR(skin_buffer, viewport->data);
351 if (skin_viewport->label && strcmp(skin_viewport->label, label)) 373
374 char *vplabel = SKINOFFSETTOPTR(skin_buffer, skin_viewport->label);
375 if (skin_viewport->label == VP_DEFAULT_LABEL)
376 vplabel = VP_DEFAULT_LABEL_STRING;
377 if (vplabel && strcmp(vplabel, label))
352 continue; 378 continue;
353 if (skin_viewport->hidden_flags&VP_NEVER_VISIBLE) 379 if (skin_viewport->hidden_flags&VP_NEVER_VISIBLE)
354 { 380 {
@@ -377,7 +403,7 @@ static void do_tags_in_hidden_conditional(struct skin_element* branch,
377 playback_current_aa_hid(data->playback_aa_slot), true); 403 playback_current_aa_hid(data->playback_aa_slot), true);
378 } 404 }
379#endif 405#endif
380 child = child->next; 406 child = SKINOFFSETTOPTR(skin_buffer, child->next);
381 } 407 }
382 } 408 }
383} 409}
@@ -433,7 +459,7 @@ static bool skin_render_line(struct skin_element* line, struct skin_draw_info *i
433 if (line->children_count == 0) 459 if (line->children_count == 0)
434 return false; /* empty line, do nothing */ 460 return false; /* empty line, do nothing */
435 461
436 struct skin_element *child = line->children[0]; 462 struct skin_element *child = get_child(line->children, 0);
437 struct conditional *conditional; 463 struct conditional *conditional;
438 skin_render_func func = skin_render_line; 464 skin_render_func func = skin_render_line;
439 int old_refresh_mode = info->refresh_type; 465 int old_refresh_mode = info->refresh_type;
@@ -442,7 +468,7 @@ static bool skin_render_line(struct skin_element* line, struct skin_draw_info *i
442 switch (child->type) 468 switch (child->type)
443 { 469 {
444 case CONDITIONAL: 470 case CONDITIONAL:
445 conditional = (struct conditional*)child->data; 471 conditional = SKINOFFSETTOPTR(skin_buffer, child->data);
446 last_value = conditional->last_value; 472 last_value = conditional->last_value;
447 value = evaluate_conditional(info->gwps, info->offset, 473 value = evaluate_conditional(info->gwps, info->offset,
448 conditional, child->children_count); 474 conditional, child->children_count);
@@ -456,20 +482,20 @@ static bool skin_render_line(struct skin_element* line, struct skin_draw_info *i
456 { 482 {
457 /* we are in a false branch of a %?aa<true> conditional */ 483 /* we are in a false branch of a %?aa<true> conditional */
458 if (last_value == 0) 484 if (last_value == 0)
459 do_tags_in_hidden_conditional(child->children[0], info); 485 do_tags_in_hidden_conditional(get_child(child->children, 0), info);
460 break; 486 break;
461 } 487 }
462 } 488 }
463 else 489 else
464 { 490 {
465 if (last_value >= 0 && value != last_value && last_value < child->children_count) 491 if (last_value >= 0 && value != last_value && last_value < child->children_count)
466 do_tags_in_hidden_conditional(child->children[last_value], info); 492 do_tags_in_hidden_conditional(get_child(child->children, last_value), info);
467 } 493 }
468 if (child->children[value]->type == LINE_ALTERNATOR) 494 if (get_child(child->children, value)->type == LINE_ALTERNATOR)
469 { 495 {
470 func = skin_render_alternator; 496 func = skin_render_alternator;
471 } 497 }
472 else if (child->children[value]->type == LINE) 498 else if (get_child(child->children, value)->type == LINE)
473 func = skin_render_line; 499 func = skin_render_line;
474 500
475 if (value != last_value) 501 if (value != last_value)
@@ -478,7 +504,7 @@ static bool skin_render_line(struct skin_element* line, struct skin_draw_info *i
478 info->force_redraw = true; 504 info->force_redraw = true;
479 } 505 }
480 506
481 if (func(child->children[value], info)) 507 if (func(get_child(child->children, value), info))
482 needs_update = true; 508 needs_update = true;
483 else 509 else
484 needs_update = needs_update || (last_value != value); 510 needs_update = needs_update || (last_value != value);
@@ -493,14 +519,14 @@ static bool skin_render_line(struct skin_element* line, struct skin_draw_info *i
493 519
494 fix_line_alignment(info, child); 520 fix_line_alignment(info, child);
495 521
496 if (!child->data) 522 if (!SKINOFFSETTOPTR(skin_buffer, child->data))
497 { 523 {
498 break; 524 break;
499 } 525 }
500 if (!do_non_text_tags(info->gwps, info, child, &info->skin_vp->vp)) 526 if (!do_non_text_tags(info->gwps, info, child, &info->skin_vp->vp))
501 { 527 {
502 static char tempbuf[128]; 528 static char tempbuf[128];
503 const char *valuestr = get_token_value(info->gwps, child->data, 529 const char *valuestr = get_token_value(info->gwps, SKINOFFSETTOPTR(skin_buffer, child->data),
504 info->offset, tempbuf, 530 info->offset, tempbuf,
505 sizeof(tempbuf), NULL); 531 sizeof(tempbuf), NULL);
506 if (valuestr) 532 if (valuestr)
@@ -517,7 +543,7 @@ static bool skin_render_line(struct skin_element* line, struct skin_draw_info *i
517 } 543 }
518 break; 544 break;
519 case TEXT: 545 case TEXT:
520 strlcat(info->cur_align_start, child->data, 546 strlcat(info->cur_align_start, SKINOFFSETTOPTR(skin_buffer, child->data),
521 info->buf_size - (info->cur_align_start-info->buf)); 547 info->buf_size - (info->cur_align_start-info->buf));
522 needs_update = needs_update || 548 needs_update = needs_update ||
523 (info->refresh_type&SKIN_REFRESH_STATIC) != 0; 549 (info->refresh_type&SKIN_REFRESH_STATIC) != 0;
@@ -527,7 +553,7 @@ static bool skin_render_line(struct skin_element* line, struct skin_draw_info *i
527 break; 553 break;
528 } 554 }
529 555
530 child = child->next; 556 child = SKINOFFSETTOPTR(skin_buffer, child->next);
531 } 557 }
532 return needs_update; 558 return needs_update;
533} 559}
@@ -541,29 +567,29 @@ static int get_subline_timeout(struct gui_wps *gwps, struct skin_element* line)
541 { 567 {
542 if (element->children_count == 0) 568 if (element->children_count == 0)
543 return retval; /* empty line, so force redraw */ 569 return retval; /* empty line, so force redraw */
544 element = element->children[0]; 570 element = get_child(element->children, 0);
545 } 571 }
546 while (element) 572 while (element)
547 { 573 {
548 if (element->type == TAG && 574 if (element->type == TAG &&
549 element->tag->type == SKIN_TOKEN_SUBLINE_TIMEOUT ) 575 element->tag->type == SKIN_TOKEN_SUBLINE_TIMEOUT )
550 { 576 {
551 token = element->data; 577 token = SKINOFFSETTOPTR(skin_buffer, element->data);
552 return token->value.i; 578 return token->value.i;
553 } 579 }
554 else if (element->type == CONDITIONAL) 580 else if (element->type == CONDITIONAL)
555 { 581 {
556 struct conditional *conditional = element->data; 582 struct conditional *conditional = SKINOFFSETTOPTR(skin_buffer, element->data);
557 int val = evaluate_conditional(gwps, 0, conditional, 583 int val = evaluate_conditional(gwps, 0, conditional,
558 element->children_count); 584 element->children_count);
559 if (val >= 0) 585 if (val >= 0)
560 { 586 {
561 retval = get_subline_timeout(gwps, element->children[val]); 587 retval = get_subline_timeout(gwps, get_child(element->children, val));
562 if (retval >= 0) 588 if (retval >= 0)
563 return retval; 589 return retval;
564 } 590 }
565 } 591 }
566 element = element->next; 592 element = SKINOFFSETTOPTR(skin_buffer, element->next);
567 } 593 }
568 return retval; 594 return retval;
569} 595}
@@ -571,7 +597,7 @@ static int get_subline_timeout(struct gui_wps *gwps, struct skin_element* line)
571bool skin_render_alternator(struct skin_element* element, struct skin_draw_info *info) 597bool skin_render_alternator(struct skin_element* element, struct skin_draw_info *info)
572{ 598{
573 bool changed_lines = false; 599 bool changed_lines = false;
574 struct line_alternator *alternator = (struct line_alternator*)element->data; 600 struct line_alternator *alternator = SKINOFFSETTOPTR(skin_buffer, element->data);
575 unsigned old_refresh = info->refresh_type; 601 unsigned old_refresh = info->refresh_type;
576 if (info->refresh_type == SKIN_REFRESH_ALL) 602 if (info->refresh_type == SKIN_REFRESH_ALL)
577 { 603 {
@@ -597,11 +623,11 @@ bool skin_render_alternator(struct skin_element* element, struct skin_draw_info
597 try_line++; 623 try_line++;
598 if (try_line >= element->children_count) 624 if (try_line >= element->children_count)
599 try_line = 0; 625 try_line = 0;
600 if (element->children[try_line]->children_count != 0) 626 if (get_child(element->children, try_line)->children_count != 0)
601 { 627 {
602 current_line = element->children[try_line]; 628 current_line = get_child(element->children, try_line);
603 rettimeout = get_subline_timeout(info->gwps, 629 rettimeout = get_subline_timeout(info->gwps,
604 current_line->children[0]); 630 get_child(current_line->children, 0));
605 if (rettimeout > 0) 631 if (rettimeout > 0)
606 { 632 {
607 suitable = true; 633 suitable = true;
@@ -619,7 +645,7 @@ bool skin_render_alternator(struct skin_element* element, struct skin_draw_info
619 info->refresh_type = SKIN_REFRESH_ALL; 645 info->refresh_type = SKIN_REFRESH_ALL;
620 info->force_redraw = true; 646 info->force_redraw = true;
621 } 647 }
622 bool ret = skin_render_line(element->children[alternator->current_line], info); 648 bool ret = skin_render_line(get_child(element->children, alternator->current_line), info);
623 info->refresh_type = old_refresh; 649 info->refresh_type = old_refresh;
624 return changed_lines || ret; 650 return changed_lines || ret;
625} 651}
@@ -646,14 +672,17 @@ void skin_render_viewport(struct skin_element* viewport, struct gui_wps *gwps,
646 672
647 struct align_pos * align = &info.align; 673 struct align_pos * align = &info.align;
648 bool needs_update; 674 bool needs_update;
675 skin_buffer = get_skin_buffer(gwps->data);
676 skinparser_set_buffer(skin_buffer);
649#ifdef HAVE_LCD_BITMAP 677#ifdef HAVE_LCD_BITMAP
650 /* Set images to not to be displayed */ 678 /* Set images to not to be displayed */
651 struct skin_token_list *imglist = gwps->data->images; 679 struct skin_token_list *imglist = SKINOFFSETTOPTR(skin_buffer, gwps->data->images);
652 while (imglist) 680 while (imglist)
653 { 681 {
654 struct gui_img *img = (struct gui_img *)imglist->token->value.data; 682 struct wps_token *token = SKINOFFSETTOPTR(skin_buffer, imglist->token);
683 struct gui_img *img = (struct gui_img *)SKINOFFSETTOPTR(skin_buffer, token->value.data);
655 img->display = -1; 684 img->display = -1;
656 imglist = imglist->next; 685 imglist = SKINOFFSETTOPTR(skin_buffer, imglist->next);
657 } 686 }
658 687
659 /* fix font ID's */ 688 /* fix font ID's */
@@ -716,7 +745,7 @@ void skin_render_viewport(struct skin_element* viewport, struct gui_wps *gwps,
716 } 745 }
717 if (!info.no_line_break) 746 if (!info.no_line_break)
718 info.line_number++; 747 info.line_number++;
719 line = line->next; 748 line = SKINOFFSETTOPTR(skin_buffer, line->next);
720 } 749 }
721#ifdef HAVE_LCD_BITMAP 750#ifdef HAVE_LCD_BITMAP
722 wps_display_images(gwps, &skin_viewport->vp); 751 wps_display_images(gwps, &skin_viewport->vp);
@@ -730,8 +759,11 @@ void skin_render(struct gui_wps *gwps, unsigned refresh_mode)
730 759
731 struct skin_element* viewport; 760 struct skin_element* viewport;
732 struct skin_viewport* skin_viewport; 761 struct skin_viewport* skin_viewport;
762 char *label;
733 763
734 int old_refresh_mode = refresh_mode; 764 int old_refresh_mode = refresh_mode;
765 skin_buffer = get_skin_buffer(gwps->data);
766 skinparser_set_buffer(skin_buffer);
735 767
736#ifdef HAVE_LCD_CHARCELLS 768#ifdef HAVE_LCD_CHARCELLS
737 int i; 769 int i;
@@ -741,18 +773,21 @@ void skin_render(struct gui_wps *gwps, unsigned refresh_mode)
741 data->wps_progress_pat[i] = display->get_locked_pattern(); 773 data->wps_progress_pat[i] = display->get_locked_pattern();
742 } 774 }
743#endif 775#endif
744 viewport = data->tree; 776 viewport = SKINOFFSETTOPTR(skin_buffer, data->tree);
745 skin_viewport = (struct skin_viewport *)viewport->data; 777 skin_viewport = SKINOFFSETTOPTR(skin_buffer, viewport->data);
746 if (skin_viewport->label && viewport->next && 778 label = SKINOFFSETTOPTR(skin_buffer, skin_viewport->label);
747 !strcmp(skin_viewport->label,VP_DEFAULT_LABEL)) 779 if (skin_viewport->label == VP_DEFAULT_LABEL)
780 label = VP_DEFAULT_LABEL_STRING;
781 if (label && SKINOFFSETTOPTR(skin_buffer, viewport->next) &&
782 !strcmp(label,VP_DEFAULT_LABEL_STRING))
748 refresh_mode = 0; 783 refresh_mode = 0;
749 784
750 for (viewport = data->tree; 785 for (viewport = SKINOFFSETTOPTR(skin_buffer, data->tree);
751 viewport; 786 viewport;
752 viewport = viewport->next) 787 viewport = SKINOFFSETTOPTR(skin_buffer, viewport->next))
753 { 788 {
754 /* SETUP */ 789 /* SETUP */
755 skin_viewport = (struct skin_viewport*)viewport->data; 790 skin_viewport = SKINOFFSETTOPTR(skin_buffer, viewport->data);
756 unsigned vp_refresh_mode = refresh_mode; 791 unsigned vp_refresh_mode = refresh_mode;
757#if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1) 792#if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1)
758 skin_viewport->vp.fg_pattern = skin_viewport->start_fgcolour; 793 skin_viewport->vp.fg_pattern = skin_viewport->start_fgcolour;
@@ -789,7 +824,7 @@ void skin_render(struct gui_wps *gwps, unsigned refresh_mode)
789 } 824 }
790 /* render */ 825 /* render */
791 if (viewport->children_count) 826 if (viewport->children_count)
792 skin_render_viewport(viewport->children[0], gwps, 827 skin_render_viewport(get_child(viewport->children, 0), gwps,
793 skin_viewport, vp_refresh_mode); 828 skin_viewport, vp_refresh_mode);
794 refresh_mode = old_refresh_mode; 829 refresh_mode = old_refresh_mode;
795 } 830 }
@@ -826,7 +861,7 @@ void skin_render_playlistviewer(struct playlistviewer* viewer,
826 struct align_pos * align = &info.align; 861 struct align_pos * align = &info.align;
827 bool needs_update; 862 bool needs_update;
828 int cur_pos, start_item, max; 863 int cur_pos, start_item, max;
829 int nb_lines = viewport_get_nb_lines(viewer->vp); 864 int nb_lines = viewport_get_nb_lines(SKINOFFSETTOPTR(skin_buffer, viewer->vp));
830#if CONFIG_TUNER 865#if CONFIG_TUNER
831 if (get_current_activity() == ACTIVITY_FM) 866 if (get_current_activity() == ACTIVITY_FM)
832 { 867 {
@@ -848,7 +883,7 @@ void skin_render_playlistviewer(struct playlistviewer* viewer,
848 if (max-start_item > nb_lines) 883 if (max-start_item > nb_lines)
849 max = start_item + nb_lines; 884 max = start_item + nb_lines;
850 885
851 line = viewer->line; 886 line = SKINOFFSETTOPTR(skin_buffer, viewer->line);
852 while (start_item < max) 887 while (start_item < max)
853 { 888 {
854 linebuf[0] = '\0'; 889 linebuf[0] = '\0';
diff --git a/apps/gui/skin_engine/skin_tokens.c b/apps/gui/skin_engine/skin_tokens.c
index 6f154a4d53..bb9466c134 100644
--- a/apps/gui/skin_engine/skin_tokens.c
+++ b/apps/gui/skin_engine/skin_tokens.c
@@ -36,6 +36,7 @@
36#include "debug.h" 36#include "debug.h"
37#include "cuesheet.h" 37#include "cuesheet.h"
38#include "replaygain.h" 38#include "replaygain.h"
39#include "core_alloc.h"
39#ifdef HAVE_LCD_CHARCELLS 40#ifdef HAVE_LCD_CHARCELLS
40#include "hwcompat.h" 41#include "hwcompat.h"
41#endif 42#endif
@@ -732,18 +733,21 @@ static const char* NOINLINE get_lif_token_value(struct gui_wps *gwps,
732{ 733{
733 int a = lif->num_options; 734 int a = lif->num_options;
734 int b; 735 int b;
735 const char* out_text = get_token_value(gwps, lif->token, offset, 736 struct wps_token *liftoken = SKINOFFSETTOPTR(get_skin_buffer(gwps->data), lif->token);
736 buf, buf_size, &a); 737 const char* out_text = get_token_value(gwps, liftoken, offset, buf, buf_size, &a);
737 if (a == -1 && lif->token->type != SKIN_TOKEN_VOLUME) 738 if (a == -1 && liftoken->type != SKIN_TOKEN_VOLUME)
738 a = (out_text && *out_text) ? 1 : 0; 739 a = (out_text && *out_text) ? 1 : 0;
739 switch (lif->operand.type) 740 switch (lif->operand.type)
740 { 741 {
741 case STRING: 742 case STRING:
743 {
744 char *cmp = SKINOFFSETTOPTR(get_skin_buffer(gwps->data), lif->operand.data.text);
742 if (out_text == NULL) 745 if (out_text == NULL)
743 return NULL; 746 return NULL;
744 a = strcmp(out_text, lif->operand.data.text); 747 a = strcmp(out_text, cmp);
745 b = 0; 748 b = 0;
746 break; 749 break;
750 }
747 case INTEGER: 751 case INTEGER:
748 case DECIMAL: 752 case DECIMAL:
749 b = lif->operand.data.number; 753 b = lif->operand.data.number;
@@ -752,11 +756,12 @@ static const char* NOINLINE get_lif_token_value(struct gui_wps *gwps,
752 { 756 {
753 char temp_buf[MAX_PATH]; 757 char temp_buf[MAX_PATH];
754 const char *outb; 758 const char *outb;
755 struct wps_token *token = lif->operand.data.code->data; 759 struct skin_element *element = SKINOFFSETTOPTR(get_skin_buffer(gwps->data), lif->operand.data.code);
760 struct wps_token *token = SKINOFFSETTOPTR(get_skin_buffer(gwps->data), element->data);
756 b = lif->num_options; 761 b = lif->num_options;
757 outb = get_token_value(gwps, token, offset, temp_buf, 762 outb = get_token_value(gwps, token, offset, temp_buf,
758 sizeof(temp_buf), &b); 763 sizeof(temp_buf), &b);
759 if (b == -1 && lif->token->type != SKIN_TOKEN_VOLUME) 764 if (b == -1 && liftoken->type != SKIN_TOKEN_VOLUME)
760 { 765 {
761 if (!out_text || !outb) 766 if (!out_text || !outb)
762 return (lif->op == IF_EQUALS) ? NULL : "neq"; 767 return (lif->op == IF_EQUALS) ? NULL : "neq";
@@ -865,14 +870,15 @@ const char *get_token_value(struct gui_wps *gwps,
865 { 870 {
866 case SKIN_TOKEN_LOGICAL_IF: 871 case SKIN_TOKEN_LOGICAL_IF:
867 { 872 {
868 struct logical_if *lif = token->value.data; 873 struct logical_if *lif = SKINOFFSETTOPTR(get_skin_buffer(data), token->value.data);
869 return get_lif_token_value(gwps, lif, offset, buf, buf_size); 874 return get_lif_token_value(gwps, lif, offset, buf, buf_size);
870 } 875 }
871 break; 876 break;
872 case SKIN_TOKEN_SUBSTRING: 877 case SKIN_TOKEN_SUBSTRING:
873 { 878 {
874 struct substring *ss = token->value.data; 879 struct substring *ss = SKINOFFSETTOPTR(get_skin_buffer(data), token->value.data);
875 const char *token_val = get_token_value(gwps, ss->token, offset, 880 const char *token_val = get_token_value(gwps,
881 SKINOFFSETTOPTR(get_skin_buffer(data), ss->token), offset,
876 buf, buf_size, intval); 882 buf, buf_size, intval);
877 if (token_val) 883 if (token_val)
878 { 884 {
@@ -909,7 +915,7 @@ const char *get_token_value(struct gui_wps *gwps,
909 return &(token->value.c); 915 return &(token->value.c);
910 916
911 case SKIN_TOKEN_STRING: 917 case SKIN_TOKEN_STRING:
912 return (char*)token->value.data; 918 return (char*)SKINOFFSETTOPTR(get_skin_buffer(data), token->value.data);
913 919
914 case SKIN_TOKEN_TRANSLATEDSTRING: 920 case SKIN_TOKEN_TRANSLATEDSTRING:
915 return (char*)P2STR(ID2P(token->value.i)); 921 return (char*)P2STR(ID2P(token->value.i));
@@ -929,7 +935,7 @@ const char *get_token_value(struct gui_wps *gwps,
929 return buf; 935 return buf;
930 case SKIN_TOKEN_LIST_ITEM_TEXT: 936 case SKIN_TOKEN_LIST_ITEM_TEXT:
931 { 937 {
932 struct listitem *li = (struct listitem *)token->value.data; 938 struct listitem *li = (struct listitem *)SKINOFFSETTOPTR(get_skin_buffer(data), token->value.data);
933 return skinlist_get_item_text(li->offset, li->wrap, buf, buf_size); 939 return skinlist_get_item_text(li->offset, li->wrap, buf, buf_size);
934 } 940 }
935 case SKIN_TOKEN_LIST_ITEM_NUMBER: 941 case SKIN_TOKEN_LIST_ITEM_NUMBER:
@@ -941,7 +947,7 @@ const char *get_token_value(struct gui_wps *gwps,
941 return skinlist_is_selected_item()?"s":""; 947 return skinlist_is_selected_item()?"s":"";
942 case SKIN_TOKEN_LIST_ITEM_ICON: 948 case SKIN_TOKEN_LIST_ITEM_ICON:
943 { 949 {
944 struct listitem *li = (struct listitem *)token->value.data; 950 struct listitem *li = (struct listitem *)SKINOFFSETTOPTR(get_skin_buffer(data), token->value.data);
945 int icon = skinlist_get_item_icon(li->offset, li->wrap); 951 int icon = skinlist_get_item_icon(li->offset, li->wrap);
946 if (intval) 952 if (intval)
947 *intval = icon; 953 *intval = icon;
@@ -997,14 +1003,15 @@ const char *get_token_value(struct gui_wps *gwps,
997 return buf; 1003 return buf;
998#ifdef HAVE_ALBUMART 1004#ifdef HAVE_ALBUMART
999 case SKIN_TOKEN_ALBUMART_FOUND: 1005 case SKIN_TOKEN_ALBUMART_FOUND:
1000 if (data->albumart) 1006 if (SKINOFFSETTOPTR(get_skin_buffer(data), data->albumart))
1001 { 1007 {
1002 int handle = -1; 1008 int handle = -1;
1003 handle = playback_current_aa_hid(data->playback_aa_slot); 1009 handle = playback_current_aa_hid(data->playback_aa_slot);
1004#if CONFIG_TUNER 1010#if CONFIG_TUNER
1005 if (in_radio_screen() || (get_radio_status() != FMRADIO_OFF)) 1011 if (in_radio_screen() || (get_radio_status() != FMRADIO_OFF))
1006 { 1012 {
1007 struct dim dim = {data->albumart->width, data->albumart->height}; 1013 struct skin_albumart *aa = SKINOFFSETTOPTR(get_skin_buffer(data), data->albumart);
1014 struct dim dim = {aa->width, aa->height};
1008 handle = radio_get_art_hid(&dim); 1015 handle = radio_get_art_hid(&dim);
1009 } 1016 }
1010#endif 1017#endif
@@ -1473,9 +1480,11 @@ const char *get_token_value(struct gui_wps *gwps,
1473 { 1480 {
1474#ifdef HAVE_TOUCHSCREEN 1481#ifdef HAVE_TOUCHSCREEN
1475 unsigned int last_touch = touchscreen_last_touch(); 1482 unsigned int last_touch = touchscreen_last_touch();
1476 struct touchregion_lastpress *data = token->value.data; 1483 char *skin_base = get_skin_buffer(data);
1477 if (data->region) 1484 struct touchregion_lastpress *data = SKINOFFSETTOPTR(skin_base, token->value.data);
1478 last_touch = data->region->last_press; 1485 struct touchregion *region = SKINOFFSETTOPTR(skin_base, data->region);
1486 if (region)
1487 last_touch = region->last_press;
1479 1488
1480 if (last_touch != 0xffff && 1489 if (last_touch != 0xffff &&
1481 TIME_BEFORE(current_tick, data->timeout + last_touch)) 1490 TIME_BEFORE(current_tick, data->timeout + last_touch))
@@ -1805,7 +1814,8 @@ const char *get_token_value(struct gui_wps *gwps,
1805#ifdef HAVE_SKIN_VARIABLES 1814#ifdef HAVE_SKIN_VARIABLES
1806 case SKIN_TOKEN_VAR_GETVAL: 1815 case SKIN_TOKEN_VAR_GETVAL:
1807 { 1816 {
1808 struct skin_var* var = token->value.data; 1817 char *skin_base = get_skin_buffer(data);
1818 struct skin_var* var = SKINOFFSETTOPTR(skin_base, token->value.data);
1809 if (intval) 1819 if (intval)
1810 *intval = var->value; 1820 *intval = var->value;
1811 snprintf(buf, buf_size, "%d", var->value); 1821 snprintf(buf, buf_size, "%d", var->value);
@@ -1814,8 +1824,10 @@ const char *get_token_value(struct gui_wps *gwps,
1814 break; 1824 break;
1815 case SKIN_TOKEN_VAR_TIMEOUT: 1825 case SKIN_TOKEN_VAR_TIMEOUT:
1816 { 1826 {
1817 struct skin_var_lastchange *data = token->value.data; 1827 char *skin_base = get_skin_buffer(data);
1818 unsigned int last_change = data->var->last_changed; 1828 struct skin_var_lastchange *data = SKINOFFSETTOPTR(skin_base, token->value.data);
1829 struct skin_var* var = SKINOFFSETTOPTR(skin_base, data->var);
1830 unsigned int last_change = var->last_changed;
1819 1831
1820 if (last_change != 0xffff && 1832 if (last_change != 0xffff &&
1821 TIME_BEFORE(current_tick, data->timeout + last_change)) 1833 TIME_BEFORE(current_tick, data->timeout + last_change))
diff --git a/apps/gui/skin_engine/skin_tokens.h b/apps/gui/skin_engine/skin_tokens.h
deleted file mode 100644
index bfca7b7f8d..0000000000
--- a/apps/gui/skin_engine/skin_tokens.h
+++ /dev/null
@@ -1,49 +0,0 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2007 Nicolas Pennequin
11 *
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.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#ifndef _SKIN_TOKENS_H_
23#define _SKIN_TOKENS_H_
24
25#include <stdbool.h>
26#include "tag_table.h"
27
28struct wps_token {
29 union {
30 char c;
31 unsigned short i;
32 long l;
33 void* data;
34 } value;
35
36 enum skin_token_type type; /* enough to store the token type */
37 /* Whether the tag (e.g. track name or the album) refers the
38 current or the next song (false=current, true=next) */
39 bool next;
40};
41
42struct skin_token_list {
43 struct wps_token *token;
44 struct skin_token_list *next;
45};
46
47char* get_dir(char* buf, int buf_size, const char* path, int level);
48
49#endif
diff --git a/apps/gui/skin_engine/skin_touchsupport.c b/apps/gui/skin_engine/skin_touchsupport.c
index 64c797942c..59687bd99b 100644
--- a/apps/gui/skin_engine/skin_touchsupport.c
+++ b/apps/gui/skin_engine/skin_touchsupport.c
@@ -37,11 +37,14 @@
37/** Disarms all touchregions. */ 37/** Disarms all touchregions. */
38void skin_disarm_touchregions(struct wps_data *data) 38void skin_disarm_touchregions(struct wps_data *data)
39{ 39{
40 struct skin_token_list *regions = data->touchregions; 40 char* skin_buffer = get_skin_buffer(data);
41 struct skin_token_list *regions = SKINOFFSETTOPTR(skin_buffer, data->touchregions);
41 while (regions) 42 while (regions)
42 { 43 {
43 ((struct touchregion *)regions->token->value.data)->armed = false; 44 struct wps_token *token = SKINOFFSETTOPTR(skin_buffer, regions->token);
44 regions = regions->next; 45 struct touchregion *region = SKINOFFSETTOPTR(skin_buffer, token->value.data);
46 region->armed = false;
47 regions = SKINOFFSETTOPTR(skin_buffer, regions->next);
45 } 48 }
46} 49}
47 50
@@ -56,35 +59,39 @@ int skin_get_touchaction(struct wps_data *data, int* edge_offset,
56 short x,y; 59 short x,y;
57 short vx, vy; 60 short vx, vy;
58 int type = action_get_touchscreen_press(&x, &y); 61 int type = action_get_touchscreen_press(&x, &y);
62 struct skin_viewport *wvp;
59 struct touchregion *r, *temp = NULL; 63 struct touchregion *r, *temp = NULL;
64 char* skin_buffer = get_skin_buffer(data);
60 bool repeated = (type == BUTTON_REPEAT); 65 bool repeated = (type == BUTTON_REPEAT);
61 bool released = (type == BUTTON_REL); 66 bool released = (type == BUTTON_REL);
62 bool pressed = (type == BUTTON_TOUCHSCREEN); 67 bool pressed = (type == BUTTON_TOUCHSCREEN);
63 struct skin_token_list *regions = data->touchregions; 68 struct skin_token_list *regions = SKINOFFSETTOPTR(skin_buffer, data->touchregions);
64 bool needs_repeat; 69 bool needs_repeat;
65 70
66 while (regions) 71 while (regions)
67 { 72 {
68 r = (struct touchregion *)regions->token->value.data; 73 struct wps_token *token = SKINOFFSETTOPTR(skin_buffer, regions->token);
74 r = SKINOFFSETTOPTR(skin_buffer, token->value.data);
75 wvp = SKINOFFSETTOPTR(skin_buffer, r->wvp);
69 /* make sure this region's viewport is visible */ 76 /* make sure this region's viewport is visible */
70 if (r->wvp->hidden_flags&VP_DRAW_HIDDEN) 77 if (wvp->hidden_flags&VP_DRAW_HIDDEN)
71 { 78 {
72 regions = regions->next; 79 regions = SKINOFFSETTOPTR(skin_buffer, regions->next);
73 continue; 80 continue;
74 } 81 }
75 if (data->touchscreen_locked && 82 if (data->touchscreen_locked &&
76 (r->action != ACTION_TOUCH_SOFTLOCK && !r->allow_while_locked)) 83 (r->action != ACTION_TOUCH_SOFTLOCK && !r->allow_while_locked))
77 { 84 {
78 regions = regions->next; 85 regions = SKINOFFSETTOPTR(skin_buffer, regions->next);
79 continue; 86 continue;
80 } 87 }
81 needs_repeat = r->press_length != PRESS; 88 needs_repeat = r->press_length != PRESS;
82 /* check if it's inside this viewport */ 89 /* check if it's inside this viewport */
83 if (viewport_point_within_vp(&(r->wvp->vp), x, y)) 90 if (viewport_point_within_vp(&(wvp->vp), x, y))
84 { /* reposition the touch inside the viewport since touchregions 91 { /* reposition the touch inside the viewport since touchregions
85 * are relative to a preceding viewport */ 92 * are relative to a preceding viewport */
86 vx = x - r->wvp->vp.x; 93 vx = x - wvp->vp.x;
87 vy = y - r->wvp->vp.y; 94 vy = y - wvp->vp.y;
88 /* now see if the point is inside this region */ 95 /* now see if the point is inside this region */
89 if (vx >= r->x && vx < r->x+r->width && 96 if (vx >= r->x && vx < r->x+r->width &&
90 vy >= r->y && vy < r->y+r->height) 97 vy >= r->y && vy < r->y+r->height)
@@ -127,7 +134,7 @@ int skin_get_touchaction(struct wps_data *data, int* edge_offset,
127 } 134 }
128 } 135 }
129 } 136 }
130 regions = regions->next; 137 regions = SKINOFFSETTOPTR(skin_buffer, regions->next);
131 } 138 }
132 139
133 /* On release, all regions are disarmed. */ 140 /* On release, all regions are disarmed. */
@@ -214,7 +221,7 @@ int skin_get_touchaction(struct wps_data *data, int* edge_offset,
214 { 221 {
215 case F_T_CUSTOM: 222 case F_T_CUSTOM:
216 s->custom_setting 223 s->custom_setting
217 ->load_from_cfg(s->setting, data->value.text); 224 ->load_from_cfg(s->setting, SKINOFFSETTOPTR(skin_buffer, data->value.text));
218 break; 225 break;
219 case F_T_INT: 226 case F_T_INT:
220 case F_T_UINT: 227 case F_T_UINT:
diff --git a/apps/gui/skin_engine/wps_internals.h b/apps/gui/skin_engine/wps_internals.h
index ed09ad0938..65a063592f 100644
--- a/apps/gui/skin_engine/wps_internals.h
+++ b/apps/gui/skin_engine/wps_internals.h
@@ -25,6 +25,11 @@
25#ifndef _WPS_ENGINE_INTERNALS_ 25#ifndef _WPS_ENGINE_INTERNALS_
26#define _WPS_ENGINE_INTERNALS_ 26#define _WPS_ENGINE_INTERNALS_
27 27
28#include "tag_table.h"
29#include "skin_parser.h"
30#ifndef __PCTOOL__
31#include "core_alloc.h"
32#endif
28 33
29/* Timeout unit expressed in HZ. In WPS, all timeouts are given in seconds 34/* Timeout unit expressed in HZ. In WPS, all timeouts are given in seconds
30 (possibly with a decimal fraction) but stored as integer values. 35 (possibly with a decimal fraction) but stored as integer values.
@@ -33,52 +38,48 @@
33#define TIMEOUT_UNIT (HZ/10) /* I.e. 0.1 sec */ 38#define TIMEOUT_UNIT (HZ/10) /* I.e. 0.1 sec */
34#define DEFAULT_SUBLINE_TIME_MULTIPLIER 20 /* In TIMEOUT_UNIT's */ 39#define DEFAULT_SUBLINE_TIME_MULTIPLIER 20 /* In TIMEOUT_UNIT's */
35 40
36#include "skin_tokens.h"
37#include "tag_table.h"
38#include "skin_parser.h"
39
40
41/* TODO: sort this mess out */ 41/* TODO: sort this mess out */
42 42
43#include "screen_access.h" 43#include "screen_access.h"
44#include "statusbar.h" 44#include "statusbar.h"
45#include "metadata.h" 45#include "metadata.h"
46 46
47/* alignments */
48#define WPS_ALIGN_RIGHT 32
49#define WPS_ALIGN_CENTER 64
50#define WPS_ALIGN_LEFT 128
51
52 47
53#define TOKEN_VALUE_ONLY 0x0DEADC0D 48#define TOKEN_VALUE_ONLY 0x0DEADC0D
54 49
55#ifdef HAVE_ALBUMART 50/* wps_data*/
56 51struct wps_token {
57/* albumart definitions */ 52 union {
58#define WPS_ALBUMART_NONE 0 /* WPS does not contain AA tag */ 53 char c;
59#define WPS_ALBUMART_CHECK 1 /* WPS contains AA conditional tag */ 54 unsigned short i;
60#define WPS_ALBUMART_LOAD 2 /* WPS contains AA tag */ 55 long l;
56 OFFSETTYPE(void*) data;
57 } value;
58
59 enum skin_token_type type; /* enough to store the token type */
60 /* Whether the tag (e.g. track name or the album) refers the
61 current or the next song (false=current, true=next) */
62 bool next;
63};
61 64
62#define WPS_ALBUMART_ALIGN_RIGHT 1 /* x align: right */ 65char* get_dir(char* buf, int buf_size, const char* path, int level);
63#define WPS_ALBUMART_ALIGN_CENTER 2 /* x/y align: center */
64#define WPS_ALBUMART_ALIGN_LEFT 4 /* x align: left */
65#define WPS_ALBUMART_ALIGN_TOP 1 /* y align: top */
66#define WPS_ALBUMART_ALIGN_BOTTOM 4 /* y align: bottom */
67 66
68#endif /* HAVE_ALBUMART */
69 67
70/* wps_data*/ 68struct skin_token_list {
69 OFFSETTYPE(struct wps_token *) token;
70 OFFSETTYPE(struct skin_token_list *) next;
71};
71 72
72#ifdef HAVE_LCD_BITMAP 73#ifdef HAVE_LCD_BITMAP
73struct gui_img { 74struct gui_img {
74 struct viewport* vp; /* The viewport to display this image in */ 75 OFFSETTYPE(struct viewport*) vp; /* The viewport to display this image in */
75 short int x; /* x-pos */ 76 short int x; /* x-pos */
76 short int y; /* y-pos */ 77 short int y; /* y-pos */
77 short int num_subimages; /* number of sub-images */ 78 short int num_subimages; /* number of sub-images */
78 short int subimage_height; /* height of each sub-image */ 79 short int subimage_height; /* height of each sub-image */
79 struct bitmap bm; 80 struct bitmap bm;
80 int buflib_handle; 81 int buflib_handle;
81 const char *label; 82 OFFSETTYPE(char*) label;
82 bool loaded; /* load state */ 83 bool loaded; /* load state */
83 bool always_display; /* not using the preload/display mechanism */ 84 bool always_display; /* not using the preload/display mechanism */
84 int display; 85 int display;
@@ -86,15 +87,15 @@ struct gui_img {
86}; 87};
87 88
88struct image_display { 89struct image_display {
89 const char *label; 90 OFFSETTYPE(char*) label;
90 int subimage; 91 int subimage;
91 struct wps_token *token; /* the token to get the subimage number from */ 92 OFFSETTYPE(struct wps_token*) token; /* the token to get the subimage number from */
92 int offset; /* offset into the bitmap strip to start */ 93 int offset; /* offset into the bitmap strip to start */
93}; 94};
94 95
95struct progressbar { 96struct progressbar {
96 enum skin_token_type type; 97 enum skin_token_type type;
97 struct viewport *vp; 98 OFFSETTYPE(struct viewport *) vp;
98 /* regular pb */ 99 /* regular pb */
99 short x; 100 short x;
100 /* >=0: explicitly set in the tag -> y-coord within the viewport 101 /* >=0: explicitly set in the tag -> y-coord within the viewport
@@ -105,14 +106,14 @@ struct progressbar {
105 short height; 106 short height;
106 bool follow_lang_direction; 107 bool follow_lang_direction;
107 108
108 struct gui_img *image; 109 OFFSETTYPE(struct gui_img *) image;
109 110
110 bool invert_fill_direction; 111 bool invert_fill_direction;
111 bool nofill; 112 bool nofill;
112 bool nobar; 113 bool nobar;
113 struct gui_img *slider; 114 OFFSETTYPE(struct gui_img *) slider;
114 bool horizontal; 115 bool horizontal;
115 struct gui_img *backdrop; 116 OFFSETTYPE(struct gui_img *) backdrop;
116}; 117};
117#endif 118#endif
118 119
@@ -125,35 +126,11 @@ struct align_pos {
125}; 126};
126 127
127#ifdef HAVE_LCD_BITMAP 128#ifdef HAVE_LCD_BITMAP
128
129#define MAX_IMAGES (26*2) /* a-z and A-Z */
130#define MAX_PROGRESSBARS 3
131
132/* The image buffer is big enough to store one full-screen native bitmap,
133 plus two full-screen mono bitmaps. */
134
135#define WPS_MAX_VIEWPORTS 24
136#define WPS_MAX_LINES ((LCD_HEIGHT/5+1) * 2)
137#define WPS_MAX_SUBLINES (WPS_MAX_LINES*3)
138#define WPS_MAX_TOKENS 1150 129#define WPS_MAX_TOKENS 1150
139#define WPS_MAX_STRINGS 128
140#define STRING_BUFFER_SIZE 1024
141#define WPS_MAX_COND_LEVEL 10
142
143#else 130#else
144
145#define WPS_MAX_VIEWPORTS 2
146#define WPS_MAX_LINES 2
147#define WPS_MAX_SUBLINES 12
148#define WPS_MAX_TOKENS 64 131#define WPS_MAX_TOKENS 64
149#define WPS_MAX_STRINGS 32
150#define STRING_BUFFER_SIZE 64
151#define WPS_MAX_COND_LEVEL 5
152
153#endif 132#endif
154 133
155#define SUBLINE_RESET -1
156
157enum wps_parse_error { 134enum wps_parse_error {
158 PARSE_OK, 135 PARSE_OK,
159 PARSE_FAIL_UNCLOSED_COND, 136 PARSE_FAIL_UNCLOSED_COND,
@@ -176,12 +153,17 @@ struct gradient_config {
176#define VP_DRAW_WASHIDDEN 0x4 153#define VP_DRAW_WASHIDDEN 0x4
177/* these are never drawn, nor cleared, i.e. just ignored */ 154/* these are never drawn, nor cleared, i.e. just ignored */
178#define VP_NEVER_VISIBLE 0x8 155#define VP_NEVER_VISIBLE 0x8
179#define VP_DEFAULT_LABEL "|" 156#ifndef __PCTOOL__
157#define VP_DEFAULT_LABEL -200
158#else
159#define VP_DEFAULT_LABEL NULL
160#endif
161#define VP_DEFAULT_LABEL_STRING "|"
180struct skin_viewport { 162struct skin_viewport {
181 struct viewport vp; /* The LCD viewport struct */ 163 struct viewport vp; /* The LCD viewport struct */
182 char hidden_flags; 164 char hidden_flags;
183 bool is_infovp; 165 bool is_infovp;
184 char* label; 166 OFFSETTYPE(char*) label;
185 int parsed_fontid; 167 int parsed_fontid;
186#if LCD_DEPTH > 1 168#if LCD_DEPTH > 1
187 unsigned start_fgcolour; 169 unsigned start_fgcolour;
@@ -192,14 +174,14 @@ struct skin_viewport {
192#endif 174#endif
193}; 175};
194struct viewport_colour { 176struct viewport_colour {
195 struct viewport *vp; 177 OFFSETTYPE(struct viewport *) vp;
196 unsigned colour; 178 unsigned colour;
197}; 179};
198 180
199#ifdef HAVE_TOUCHSCREEN 181#ifdef HAVE_TOUCHSCREEN
200struct touchregion { 182struct touchregion {
201 char* label; /* label to identify this region */ 183 OFFSETTYPE(char*) label; /* label to identify this region */
202 struct skin_viewport* wvp;/* The viewport this region is in */ 184 OFFSETTYPE(struct skin_viewport*) wvp;/* The viewport this region is in */
203 short int x; /* x-pos */ 185 short int x; /* x-pos */
204 short int y; /* y-pos */ 186 short int y; /* y-pos */
205 short int width; /* width */ 187 short int width; /* width */
@@ -219,7 +201,7 @@ struct touchregion {
219 const struct settings_list *setting; /* setting being controlled */ 201 const struct settings_list *setting; /* setting being controlled */
220 union { /* Value to set the setting to for ACTION_SETTING_SET */ 202 union { /* Value to set the setting to for ACTION_SETTING_SET */
221 int number; 203 int number;
222 char* text; 204 OFFSETTYPE(char*) text;
223 } value; 205 } value;
224 } setting_data; 206 } setting_data;
225 int value; 207 int value;
@@ -230,20 +212,32 @@ struct touchregion {
230 212
231 213
232struct touchregion_lastpress { 214struct touchregion_lastpress {
233 struct touchregion *region; 215 OFFSETTYPE(struct touchregion *) region;
234 long timeout; 216 long timeout;
235}; 217};
236#endif 218#endif
237 219
238struct playlistviewer { 220struct playlistviewer {
239 struct viewport *vp; 221 OFFSETTYPE(struct viewport *) vp;
240 bool show_icons; 222 bool show_icons;
241 int start_offset; 223 int start_offset;
242 struct skin_element *line; 224 OFFSETTYPE(struct skin_element *) line;
243}; 225};
244 226
245 227
246#ifdef HAVE_ALBUMART 228#ifdef HAVE_ALBUMART
229
230/* albumart definitions */
231#define WPS_ALBUMART_NONE 0 /* WPS does not contain AA tag */
232#define WPS_ALBUMART_CHECK 1 /* WPS contains AA conditional tag */
233#define WPS_ALBUMART_LOAD 2 /* WPS contains AA tag */
234
235#define WPS_ALBUMART_ALIGN_RIGHT 1 /* x align: right */
236#define WPS_ALBUMART_ALIGN_CENTER 2 /* x/y align: center */
237#define WPS_ALBUMART_ALIGN_LEFT 4 /* x align: left */
238#define WPS_ALBUMART_ALIGN_TOP 1 /* y align: top */
239#define WPS_ALBUMART_ALIGN_BOTTOM 4 /* y align: bottom */
240
247struct skin_albumart { 241struct skin_albumart {
248 /* Album art support */ 242 /* Album art support */
249 int x; 243 int x;
@@ -255,7 +249,7 @@ struct skin_albumart {
255 unsigned char yalign; /* WPS_ALBUMART_ALIGN_TOP, _CENTER, _BOTTOM */ 249 unsigned char yalign; /* WPS_ALBUMART_ALIGN_TOP, _CENTER, _BOTTOM */
256 unsigned char state; /* WPS_ALBUMART_NONE, _CHECK, _LOAD */ 250 unsigned char state; /* WPS_ALBUMART_NONE, _CHECK, _LOAD */
257 251
258 struct viewport *vp; 252 OFFSETTYPE(struct viewport *) vp;
259 int draw_handle; 253 int draw_handle;
260}; 254};
261#endif 255#endif
@@ -272,11 +266,11 @@ struct line_alternator {
272 266
273struct conditional { 267struct conditional {
274 int last_value; 268 int last_value;
275 struct wps_token *token; 269 OFFSETTYPE(struct wps_token *) token;
276}; 270};
277 271
278struct logical_if { 272struct logical_if {
279 struct wps_token *token; 273 OFFSETTYPE(struct wps_token *) token;
280 enum { 274 enum {
281 IF_EQUALS, /* == */ 275 IF_EQUALS, /* == */
282 IF_NOTEQUALS, /* != */ 276 IF_NOTEQUALS, /* != */
@@ -292,7 +286,7 @@ struct logical_if {
292struct substring { 286struct substring {
293 int start; 287 int start;
294 int length; 288 int length;
295 struct wps_token *token; 289 OFFSETTYPE(struct wps_token *) token;
296}; 290};
297 291
298struct listitem { 292struct listitem {
@@ -302,16 +296,16 @@ struct listitem {
302 296
303#ifdef HAVE_SKIN_VARIABLES 297#ifdef HAVE_SKIN_VARIABLES
304struct skin_var { 298struct skin_var {
305 const char *label; 299 OFFSETTYPE(const char *) label;
306 int value; 300 int value;
307 long last_changed; 301 long last_changed;
308}; 302};
309struct skin_var_lastchange { 303struct skin_var_lastchange {
310 struct skin_var *var; 304 OFFSETTYPE(struct skin_var *) var;
311 long timeout; 305 long timeout;
312}; 306};
313struct skin_var_changer { 307struct skin_var_changer {
314 struct skin_var *var; 308 OFFSETTYPE(struct skin_var *) var;
315 int newval; 309 int newval;
316 bool direct; /* true to make val=newval, false for val += newval */ 310 bool direct; /* true to make val=newval, false for val += newval */
317 int max; 311 int max;
@@ -323,30 +317,29 @@ struct skin_var_changer {
323 viewable content of a wps */ 317 viewable content of a wps */
324struct wps_data 318struct wps_data
325{ 319{
326 struct skin_element *tree; 320 int buflib_handle;
321
322 OFFSETTYPE(struct skin_element *) tree;
327#ifdef HAVE_LCD_BITMAP 323#ifdef HAVE_LCD_BITMAP
328 struct skin_token_list *images; 324 OFFSETTYPE(struct skin_token_list *) images;
329 int *font_ids; 325 OFFSETTYPE(int *) font_ids;
330 int font_count; 326 int font_count;
331#endif 327#endif
332#if LCD_DEPTH > 1 || defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1 328#if LCD_DEPTH > 1 || defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1
333 struct { 329 int backdrop_id;
334 char *backdrop;
335 int backdrop_id;
336 };
337#endif 330#endif
338 331
339#ifdef HAVE_TOUCHSCREEN 332#ifdef HAVE_TOUCHSCREEN
340 struct skin_token_list *touchregions; 333 OFFSETTYPE(struct skin_token_list *) touchregions;
341 bool touchscreen_locked; 334 bool touchscreen_locked;
342#endif 335#endif
343#ifdef HAVE_ALBUMART 336#ifdef HAVE_ALBUMART
344 struct skin_albumart *albumart; 337 OFFSETTYPE(struct skin_albumart *) albumart;
345 int playback_aa_slot; 338 int playback_aa_slot;
346#endif 339#endif
347 340
348#ifdef HAVE_SKIN_VARIABLES 341#ifdef HAVE_SKIN_VARIABLES
349 struct skin_token_list *skinvars; 342 OFFSETTYPE(struct skin_token_list *) skinvars;
350#endif 343#endif
351 344
352#ifdef HAVE_LCD_BITMAP 345#ifdef HAVE_LCD_BITMAP
@@ -360,6 +353,17 @@ struct wps_data
360 bool wps_loaded; 353 bool wps_loaded;
361}; 354};
362 355
356#ifndef __PCTOOL__
357static inline char* get_skin_buffer(struct wps_data* data)
358{
359 if (data->buflib_handle >= 0)
360 return core_get_data(data->buflib_handle);
361 return NULL;
362}
363#else
364#define get_skin_buffer(d) skin_buffer
365#endif
366
363/* wps_data end */ 367/* wps_data end */
364 368
365/* wps_state 369/* wps_state
diff --git a/apps/gui/statusbar-skinned.c b/apps/gui/statusbar-skinned.c
index f79672c0d9..960cf67d4d 100644
--- a/apps/gui/statusbar-skinned.c
+++ b/apps/gui/statusbar-skinned.c
@@ -87,8 +87,9 @@ int sb_postproccess(enum screen_type screen, struct wps_data *data)
87 /* hide the sb's default viewport because it has nasty effect with stuff 87 /* hide the sb's default viewport because it has nasty effect with stuff
88 * not part of the statusbar, 88 * not part of the statusbar,
89 * hence .sbs's without any other vps are unsupported*/ 89 * hence .sbs's without any other vps are unsupported*/
90 struct skin_viewport *vp = skin_find_item(VP_DEFAULT_LABEL, SKIN_FIND_VP, data); 90 struct skin_viewport *vp = skin_find_item(VP_DEFAULT_LABEL_STRING, SKIN_FIND_VP, data);
91 struct skin_element *next_vp = data->tree->next; 91 struct skin_element *tree = SKINOFFSETTOPTR(get_skin_buffer(data), data->tree);
92 struct skin_element *next_vp = SKINOFFSETTOPTR(get_skin_buffer(data), tree->next);
92 93
93 if (vp) 94 if (vp)
94 { 95 {
@@ -105,9 +106,9 @@ int sb_postproccess(enum screen_type screen, struct wps_data *data)
105 return 1; 106 return 1;
106} 107}
107 108
108static char *infovp_label[NB_SCREENS]; 109static OFFSETTYPE(char*) infovp_label[NB_SCREENS];
109static char *oldinfovp_label[NB_SCREENS]; 110static OFFSETTYPE(char*) oldinfovp_label[NB_SCREENS];
110void sb_set_info_vp(enum screen_type screen, char *label) 111void sb_set_info_vp(enum screen_type screen, OFFSETTYPE(char*) label)
111{ 112{
112 infovp_label[screen] = label; 113 infovp_label[screen] = label;
113} 114}
@@ -116,15 +117,19 @@ struct viewport *sb_skin_get_info_vp(enum screen_type screen)
116{ 117{
117 struct wps_data *data = skin_get_gwps(CUSTOM_STATUSBAR, screen)->data; 118 struct wps_data *data = skin_get_gwps(CUSTOM_STATUSBAR, screen)->data;
118 struct skin_viewport *vp = NULL; 119 struct skin_viewport *vp = NULL;
120 char *label;
119 if (oldinfovp_label[screen] && 121 if (oldinfovp_label[screen] &&
120 strcmp(oldinfovp_label[screen], infovp_label[screen])) 122 (oldinfovp_label[screen] != infovp_label[screen]))
121 { 123 {
122 /* UI viewport changed, so force a redraw */ 124 /* UI viewport changed, so force a redraw */
123 oldinfovp_label[screen] = infovp_label[screen]; 125 oldinfovp_label[screen] = infovp_label[screen];
124 viewportmanager_theme_enable(screen, false, NULL); 126 viewportmanager_theme_enable(screen, false, NULL);
125 viewportmanager_theme_undo(screen, true); 127 viewportmanager_theme_undo(screen, true);
126 } 128 }
127 vp = skin_find_item(infovp_label[screen], SKIN_FIND_UIVP, data); 129 label = SKINOFFSETTOPTR(get_skin_buffer(data), infovp_label[screen]);
130 if (infovp_label[screen] == VP_DEFAULT_LABEL)
131 label = VP_DEFAULT_LABEL_STRING;
132 vp = skin_find_item(label, SKIN_FIND_UIVP, data);
128 if (!vp) 133 if (!vp)
129 return NULL; 134 return NULL;
130 if (vp->parsed_fontid == 1) 135 if (vp->parsed_fontid == 1)
@@ -270,7 +275,7 @@ void sb_skin_init(void)
270{ 275{
271 FOR_NB_SCREENS(i) 276 FOR_NB_SCREENS(i)
272 { 277 {
273 oldinfovp_label[i] = NULL; 278 oldinfovp_label[i] = VP_DEFAULT_LABEL;
274 } 279 }
275} 280}
276 281
diff --git a/apps/gui/statusbar-skinned.h b/apps/gui/statusbar-skinned.h
index bfd8193110..ac12dfa1aa 100644
--- a/apps/gui/statusbar-skinned.h
+++ b/apps/gui/statusbar-skinned.h
@@ -36,7 +36,7 @@ void sb_skin_data_load(enum screen_type screen, const char *buf, bool isfile);
36 36
37char* sb_create_from_settings(enum screen_type screen); 37char* sb_create_from_settings(enum screen_type screen);
38void sb_skin_init(void) INIT_ATTR; 38void sb_skin_init(void) INIT_ATTR;
39void sb_set_info_vp(enum screen_type screen, char *label); 39void sb_set_info_vp(enum screen_type screen, OFFSETTYPE(char*) label);
40struct viewport *sb_skin_get_info_vp(enum screen_type screen); 40struct viewport *sb_skin_get_info_vp(enum screen_type screen);
41void sb_skin_update(enum screen_type screen, bool force); 41void sb_skin_update(enum screen_type screen, bool force);
42 42
diff --git a/apps/gui/wps.c b/apps/gui/wps.c
index 6486e42fbb..97c945d0e8 100644
--- a/apps/gui/wps.c
+++ b/apps/gui/wps.c
@@ -667,7 +667,7 @@ static void gwps_enter_wps(void)
667#if LCD_DEPTH > 1 667#if LCD_DEPTH > 1
668 if (display->depth > 1) 668 if (display->depth > 1)
669 { 669 {
670 struct skin_viewport *svp = skin_find_item(VP_DEFAULT_LABEL, 670 struct skin_viewport *svp = skin_find_item(VP_DEFAULT_LABEL_STRING,
671 SKIN_FIND_VP, gwps->data); 671 SKIN_FIND_VP, gwps->data);
672 if (svp) 672 if (svp)
673 { 673 {