summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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
-rw-r--r--apps/lang/basque.lang8
-rw-r--r--apps/lang/bulgarian.lang8
-rw-r--r--apps/lang/catala.lang8
-rw-r--r--apps/lang/chinese-simp.lang8
-rw-r--r--apps/lang/czech.lang8
-rw-r--r--apps/lang/dansk.lang8
-rw-r--r--apps/lang/deutsch.lang8
-rw-r--r--apps/lang/english-us.lang8
-rw-r--r--apps/lang/english.lang8
-rw-r--r--apps/lang/espanol.lang8
-rw-r--r--apps/lang/finnish.lang8
-rw-r--r--apps/lang/francais.lang8
-rw-r--r--apps/lang/galego.lang8
-rw-r--r--apps/lang/hebrew.lang8
-rw-r--r--apps/lang/hrvatski.lang8
-rw-r--r--apps/lang/italiano.lang8
-rw-r--r--apps/lang/japanese.lang8
-rw-r--r--apps/lang/latviesu.lang8
-rw-r--r--apps/lang/magyar.lang8
-rw-r--r--apps/lang/nederlands.lang8
-rw-r--r--apps/lang/polski.lang8
-rw-r--r--apps/lang/portugues-brasileiro.lang8
-rw-r--r--apps/lang/portugues.lang8
-rw-r--r--apps/lang/romaneste.lang8
-rw-r--r--apps/lang/russian.lang8
-rw-r--r--apps/lang/slovak.lang8
-rw-r--r--apps/lang/slovenscina.lang8
-rw-r--r--apps/lang/srpski.lang8
-rw-r--r--apps/lang/svenska.lang8
-rw-r--r--apps/lang/tagalog.lang8
-rw-r--r--apps/lang/thai.lang8
-rw-r--r--apps/lang/walon.lang8
-rw-r--r--apps/menus/main_menu.c19
-rw-r--r--apps/recorder/albumart.c2
-rw-r--r--lib/skin_parser/skin_buffer.c73
-rw-r--r--lib/skin_parser/skin_buffer.h15
-rw-r--r--lib/skin_parser/skin_debug.c27
-rw-r--r--lib/skin_parser/skin_parser.c178
-rw-r--r--lib/skin_parser/skin_parser.h35
-rw-r--r--tools/checkwps/checkwps.c11
52 files changed, 943 insertions, 851 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 {
diff --git a/apps/lang/basque.lang b/apps/lang/basque.lang
index f0cc1ee1c3..8a9de4b385 100644
--- a/apps/lang/basque.lang
+++ b/apps/lang/basque.lang
@@ -11502,16 +11502,16 @@
11502</phrase> 11502</phrase>
11503<phrase> 11503<phrase>
11504 id: LANG_SKIN_RAM_USAGE 11504 id: LANG_SKIN_RAM_USAGE
11505 desc: how much RAM the skins are using 11505 desc: deprecated
11506 user: core 11506 user: core
11507 <source> 11507 <source>
11508 *: "Skin RAM usage:" 11508 *: ""
11509 </source> 11509 </source>
11510 <dest> 11510 <dest>
11511 *: "Azalaren RAM erabilera:" 11511 *: ""
11512 </dest> 11512 </dest>
11513 <voice> 11513 <voice>
11514 *: "Azalaren RAM erabilera:" 11514 *: ""
11515 </voice> 11515 </voice>
11516</phrase> 11516</phrase>
11517<phrase> 11517<phrase>
diff --git a/apps/lang/bulgarian.lang b/apps/lang/bulgarian.lang
index ad88cd77cc..257389c36e 100644
--- a/apps/lang/bulgarian.lang
+++ b/apps/lang/bulgarian.lang
@@ -12255,16 +12255,16 @@
12255</phrase> 12255</phrase>
12256<phrase> 12256<phrase>
12257 id: LANG_SKIN_RAM_USAGE 12257 id: LANG_SKIN_RAM_USAGE
12258 desc: how much RAM the skins are using 12258 desc: deprecated
12259 user: core 12259 user: core
12260 <source> 12260 <source>
12261 *: "Skin RAM usage:" 12261 *: ""
12262 </source> 12262 </source>
12263 <dest> 12263 <dest>
12264 *: "Използвана RAM от скина:" 12264 *: ""
12265 </dest> 12265 </dest>
12266 <voice> 12266 <voice>
12267 *: "Използвана RAM от скина" 12267 *: ""
12268 </voice> 12268 </voice>
12269</phrase> 12269</phrase>
12270<phrase> 12270<phrase>
diff --git a/apps/lang/catala.lang b/apps/lang/catala.lang
index e4abf581cc..aabcb931ff 100644
--- a/apps/lang/catala.lang
+++ b/apps/lang/catala.lang
@@ -11494,16 +11494,16 @@
11494</phrase> 11494</phrase>
11495<phrase> 11495<phrase>
11496 id: LANG_SKIN_RAM_USAGE 11496 id: LANG_SKIN_RAM_USAGE
11497 desc: how much RAM the skins are using 11497 desc: deprecated
11498 user: core 11498 user: core
11499 <source> 11499 <source>
11500 *: "Skin RAM usage:" 11500 *: ""
11501 </source> 11501 </source>
11502 <dest> 11502 <dest>
11503 *: "Ús de RAM per part del tema:" 11503 *: ""
11504 </dest> 11504 </dest>
11505 <voice> 11505 <voice>
11506 *: "Ús de RAM per part del tema" 11506 *: ""
11507 </voice> 11507 </voice>
11508</phrase> 11508</phrase>
11509<phrase> 11509<phrase>
diff --git a/apps/lang/chinese-simp.lang b/apps/lang/chinese-simp.lang
index fb0408d472..7319071903 100644
--- a/apps/lang/chinese-simp.lang
+++ b/apps/lang/chinese-simp.lang
@@ -11821,16 +11821,16 @@
11821</phrase> 11821</phrase>
11822<phrase> 11822<phrase>
11823 id: LANG_SKIN_RAM_USAGE 11823 id: LANG_SKIN_RAM_USAGE
11824 desc: how much RAM the skins are using 11824 desc: deprecated
11825 user: core 11825 user: core
11826 <source> 11826 <source>
11827 *: "Skin RAM usage:" 11827 *: ""
11828 </source> 11828 </source>
11829 <dest> 11829 <dest>
11830 *: "Skin RAM usage:" 11830 *: ""
11831 </dest> 11831 </dest>
11832 <voice> 11832 <voice>
11833 *: "Skin RAM usage" 11833 *: ""
11834 </voice> 11834 </voice>
11835</phrase> 11835</phrase>
11836<phrase> 11836<phrase>
diff --git a/apps/lang/czech.lang b/apps/lang/czech.lang
index 3d9557d4cb..00a89b87ff 100644
--- a/apps/lang/czech.lang
+++ b/apps/lang/czech.lang
@@ -11504,16 +11504,16 @@
11504</phrase> 11504</phrase>
11505<phrase> 11505<phrase>
11506 id: LANG_SKIN_RAM_USAGE 11506 id: LANG_SKIN_RAM_USAGE
11507 desc: how much RAM the skins are using 11507 desc: deprecated
11508 user: core 11508 user: core
11509 <source> 11509 <source>
11510 *: "Skin RAM usage:" 11510 *: ""
11511 </source> 11511 </source>
11512 <dest> 11512 <dest>
11513 *: "Využití RAM pro skiny:" 11513 *: ""
11514 </dest> 11514 </dest>
11515 <voice> 11515 <voice>
11516 *: "Využití RAM pro skiny" 11516 *: ""
11517 </voice> 11517 </voice>
11518</phrase> 11518</phrase>
11519<phrase> 11519<phrase>
diff --git a/apps/lang/dansk.lang b/apps/lang/dansk.lang
index 2c89ccdc4c..d99cbc9003 100644
--- a/apps/lang/dansk.lang
+++ b/apps/lang/dansk.lang
@@ -11446,16 +11446,16 @@
11446</phrase> 11446</phrase>
11447<phrase> 11447<phrase>
11448 id: LANG_SKIN_RAM_USAGE 11448 id: LANG_SKIN_RAM_USAGE
11449 desc: how much RAM the skins are using 11449 desc: deprecated
11450 user: core 11450 user: core
11451 <source> 11451 <source>
11452 *: "Skin RAM usage:" 11452 *: ""
11453 </source> 11453 </source>
11454 <dest> 11454 <dest>
11455 *: "Temas RAM-forbrug:" 11455 *: ""
11456 </dest> 11456 </dest>
11457 <voice> 11457 <voice>
11458 *: "Temas RAM-forbrug" 11458 *: ""
11459 </voice> 11459 </voice>
11460</phrase> 11460</phrase>
11461<phrase> 11461<phrase>
diff --git a/apps/lang/deutsch.lang b/apps/lang/deutsch.lang
index ae7867bf20..d565effb03 100644
--- a/apps/lang/deutsch.lang
+++ b/apps/lang/deutsch.lang
@@ -11445,16 +11445,16 @@
11445</phrase> 11445</phrase>
11446<phrase> 11446<phrase>
11447 id: LANG_SKIN_RAM_USAGE 11447 id: LANG_SKIN_RAM_USAGE
11448 desc: how much RAM the skins are using 11448 desc: deprecated
11449 user: core 11449 user: core
11450 <source> 11450 <source>
11451 *: "Skin RAM usage:" 11451 *: ""
11452 </source> 11452 </source>
11453 <dest> 11453 <dest>
11454 *: "Themen-Speicher:" 11454 *: ""
11455 </dest> 11455 </dest>
11456 <voice> 11456 <voice>
11457 *: "Themen-Speicher" 11457 *: ""
11458 </voice> 11458 </voice>
11459</phrase> 11459</phrase>
11460<phrase> 11460<phrase>
diff --git a/apps/lang/english-us.lang b/apps/lang/english-us.lang
index 9a7c8786e7..16af129376 100644
--- a/apps/lang/english-us.lang
+++ b/apps/lang/english-us.lang
@@ -11500,16 +11500,16 @@
11500</phrase> 11500</phrase>
11501<phrase> 11501<phrase>
11502 id: LANG_SKIN_RAM_USAGE 11502 id: LANG_SKIN_RAM_USAGE
11503 desc: how much RAM the skins are using 11503 desc: deprecated
11504 user: core 11504 user: core
11505 <source> 11505 <source>
11506 *: "Skin RAM usage:" 11506 *: ""
11507 </source> 11507 </source>
11508 <dest> 11508 <dest>
11509 *: "Skin RAM usage:" 11509 *: ""
11510 </dest> 11510 </dest>
11511 <voice> 11511 <voice>
11512 *: "Skin RAM usage" 11512 *: ""
11513 </voice> 11513 </voice>
11514</phrase> 11514</phrase>
11515<phrase> 11515<phrase>
diff --git a/apps/lang/english.lang b/apps/lang/english.lang
index 741f120023..de541af1f5 100644
--- a/apps/lang/english.lang
+++ b/apps/lang/english.lang
@@ -11587,16 +11587,16 @@
11587</phrase> 11587</phrase>
11588<phrase> 11588<phrase>
11589 id: LANG_SKIN_RAM_USAGE 11589 id: LANG_SKIN_RAM_USAGE
11590 desc: how much RAM the skins are using 11590 desc: deprecated
11591 user: core 11591 user: core
11592 <source> 11592 <source>
11593 *: "Skin RAM usage:" 11593 *: ""
11594 </source> 11594 </source>
11595 <dest> 11595 <dest>
11596 *: "Skin RAM usage:" 11596 *: ""
11597 </dest> 11597 </dest>
11598 <voice> 11598 <voice>
11599 *: "Skin RAM usage" 11599 *: ""
11600 </voice> 11600 </voice>
11601</phrase> 11601</phrase>
11602<phrase> 11602<phrase>
diff --git a/apps/lang/espanol.lang b/apps/lang/espanol.lang
index d1b484413f..f12fb2ec70 100644
--- a/apps/lang/espanol.lang
+++ b/apps/lang/espanol.lang
@@ -11816,16 +11816,16 @@
11816</phrase> 11816</phrase>
11817<phrase> 11817<phrase>
11818 id: LANG_SKIN_RAM_USAGE 11818 id: LANG_SKIN_RAM_USAGE
11819 desc: how much RAM the skins are using 11819 desc: deprecated
11820 user: core 11820 user: core
11821 <source> 11821 <source>
11822 *: "Skin RAM usage:" 11822 *: ""
11823 </source> 11823 </source>
11824 <dest> 11824 <dest>
11825 *: "Uso de RAM de la piel:" 11825 *: ""
11826 </dest> 11826 </dest>
11827 <voice> 11827 <voice>
11828 *: "Uso de RAM de la piel" 11828 *: ""
11829 </voice> 11829 </voice>
11830</phrase> 11830</phrase>
11831<phrase> 11831<phrase>
diff --git a/apps/lang/finnish.lang b/apps/lang/finnish.lang
index a2ab55101f..0855a5f04c 100644
--- a/apps/lang/finnish.lang
+++ b/apps/lang/finnish.lang
@@ -11383,16 +11383,16 @@
11383</phrase> 11383</phrase>
11384<phrase> 11384<phrase>
11385 id: LANG_SKIN_RAM_USAGE 11385 id: LANG_SKIN_RAM_USAGE
11386 desc: how much RAM the skins are using 11386 desc: deprecated
11387 user: core 11387 user: core
11388 <source> 11388 <source>
11389 *: "Skin RAM usage:" 11389 *: ""
11390 </source> 11390 </source>
11391 <dest> 11391 <dest>
11392 *: "Nahan käyttämä RAM-muisti:" 11392 *: ""
11393 </dest> 11393 </dest>
11394 <voice> 11394 <voice>
11395 *: "Nahan käyttämä RAM-muisti" 11395 *: ""
11396 </voice> 11396 </voice>
11397</phrase> 11397</phrase>
11398<phrase> 11398<phrase>
diff --git a/apps/lang/francais.lang b/apps/lang/francais.lang
index ff94abfc92..9ad6e92073 100644
--- a/apps/lang/francais.lang
+++ b/apps/lang/francais.lang
@@ -11528,16 +11528,16 @@
11528</phrase> 11528</phrase>
11529<phrase> 11529<phrase>
11530 id: LANG_SKIN_RAM_USAGE 11530 id: LANG_SKIN_RAM_USAGE
11531 desc: how much RAM the skins are using 11531 desc: deprecated
11532 user: core 11532 user: core
11533 <source> 11533 <source>
11534 *: "Skin RAM usage:" 11534 *: ""
11535 </source> 11535 </source>
11536 <dest> 11536 <dest>
11537 *: "Tampon du thème:" 11537 *: ""
11538 </dest> 11538 </dest>
11539 <voice> 11539 <voice>
11540 *: "Tampon du thème utilisé" 11540 *: ""
11541 </voice> 11541 </voice>
11542</phrase> 11542</phrase>
11543<phrase> 11543<phrase>
diff --git a/apps/lang/galego.lang b/apps/lang/galego.lang
index 4d390a30e9..a137f6888f 100644
--- a/apps/lang/galego.lang
+++ b/apps/lang/galego.lang
@@ -10883,16 +10883,16 @@ ipod*,iaudiox5,iaudiom5,iriverh10,iriverh10_5gb,sansae200*,sansac200*,gigabeat*,
10883</phrase> 10883</phrase>
10884<phrase> 10884<phrase>
10885 id: LANG_SKIN_RAM_USAGE 10885 id: LANG_SKIN_RAM_USAGE
10886 desc: how much RAM the skins are using 10886 desc: deprecated
10887 user: core 10887 user: core
10888 <source> 10888 <source>
10889 *: "Skin RAM usage:" 10889 *: ""
10890 </source> 10890 </source>
10891 <dest> 10891 <dest>
10892 *: "Uso de RAM pola skin:" 10892 *: ""
10893 </dest> 10893 </dest>
10894 <voice> 10894 <voice>
10895 *: "Uso de RAM pola skin" 10895 *: ""
10896 </voice> 10896 </voice>
10897</phrase> 10897</phrase>
10898<phrase> 10898<phrase>
diff --git a/apps/lang/hebrew.lang b/apps/lang/hebrew.lang
index 30ce32f793..100a5f66ac 100644
--- a/apps/lang/hebrew.lang
+++ b/apps/lang/hebrew.lang
@@ -11509,16 +11509,16 @@
11509</phrase> 11509</phrase>
11510<phrase> 11510<phrase>
11511 id: LANG_SKIN_RAM_USAGE 11511 id: LANG_SKIN_RAM_USAGE
11512 desc: how much RAM the skins are using 11512 desc: deprecated
11513 user: core 11513 user: core
11514 <source> 11514 <source>
11515 *: "Skin RAM usage:" 11515 *: ""
11516 </source> 11516 </source>
11517 <dest> 11517 <dest>
11518 *: "Skin RAM usage:" 11518 *: ""
11519 </dest> 11519 </dest>
11520 <voice> 11520 <voice>
11521 *: "Skin RAM usage" 11521 *: ""
11522 </voice> 11522 </voice>
11523</phrase> 11523</phrase>
11524<phrase> 11524<phrase>
diff --git a/apps/lang/hrvatski.lang b/apps/lang/hrvatski.lang
index cc45c157bf..1dbfc620c1 100644
--- a/apps/lang/hrvatski.lang
+++ b/apps/lang/hrvatski.lang
@@ -11503,16 +11503,16 @@
11503</phrase> 11503</phrase>
11504<phrase> 11504<phrase>
11505 id: LANG_SKIN_RAM_USAGE 11505 id: LANG_SKIN_RAM_USAGE
11506 desc: how much RAM the skins are using 11506 desc: deprecated
11507 user: core 11507 user: core
11508 <source> 11508 <source>
11509 *: "Skin RAM usage:" 11509 *: ""
11510 </source> 11510 </source>
11511 <dest> 11511 <dest>
11512 *: "Korištenje RAM-a presvlake:" 11512 *: ""
11513 </dest> 11513 </dest>
11514 <voice> 11514 <voice>
11515 *: "Korištenje RAM-a presvlake" 11515 *: ""
11516 </voice> 11516 </voice>
11517</phrase> 11517</phrase>
11518<phrase> 11518<phrase>
diff --git a/apps/lang/italiano.lang b/apps/lang/italiano.lang
index 0450f2280d..ddb18039e1 100644
--- a/apps/lang/italiano.lang
+++ b/apps/lang/italiano.lang
@@ -11504,16 +11504,16 @@ desc: deprecated
11504</phrase> 11504</phrase>
11505<phrase> 11505<phrase>
11506 id: LANG_SKIN_RAM_USAGE 11506 id: LANG_SKIN_RAM_USAGE
11507 desc: how much RAM the skins are using 11507 desc: deprecated
11508 user: core 11508 user: core
11509 <source> 11509 <source>
11510 *: "Skin RAM usage:" 11510 *: ""
11511 </source> 11511 </source>
11512 <dest> 11512 <dest>
11513 *: "RAM usata per Skin:" 11513 *: ""
11514 </dest> 11514 </dest>
11515 <voice> 11515 <voice>
11516 *: "RAM usata per Skin" 11516 *: ""
11517 </voice> 11517 </voice>
11518</phrase> 11518</phrase>
11519<phrase> 11519<phrase>
diff --git a/apps/lang/japanese.lang b/apps/lang/japanese.lang
index a1d6039979..3a62826d28 100644
--- a/apps/lang/japanese.lang
+++ b/apps/lang/japanese.lang
@@ -11509,16 +11509,16 @@
11509</phrase> 11509</phrase>
11510<phrase> 11510<phrase>
11511 id: LANG_SKIN_RAM_USAGE 11511 id: LANG_SKIN_RAM_USAGE
11512 desc: how much RAM the skins are using 11512 desc: deprecated
11513 user: core 11513 user: core
11514 <source> 11514 <source>
11515 *: "Skin RAM usage:" 11515 *: ""
11516 </source> 11516 </source>
11517 <dest> 11517 <dest>
11518 *: "スキンのRAM使用量:" 11518 *: ""
11519 </dest> 11519 </dest>
11520 <voice> 11520 <voice>
11521 *: "スキンのRAM使用量" 11521 *: ""
11522 </voice> 11522 </voice>
11523</phrase> 11523</phrase>
11524<phrase> 11524<phrase>
diff --git a/apps/lang/latviesu.lang b/apps/lang/latviesu.lang
index 866820d4f3..0a46088444 100644
--- a/apps/lang/latviesu.lang
+++ b/apps/lang/latviesu.lang
@@ -11505,16 +11505,16 @@
11505</phrase> 11505</phrase>
11506<phrase> 11506<phrase>
11507 id: LANG_SKIN_RAM_USAGE 11507 id: LANG_SKIN_RAM_USAGE
11508 desc: how much RAM the skins are using 11508 desc: deprecated
11509 user: core 11509 user: core
11510 <source> 11510 <source>
11511 *: "Skin RAM usage:" 11511 *: ""
11512 </source> 11512 </source>
11513 <dest> 11513 <dest>
11514 *: "Ādas RAM izl.:" 11514 *: ""
11515 </dest> 11515 </dest>
11516 <voice> 11516 <voice>
11517 *: "aadas ram izlietojums" 11517 *: ""
11518 </voice> 11518 </voice>
11519</phrase> 11519</phrase>
11520<phrase> 11520<phrase>
diff --git a/apps/lang/magyar.lang b/apps/lang/magyar.lang
index e18fbe4ceb..a12de094ad 100644
--- a/apps/lang/magyar.lang
+++ b/apps/lang/magyar.lang
@@ -11366,16 +11366,16 @@
11366</phrase> 11366</phrase>
11367<phrase> 11367<phrase>
11368 id: LANG_SKIN_RAM_USAGE 11368 id: LANG_SKIN_RAM_USAGE
11369 desc: how much RAM the skins are using 11369 desc: deprecated
11370 user: core 11370 user: core
11371 <source> 11371 <source>
11372 *: "Skin RAM usage:" 11372 *: ""
11373 </source> 11373 </source>
11374 <dest> 11374 <dest>
11375 *: "Téma RAM használat:" 11375 *: ""
11376 </dest> 11376 </dest>
11377 <voice> 11377 <voice>
11378 *: "Téma RAM használat" 11378 *: ""
11379 </voice> 11379 </voice>
11380</phrase> 11380</phrase>
11381<phrase> 11381<phrase>
diff --git a/apps/lang/nederlands.lang b/apps/lang/nederlands.lang
index 76cd861276..689b410a96 100644
--- a/apps/lang/nederlands.lang
+++ b/apps/lang/nederlands.lang
@@ -11852,16 +11852,16 @@
11852</phrase> 11852</phrase>
11853<phrase> 11853<phrase>
11854 id: LANG_SKIN_RAM_USAGE 11854 id: LANG_SKIN_RAM_USAGE
11855 desc: how much RAM the skins are using 11855 desc: deprecated
11856 user: core 11856 user: core
11857 <source> 11857 <source>
11858 *: "Skin RAM usage:" 11858 *: ""
11859 </source> 11859 </source>
11860 <dest> 11860 <dest>
11861 *: "Uitzicht RAM gebruik:" 11861 *: ""
11862 </dest> 11862 </dest>
11863 <voice> 11863 <voice>
11864 *: "Uitzicht RAM gebruik" 11864 *: ""
11865 </voice> 11865 </voice>
11866</phrase> 11866</phrase>
11867<phrase> 11867<phrase>
diff --git a/apps/lang/polski.lang b/apps/lang/polski.lang
index c68484ffbd..8baa93d774 100644
--- a/apps/lang/polski.lang
+++ b/apps/lang/polski.lang
@@ -11426,16 +11426,16 @@
11426</phrase> 11426</phrase>
11427<phrase> 11427<phrase>
11428 id: LANG_SKIN_RAM_USAGE 11428 id: LANG_SKIN_RAM_USAGE
11429 desc: how much RAM the skins are using 11429 desc: deprecated
11430 user: core 11430 user: core
11431 <source> 11431 <source>
11432 *: "Skin RAM usage:" 11432 *: ""
11433 </source> 11433 </source>
11434 <dest> 11434 <dest>
11435 *: "Pamięć zajmowana przez styl:" 11435 *: ""
11436 </dest> 11436 </dest>
11437 <voice> 11437 <voice>
11438 *: "Pamięć zajmowana przez styl" 11438 *: ""
11439 </voice> 11439 </voice>
11440</phrase> 11440</phrase>
11441<phrase> 11441<phrase>
diff --git a/apps/lang/portugues-brasileiro.lang b/apps/lang/portugues-brasileiro.lang
index e708e936d4..43bd38e283 100644
--- a/apps/lang/portugues-brasileiro.lang
+++ b/apps/lang/portugues-brasileiro.lang
@@ -11501,16 +11501,16 @@
11501</phrase> 11501</phrase>
11502<phrase> 11502<phrase>
11503 id: LANG_SKIN_RAM_USAGE 11503 id: LANG_SKIN_RAM_USAGE
11504 desc: how much RAM the skins are using 11504 desc: deprecated
11505 user: core 11505 user: core
11506 <source> 11506 <source>
11507 *: "Skin RAM usage:" 11507 *: ""
11508 </source> 11508 </source>
11509 <dest> 11509 <dest>
11510 *: "Uso de RAM do Skin:" 11510 *: ""
11511 </dest> 11511 </dest>
11512 <voice> 11512 <voice>
11513 *: "Uso de RAM do Skin" 11513 *: ""
11514 </voice> 11514 </voice>
11515</phrase> 11515</phrase>
11516<phrase> 11516<phrase>
diff --git a/apps/lang/portugues.lang b/apps/lang/portugues.lang
index c9808596ae..fde14e89b4 100644
--- a/apps/lang/portugues.lang
+++ b/apps/lang/portugues.lang
@@ -11679,16 +11679,16 @@
11679</phrase> 11679</phrase>
11680<phrase> 11680<phrase>
11681 id: LANG_SKIN_RAM_USAGE 11681 id: LANG_SKIN_RAM_USAGE
11682 desc: how much RAM the skins are using 11682 desc: deprecated
11683 user: core 11683 user: core
11684 <source> 11684 <source>
11685 *: "Skin RAM usage:" 11685 *: ""
11686 </source> 11686 </source>
11687 <dest> 11687 <dest>
11688 *: "Uso de RAM do Visual:" 11688 *: ""
11689 </dest> 11689 </dest>
11690 <voice> 11690 <voice>
11691 *: "Uso de RAM do Visual" 11691 *: ""
11692 </voice> 11692 </voice>
11693</phrase> 11693</phrase>
11694<phrase> 11694<phrase>
diff --git a/apps/lang/romaneste.lang b/apps/lang/romaneste.lang
index 169df41ed9..8fcb4f8b99 100644
--- a/apps/lang/romaneste.lang
+++ b/apps/lang/romaneste.lang
@@ -12501,16 +12501,16 @@
12501 12501
12502<phrase> 12502<phrase>
12503 id: LANG_SKIN_RAM_USAGE 12503 id: LANG_SKIN_RAM_USAGE
12504 desc: how much RAM the skins are using 12504 desc: deprecated
12505 user: core 12505 user: core
12506 <source> 12506 <source>
12507 *: "Skin RAM usage:" 12507 *: ""
12508 </source> 12508 </source>
12509 <dest> 12509 <dest>
12510 *: "Utilizare RAM de către skin:" 12510 *: ""
12511 </dest> 12511 </dest>
12512 <voice> 12512 <voice>
12513 *: "Utilizare RAM de către skin:" 12513 *: ""
12514 </voice> 12514 </voice>
12515</phrase> 12515</phrase>
12516 12516
diff --git a/apps/lang/russian.lang b/apps/lang/russian.lang
index be67c92259..7cd280ce62 100644
--- a/apps/lang/russian.lang
+++ b/apps/lang/russian.lang
@@ -12219,16 +12219,16 @@
12219</phrase> 12219</phrase>
12220<phrase> 12220<phrase>
12221 id: LANG_SKIN_RAM_USAGE 12221 id: LANG_SKIN_RAM_USAGE
12222 desc: how much RAM the skins are using 12222 desc: deprecated
12223 user: core 12223 user: core
12224 <source> 12224 <source>
12225 *: "Skin RAM usage:" 12225 *: ""
12226 </source> 12226 </source>
12227 <dest> 12227 <dest>
12228 *: "RAM для темы:" 12228 *: ""
12229 </dest> 12229 </dest>
12230 <voice> 12230 <voice>
12231 *: "RAM для темы" 12231 *: ""
12232 </voice> 12232 </voice>
12233</phrase> 12233</phrase>
12234<phrase> 12234<phrase>
diff --git a/apps/lang/slovak.lang b/apps/lang/slovak.lang
index 8b34e739d8..0bb4b46270 100644
--- a/apps/lang/slovak.lang
+++ b/apps/lang/slovak.lang
@@ -11500,16 +11500,16 @@
11500</phrase> 11500</phrase>
11501<phrase> 11501<phrase>
11502 id: LANG_SKIN_RAM_USAGE 11502 id: LANG_SKIN_RAM_USAGE
11503 desc: how much RAM the skins are using 11503 desc: deprecated
11504 user: core 11504 user: core
11505 <source> 11505 <source>
11506 *: "Skin RAM usage:" 11506 *: ""
11507 </source> 11507 </source>
11508 <dest> 11508 <dest>
11509 *: "Pamäť Ram využitá vzhľadom" 11509 *: ""
11510 </dest> 11510 </dest>
11511 <voice> 11511 <voice>
11512 *: "Pamäť RAM využitá vzhľadom" 11512 *: ""
11513 </voice> 11513 </voice>
11514</phrase> 11514</phrase>
11515<phrase> 11515<phrase>
diff --git a/apps/lang/slovenscina.lang b/apps/lang/slovenscina.lang
index a40ba3a6b9..546eb86b5e 100644
--- a/apps/lang/slovenscina.lang
+++ b/apps/lang/slovenscina.lang
@@ -9764,16 +9764,16 @@
9764</phrase> 9764</phrase>
9765<phrase> 9765<phrase>
9766 id: LANG_SKIN_RAM_USAGE 9766 id: LANG_SKIN_RAM_USAGE
9767 desc: how much RAM the skins are using 9767 desc: deprecated
9768 user: core 9768 user: core
9769 <source> 9769 <source>
9770 *: "Skin RAM usage:" 9770 *: ""
9771 </source> 9771 </source>
9772 <dest> 9772 <dest>
9773 *: "Skin RAM usage:" 9773 *: ""
9774 </dest> 9774 </dest>
9775 <voice> 9775 <voice>
9776 *: "Skin RAM usage" 9776 *: ""
9777 </voice> 9777 </voice>
9778</phrase> 9778</phrase>
9779<phrase> 9779<phrase>
diff --git a/apps/lang/srpski.lang b/apps/lang/srpski.lang
index 0f70707981..8d5b311c4b 100644
--- a/apps/lang/srpski.lang
+++ b/apps/lang/srpski.lang
@@ -11784,16 +11784,16 @@
11784</phrase> 11784</phrase>
11785<phrase> 11785<phrase>
11786 id: LANG_SKIN_RAM_USAGE 11786 id: LANG_SKIN_RAM_USAGE
11787 desc: how much RAM the skins are using 11787 desc: deprecated
11788 user: core 11788 user: core
11789 <source> 11789 <source>
11790 *: "Skin RAM usage:" 11790 *: ""
11791 </source> 11791 </source>
11792 <dest> 11792 <dest>
11793 *: "Потрошња RAM за скинове:" 11793 *: ""
11794 </dest> 11794 </dest>
11795 <voice> 11795 <voice>
11796 *: "Потрошња RAM за скинове" 11796 *: ""
11797 </voice> 11797 </voice>
11798</phrase> 11798</phrase>
11799<phrase> 11799<phrase>
diff --git a/apps/lang/svenska.lang b/apps/lang/svenska.lang
index a154e0032d..c0b1b048cf 100644
--- a/apps/lang/svenska.lang
+++ b/apps/lang/svenska.lang
@@ -11506,16 +11506,16 @@
11506</phrase> 11506</phrase>
11507<phrase> 11507<phrase>
11508 id: LANG_SKIN_RAM_USAGE 11508 id: LANG_SKIN_RAM_USAGE
11509 desc: how much RAM the skins are using 11509 desc: deprecated
11510 user: core 11510 user: core
11511 <source> 11511 <source>
11512 *: "Skin RAM usage:" 11512 *: ""
11513 </source> 11513 </source>
11514 <dest> 11514 <dest>
11515 *: "Tema:" 11515 *: ""
11516 </dest> 11516 </dest>
11517 <voice> 11517 <voice>
11518 *: "Tema" 11518 *: ""
11519 </voice> 11519 </voice>
11520</phrase> 11520</phrase>
11521<phrase> 11521<phrase>
diff --git a/apps/lang/tagalog.lang b/apps/lang/tagalog.lang
index 7547954c42..51d8e912df 100644
--- a/apps/lang/tagalog.lang
+++ b/apps/lang/tagalog.lang
@@ -11394,16 +11394,16 @@
11394</phrase> 11394</phrase>
11395<phrase> 11395<phrase>
11396 id: LANG_SKIN_RAM_USAGE 11396 id: LANG_SKIN_RAM_USAGE
11397 desc: how much RAM the skins are using 11397 desc: deprecated
11398 user: core 11398 user: core
11399 <source> 11399 <source>
11400 *: "Skin RAM usage:" 11400 *: ""
11401 </source> 11401 </source>
11402 <dest> 11402 <dest>
11403 *: "Skin RAM usage:" 11403 *: ""
11404 </dest> 11404 </dest>
11405 <voice> 11405 <voice>
11406 *: "Skin RAM usage" 11406 *: ""
11407 </voice> 11407 </voice>
11408</phrase> 11408</phrase>
11409<phrase> 11409<phrase>
diff --git a/apps/lang/thai.lang b/apps/lang/thai.lang
index fd2d698844..e0079ac408 100644
--- a/apps/lang/thai.lang
+++ b/apps/lang/thai.lang
@@ -11342,16 +11342,16 @@
11342</phrase> 11342</phrase>
11343<phrase> 11343<phrase>
11344 id: LANG_SKIN_RAM_USAGE 11344 id: LANG_SKIN_RAM_USAGE
11345 desc: how much RAM the skins are using 11345 desc: deprecated
11346 user: core 11346 user: core
11347 <source> 11347 <source>
11348 *: "Skin RAM usage:" 11348 *: ""
11349 </source> 11349 </source>
11350 <dest> 11350 <dest>
11351 *: "หน่วยความจำหน้ากาก:" 11351 *: ""
11352 </dest> 11352 </dest>
11353 <voice> 11353 <voice>
11354 *: "Skin RAM usage" 11354 *: ""
11355 </voice> 11355 </voice>
11356</phrase> 11356</phrase>
11357<phrase> 11357<phrase>
diff --git a/apps/lang/walon.lang b/apps/lang/walon.lang
index 0f9b508a83..ab3c8427a3 100644
--- a/apps/lang/walon.lang
+++ b/apps/lang/walon.lang
@@ -11505,16 +11505,16 @@
11505</phrase> 11505</phrase>
11506<phrase> 11506<phrase>
11507 id: LANG_SKIN_RAM_USAGE 11507 id: LANG_SKIN_RAM_USAGE
11508 desc: how much RAM the skins are using 11508 desc: deprecated
11509 user: core 11509 user: core
11510 <source> 11510 <source>
11511 *: "Skin RAM usage:" 11511 *: ""
11512 </source> 11512 </source>
11513 <dest> 11513 <dest>
11514 *: "Memwere eployeye pol pea:" 11514 *: ""
11515 </dest> 11515 </dest>
11516 <voice> 11516 <voice>
11517 *: "Memwere eployeye pol pea" 11517 *: ""
11518 </voice> 11518 </voice>
11519</phrase> 11519</phrase>
11520<phrase> 11520<phrase>
diff --git a/apps/menus/main_menu.c b/apps/menus/main_menu.c
index 7f8a56e887..8053bf0cf8 100644
--- a/apps/menus/main_menu.c
+++ b/apps/menus/main_menu.c
@@ -147,9 +147,6 @@ enum infoscreenorder
147 INFO_DISK1, /* capacity or internal capacity/free on hotswap */ 147 INFO_DISK1, /* capacity or internal capacity/free on hotswap */
148 INFO_DISK2, /* free space or external capacity/free on hotswap */ 148 INFO_DISK2, /* free space or external capacity/free on hotswap */
149 INFO_BUFFER, 149 INFO_BUFFER,
150#ifndef APPLICATION
151 INFO_SKIN_USAGE, /* ram usage of the skins */
152#endif
153 INFO_VERSION, 150 INFO_VERSION,
154 INFO_COUNT 151 INFO_COUNT
155}; 152};
@@ -159,7 +156,7 @@ static const char* info_getname(int selected_item, void *data,
159{ 156{
160 struct info_data *info = (struct info_data*)data; 157 struct info_data *info = (struct info_data*)data;
161 char s1[32]; 158 char s1[32];
162#if defined(HAVE_MULTIVOLUME) || !defined(APPLICATION) 159#if defined(HAVE_MULTIVOLUME)
163 char s2[32]; 160 char s2[32];
164#endif 161#endif
165 if (info->new_data) 162 if (info->new_data)
@@ -246,14 +243,6 @@ static const char* info_getname(int selected_item, void *data,
246 snprintf(buffer, buffer_len, SIZE_FMT, str(LANG_DISK_SIZE_INFO), s1); 243 snprintf(buffer, buffer_len, SIZE_FMT, str(LANG_DISK_SIZE_INFO), s1);
247#endif 244#endif
248 break; 245 break;
249#ifndef APPLICATION
250 case INFO_SKIN_USAGE:
251 output_dyn_value(s1, sizeof s1, skin_buffer_usage(), byte_units, true);
252 output_dyn_value(s2, sizeof s2, skin_buffer_usage()
253 +skin_buffer_freespace(), byte_units, true);
254 snprintf(buffer, buffer_len, "%s %s / %s", str(LANG_SKIN_RAM_USAGE), s1, s2);
255 break;
256#endif
257 } 246 }
258 return buffer; 247 return buffer;
259} 248}
@@ -334,12 +323,6 @@ static int info_speak_item(int selected_item, void * data)
334 output_dyn_value(NULL, 0, info->size, kbyte_units, true); 323 output_dyn_value(NULL, 0, info->size, kbyte_units, true);
335#endif 324#endif
336 break; 325 break;
337#ifndef APPLICATION
338 case INFO_SKIN_USAGE:
339 talk_id(LANG_SKIN_RAM_USAGE, false);
340 output_dyn_value(NULL, 0, skin_buffer_usage(), byte_units, true);
341 break;
342#endif
343 326
344 } 327 }
345 return 0; 328 return 0;
diff --git a/apps/recorder/albumart.c b/apps/recorder/albumart.c
index 43f18cd163..4cbabbc8ce 100644
--- a/apps/recorder/albumart.c
+++ b/apps/recorder/albumart.c
@@ -305,7 +305,7 @@ void draw_album_art(struct gui_wps *gwps, int handle_id, bool clear)
305 return; 305 return;
306 306
307 struct wps_data *data = gwps->data; 307 struct wps_data *data = gwps->data;
308 struct skin_albumart *aa = data->albumart; 308 struct skin_albumart *aa = SKINOFFSETTOPTR(get_skin_buffer(data), data->albumart);
309 309
310 if (!aa) 310 if (!aa)
311 return; 311 return;
diff --git a/lib/skin_parser/skin_buffer.c b/lib/skin_parser/skin_buffer.c
index 5a9d4464b8..d18122ef20 100644
--- a/lib/skin_parser/skin_buffer.c
+++ b/lib/skin_parser/skin_buffer.c
@@ -47,54 +47,26 @@
47#ifdef ROCKBOX 47#ifdef ROCKBOX
48#include "config.h" 48#include "config.h"
49#include "skin_debug.h" 49#include "skin_debug.h"
50
51#ifdef APPLICATION
52# define USE_HOST_MALLOC
53#else
54# define USE_ROCKBOX_ALLOC
55#endif
56
57#endif
58
59#ifdef USE_ROCKBOX_ALLOC
60static size_t buf_size; 50static size_t buf_size;
61static unsigned char *buffer_start = NULL; 51static unsigned char *buffer_start = NULL;
62static unsigned char *buffer_front = NULL; 52static unsigned char *buffer_front = NULL;
63#endif
64
65#ifdef USE_HOST_MALLOC
66
67struct malloc_object {
68 struct malloc_object *next;
69 char buf[0];
70};
71static struct malloc_object *malloced_head = NULL, *malloced_tail = NULL;
72 53
73static void skin_free_malloced(void) 54#ifndef __PCTOOL__
55long skin_buffer_to_offset(void *pointer)
74{ 56{
75 struct malloc_object *obj = malloced_head; 57 return pointer == NULL ? -1 : (void*)pointer - (void*)buffer_start;
76 struct malloc_object *this;
77 while (obj)
78 {
79 this = obj;
80 obj = this->next;
81 free(this);
82 }
83 malloced_head = NULL;
84 malloced_tail = NULL;
85} 58}
86 59
60void* skin_buffer_from_offset(long offset)
61{
62 return offset < 0 ? NULL : buffer_start + offset;
63}
87#endif 64#endif
88 65
89void skin_buffer_init(char* buffer, size_t size) 66void skin_buffer_init(char* buffer, size_t size)
90{ 67{
91#ifdef USE_ROCKBOX_ALLOC
92 buffer_start = buffer_front = buffer; 68 buffer_start = buffer_front = buffer;
93 buf_size = size; 69 buf_size = size;
94#elif defined(USE_HOST_MALLOC)
95 (void)buffer; (void)size;
96 skin_free_malloced();
97#endif
98} 70}
99 71
100/* Allocate size bytes from the buffer */ 72/* Allocate size bytes from the buffer */
@@ -108,8 +80,6 @@ void* skin_buffer_alloc(size_t size)
108{ 80{
109 void *retval = NULL; 81 void *retval = NULL;
110#endif 82#endif
111
112#ifdef USE_ROCKBOX_ALLOC
113 /* 32-bit aligned */ 83 /* 32-bit aligned */
114 size = (size + 3) & ~3; 84 size = (size + 3) & ~3;
115 if (size > skin_buffer_freespace()) 85 if (size > skin_buffer_freespace())
@@ -119,25 +89,9 @@ void* skin_buffer_alloc(size_t size)
119 } 89 }
120 retval = buffer_front; 90 retval = buffer_front;
121 buffer_front += size; 91 buffer_front += size;
122#elif defined(USE_HOST_MALLOC)
123 size_t malloc_size = sizeof(struct malloc_object) + size;
124 struct malloc_object *obj = malloc(malloc_size);
125 retval = &obj->buf;
126 obj->next = NULL;
127 if (malloced_tail == NULL)
128 malloced_head = malloced_tail = obj;
129 else
130 malloced_tail->next = obj;
131 malloced_tail = obj;
132
133#else
134 retval = malloc(size);
135#endif
136 return retval; 92 return retval;
137} 93}
138 94
139
140#ifdef USE_ROCKBOX_ALLOC
141/* get the number of bytes currently being used */ 95/* get the number of bytes currently being used */
142size_t skin_buffer_usage(void) 96size_t skin_buffer_usage(void)
143{ 97{
@@ -147,16 +101,9 @@ size_t skin_buffer_freespace(void)
147{ 101{
148 return buf_size - skin_buffer_usage(); 102 return buf_size - skin_buffer_usage();
149} 103}
150 104#else
151static unsigned char *saved_buffer_pos = NULL; 105void* skin_buffer_alloc(size_t size)
152void skin_buffer_save_position(void)
153{
154 saved_buffer_pos = buffer_front;
155}
156
157void skin_buffer_restore_position(void)
158{ 106{
159 if (saved_buffer_pos) 107 return malloc(size);
160 buffer_front = saved_buffer_pos;
161} 108}
162#endif 109#endif
diff --git a/lib/skin_parser/skin_buffer.h b/lib/skin_parser/skin_buffer.h
index b2ed34e09f..7c9bb0b9c0 100644
--- a/lib/skin_parser/skin_buffer.h
+++ b/lib/skin_parser/skin_buffer.h
@@ -28,6 +28,18 @@
28void skin_buffer_init(char* buffer, size_t size); 28void skin_buffer_init(char* buffer, size_t size);
29/* Allocate size bytes from the buffer */ 29/* Allocate size bytes from the buffer */
30 30
31#ifndef __PCTOOL__
32#define INVALID_OFFSET (-1)
33#define IS_VALID_OFFSET(o) ((o) >= 0)
34long skin_buffer_to_offset(void *pointer);
35void* skin_buffer_from_offset(long offset);
36#else
37#define INVALID_OFFSET (NULL)
38#define IS_VALID_OFFSET(o) ((o) != NULL)
39#define skin_buffer_to_offset(p) p
40#define skin_buffer_from_offset(o) o
41#endif
42
31/* #define DEBUG_SKIN_ALLOCATIONS */ 43/* #define DEBUG_SKIN_ALLOCATIONS */
32 44
33#ifdef DEBUG_SKIN_ALLOCATIONS 45#ifdef DEBUG_SKIN_ALLOCATIONS
@@ -44,7 +56,4 @@ void* skin_buffer_alloc(size_t size);
44size_t skin_buffer_usage(void); 56size_t skin_buffer_usage(void);
45size_t skin_buffer_freespace(void); 57size_t skin_buffer_freespace(void);
46 58
47/* save and restore a buffer position incase a skin fails to load */
48void skin_buffer_save_position(void);
49void skin_buffer_restore_position(void);
50#endif 59#endif
diff --git a/lib/skin_parser/skin_debug.c b/lib/skin_parser/skin_debug.c
index 52f9127f1f..ecf238f1b1 100644
--- a/lib/skin_parser/skin_debug.c
+++ b/lib/skin_parser/skin_debug.c
@@ -31,6 +31,7 @@
31int debug_indent_level = 0; 31int debug_indent_level = 0;
32extern int skin_line; 32extern int skin_line;
33extern char* skin_start; 33extern char* skin_start;
34extern char* skin_buffer;
34 35
35/* Global error variables */ 36/* Global error variables */
36int error_line; 37int error_line;
@@ -38,6 +39,14 @@ int error_col;
38const char *error_line_start; 39const char *error_line_start;
39char* error_message; 40char* error_message;
40 41
42
43static inline struct skin_element*
44get_child(OFFSETTYPE(struct skin_element**) children, int child)
45{
46 struct skin_element **kids = SKINOFFSETTOPTR(skin_buffer, children);
47 return kids[child];
48}
49
41/* Debugging functions */ 50/* Debugging functions */
42void skin_error(enum skin_errorcode error, const char* cursor) 51void skin_error(enum skin_errorcode error, const char* cursor)
43{ 52{
@@ -144,14 +153,14 @@ void skin_debug_tree(struct skin_element* root)
144 printf("{ Viewport \n"); 153 printf("{ Viewport \n");
145 154
146 debug_indent_level++; 155 debug_indent_level++;
147 skin_debug_tree(current->children[0]); 156 skin_debug_tree(get_child(current->children, 0));
148 debug_indent_level--; 157 debug_indent_level--;
149 158
150 printf("}"); 159 printf("}");
151 break; 160 break;
152 161
153 case TEXT: 162 case TEXT:
154 text = current->data; 163 text = SKINOFFSETTOPTR(skin_buffer, current->data);
155 printf("* Plain text on line %d: \"%s\"\n", current->line, text); 164 printf("* Plain text on line %d: \"%s\"\n", current->line, text);
156 break; 165 break;
157 166
@@ -166,7 +175,7 @@ void skin_debug_tree(struct skin_element* root)
166 current->tag->name, 175 current->tag->name,
167 current->line, current->params_count); 176 current->line, current->params_count);
168 debug_indent_level++; 177 debug_indent_level++;
169 skin_debug_params(current->params_count, current->params); 178 skin_debug_params(current->params_count, SKINOFFSETTOPTR(skin_buffer, current->params));
170 debug_indent_level--; 179 debug_indent_level--;
171 skin_debug_indent(); 180 skin_debug_indent();
172 printf(")\n"); 181 printf(")\n");
@@ -185,7 +194,7 @@ void skin_debug_tree(struct skin_element* root)
185 debug_indent_level++; 194 debug_indent_level++;
186 for(i = 0; i < current->children_count; i++) 195 for(i = 0; i < current->children_count; i++)
187 { 196 {
188 skin_debug_tree(current->children[i]); 197 skin_debug_tree(get_child(current->children, i));
189 } 198 }
190 debug_indent_level--; 199 debug_indent_level--;
191 200
@@ -203,7 +212,7 @@ void skin_debug_tree(struct skin_element* root)
203 skin_debug_indent(); 212 skin_debug_indent();
204 printf("[ Enumeration %d\n", i); 213 printf("[ Enumeration %d\n", i);
205 debug_indent_level++; 214 debug_indent_level++;
206 skin_debug_tree(current->children[i]); 215 skin_debug_tree(get_child(current->children, i));
207 debug_indent_level--; 216 debug_indent_level--;
208 skin_debug_indent(); 217 skin_debug_indent();
209 printf("]\n"); 218 printf("]\n");
@@ -221,7 +230,7 @@ void skin_debug_tree(struct skin_element* root)
221 230
222 debug_indent_level++; 231 debug_indent_level++;
223 if (current->children) 232 if (current->children)
224 skin_debug_tree(current->children[0]); 233 skin_debug_tree(get_child(current->children, 0));
225 debug_indent_level--; 234 debug_indent_level--;
226 235
227 skin_debug_indent(); 236 skin_debug_indent();
@@ -229,7 +238,7 @@ void skin_debug_tree(struct skin_element* root)
229 break; 238 break;
230 } 239 }
231 240
232 current = current->next; 241 current = SKINOFFSETTOPTR(skin_buffer, current->next);
233 } 242 }
234 243
235} 244}
@@ -248,7 +257,7 @@ void skin_debug_params(int count, struct skin_tag_parameter params[])
248 break; 257 break;
249 258
250 case STRING: 259 case STRING:
251 printf("string: \"%s\"", params[i].data.text); 260 printf("string: \"%s\"", SKINOFFSETTOPTR(skin_buffer, params[i].data.text));
252 break; 261 break;
253 262
254 case INTEGER: 263 case INTEGER:
@@ -263,7 +272,7 @@ void skin_debug_params(int count, struct skin_tag_parameter params[])
263 case CODE: 272 case CODE:
264 printf("Skin Code: \n"); 273 printf("Skin Code: \n");
265 debug_indent_level++; 274 debug_indent_level++;
266 skin_debug_tree(params[i].data.code); 275 skin_debug_tree(SKINOFFSETTOPTR(skin_buffer, params[i].data.code));
267 debug_indent_level--; 276 debug_indent_level--;
268 skin_debug_indent(); 277 skin_debug_indent();
269 break; 278 break;
diff --git a/lib/skin_parser/skin_parser.c b/lib/skin_parser/skin_parser.c
index 2612cc8906..c49ac12a59 100644
--- a/lib/skin_parser/skin_parser.c
+++ b/lib/skin_parser/skin_parser.c
@@ -37,8 +37,6 @@ int skin_line = 0;
37char* skin_start = 0; 37char* skin_start = 0;
38int viewport_line = 0; 38int viewport_line = 0;
39 39
40static int tag_recursion_level = 0;
41
42#ifdef ROCKBOX 40#ifdef ROCKBOX
43static skin_callback callback = NULL; 41static skin_callback callback = NULL;
44static void* callback_data; 42static void* callback_data;
@@ -81,8 +79,6 @@ struct skin_element* skin_parse(const char* document)
81 struct skin_element* root = NULL; 79 struct skin_element* root = NULL;
82 struct skin_element* last = NULL; 80 struct skin_element* last = NULL;
83 81
84 struct skin_element** to_write = 0;
85
86 const char* cursor = document; /*Keeps track of location in the document*/ 82 const char* cursor = document; /*Keeps track of location in the document*/
87 83
88 skin_line = 1; 84 skin_line = 1;
@@ -93,14 +89,18 @@ struct skin_element* skin_parse(const char* document)
93 89
94 while(*cursor != '\0') 90 while(*cursor != '\0')
95 { 91 {
92 struct skin_element* tree = skin_parse_viewport(&cursor);
96 if(!root) 93 if(!root)
97 to_write = &root; 94 {
95 root = tree;
96 last = root;
97 }
98 else 98 else
99 to_write = &(last->next); 99 {
100 100 last->next = skin_buffer_to_offset(tree);
101 last = tree;
102 }
101 103
102 *to_write = skin_parse_viewport(&cursor);
103 last = *to_write;
104 if(!last) 104 if(!last)
105 { 105 {
106 skin_free_tree(root); /* Clearing any memory already used */ 106 skin_free_tree(root); /* Clearing any memory already used */
@@ -108,8 +108,8 @@ struct skin_element* skin_parse(const char* document)
108 } 108 }
109 109
110 /* Making sure last is at the end */ 110 /* Making sure last is at the end */
111 while(last->next) 111 while(IS_VALID_OFFSET(last->next))
112 last = last->next; 112 last = skin_buffer_from_offset(last->next);
113 113
114 } 114 }
115 return root; 115 return root;
@@ -121,8 +121,6 @@ static struct skin_element* skin_parse_viewport(const char** document)
121 struct skin_element* root = NULL; 121 struct skin_element* root = NULL;
122 struct skin_element* last = NULL; 122 struct skin_element* last = NULL;
123 struct skin_element* retval = NULL; 123 struct skin_element* retval = NULL;
124
125 tag_recursion_level = 0;
126 124
127 retval = skin_alloc_element(); 125 retval = skin_alloc_element();
128 if (!retval) 126 if (!retval)
@@ -132,7 +130,7 @@ static struct skin_element* skin_parse_viewport(const char** document)
132 retval->line = skin_line; 130 retval->line = skin_line;
133 viewport_line = skin_line; 131 viewport_line = skin_line;
134 132
135 struct skin_element** to_write = 0; 133 OFFSETTYPE(struct skin_element*)* children;
136 134
137 const char* cursor = *document; /* Keeps track of location in the document */ 135 const char* cursor = *document; /* Keeps track of location in the document */
138 const char* bookmark; /* Used when we need to look ahead */ 136 const char* bookmark; /* Used when we need to look ahead */
@@ -165,8 +163,8 @@ static struct skin_element* skin_parse_viewport(const char** document)
165 return retval; 163 return retval;
166 } 164 }
167 retval->children_count = 1; 165 retval->children_count = 1;
168 retval->children = skin_alloc_children(1); 166 children = skin_alloc_children(1);
169 if (!retval->children) 167 if (!children)
170 return NULL; 168 return NULL;
171 do 169 do
172 { 170 {
@@ -212,15 +210,19 @@ static struct skin_element* skin_parse_viewport(const char** document)
212 } 210 }
213 cursor = bookmark; 211 cursor = bookmark;
214 212
215 if(!root)
216 to_write = &root;
217 else
218 to_write = &(last->next);
219
220 if(sublines) 213 if(sublines)
221 { 214 {
222 *to_write = skin_parse_sublines(&cursor); 215 struct skin_element* out = skin_parse_sublines(&cursor);
223 last = *to_write; 216 if (!root)
217 {
218 root = out;
219 last = root;
220 }
221 else
222 {
223 last->next = skin_buffer_to_offset(out);
224 last = out;
225 }
224 if(!last) 226 if(!last)
225 return NULL; 227 return NULL;
226 } 228 }
@@ -237,15 +239,25 @@ static struct skin_element* skin_parse_viewport(const char** document)
237 if (check_viewport(cursor)) 239 if (check_viewport(cursor))
238 break; 240 break;
239#endif 241#endif
240 *to_write = skin_parse_line(&cursor); 242
241 last = *to_write; 243 struct skin_element* out = skin_parse_line(&cursor);
244 if (!root)
245 {
246 root = out;
247 last = root;
248 }
249 else
250 {
251 last->next = skin_buffer_to_offset(out);
252 last = out;
253 }
242 if(!last) 254 if(!last)
243 return NULL; 255 return NULL;
244 256
245 } 257 }
246 /* Making sure last is at the end */ 258 /* Making sure last is at the end */
247 while(last->next) 259 while(IS_VALID_OFFSET(last->next))
248 last = last->next; 260 last = skin_buffer_from_offset(last->next);
249 261
250 if(*cursor == '\n') 262 if(*cursor == '\n')
251 { 263 {
@@ -269,7 +281,8 @@ static struct skin_element* skin_parse_viewport(const char** document)
269 281
270 *document = cursor; 282 *document = cursor;
271 283
272 retval->children[0] = root; 284 children[0] = skin_buffer_to_offset(root);
285 retval->children = skin_buffer_to_offset(children);
273 return retval; 286 return retval;
274} 287}
275 288
@@ -293,6 +306,7 @@ static struct skin_element* skin_parse_line_optional(const char** document,
293 struct skin_element* root = NULL; 306 struct skin_element* root = NULL;
294 struct skin_element* current = NULL; 307 struct skin_element* current = NULL;
295 struct skin_element* retval = NULL; 308 struct skin_element* retval = NULL;
309 OFFSETTYPE(struct skin_element*)* children = NULL;
296 310
297 /* A wrapper for the line */ 311 /* A wrapper for the line */
298 retval = skin_alloc_element(); 312 retval = skin_alloc_element();
@@ -315,8 +329,8 @@ static struct skin_element* skin_parse_line_optional(const char** document,
315 329
316 if(retval->children_count > 0) 330 if(retval->children_count > 0)
317 { 331 {
318 retval->children = skin_alloc_children(1); 332 children = skin_alloc_children(1);
319 if (!retval->children) 333 if (!children)
320 return NULL; 334 return NULL;
321 } 335 }
322 336
@@ -344,10 +358,11 @@ static struct skin_element* skin_parse_line_optional(const char** document,
344 /* Allocating memory if necessary */ 358 /* Allocating memory if necessary */
345 if(root) 359 if(root)
346 { 360 {
347 current->next = skin_alloc_element(); 361 struct skin_element *next = skin_alloc_element();
348 if (!current->next) 362 if (!next)
349 return NULL; 363 return NULL;
350 current = current->next; 364 current->next = skin_buffer_to_offset(next);
365 current = next;
351 } 366 }
352 else 367 else
353 { 368 {
@@ -384,7 +399,10 @@ static struct skin_element* skin_parse_line_optional(const char** document,
384 *document = cursor; 399 *document = cursor;
385 400
386 if(root) 401 if(root)
387 retval->children[0] = root; 402 {
403 children[0] = skin_buffer_to_offset(root);
404 retval->children = skin_buffer_to_offset(children);
405 }
388 return retval; 406 return retval;
389} 407}
390 408
@@ -397,6 +415,7 @@ static struct skin_element* skin_parse_sublines_optional(const char** document,
397 int conditional) 415 int conditional)
398{ 416{
399 struct skin_element* retval; 417 struct skin_element* retval;
418 OFFSETTYPE(struct skin_element*)* children;
400 const char* cursor = *document; 419 const char* cursor = *document;
401 int sublines = 1; 420 int sublines = 1;
402 int i; 421 int i;
@@ -405,7 +424,7 @@ static struct skin_element* skin_parse_sublines_optional(const char** document,
405 if (!retval) 424 if (!retval)
406 return NULL; 425 return NULL;
407 retval->type = LINE_ALTERNATOR; 426 retval->type = LINE_ALTERNATOR;
408 retval->next = NULL; 427 retval->next = skin_buffer_to_offset(NULL);
409 retval->line = skin_line; 428 retval->line = skin_line;
410 429
411 /* First we count the sublines */ 430 /* First we count the sublines */
@@ -449,14 +468,16 @@ static struct skin_element* skin_parse_sublines_optional(const char** document,
449 468
450 /* ...and then we parse them */ 469 /* ...and then we parse them */
451 retval->children_count = sublines; 470 retval->children_count = sublines;
452 retval->children = skin_alloc_children(sublines); 471 children = skin_alloc_children(sublines);
453 if (!retval->children) 472 if (!children)
454 return NULL; 473 return NULL;
455 474
456 cursor = *document; 475 cursor = *document;
457 for(i = 0; i < sublines; i++) 476 for(i = 0; i < sublines; i++)
458 { 477 {
459 retval->children[i] = skin_parse_line_optional(&cursor, conditional); 478 children[i] = skin_buffer_to_offset(skin_parse_line_optional(&cursor, conditional));
479 if (children[i] < 0)
480 return NULL;
460 skip_whitespace(&cursor); 481 skip_whitespace(&cursor);
461 482
462 if(*cursor != MULTILINESYM && i != sublines - 1) 483 if(*cursor != MULTILINESYM && i != sublines - 1)
@@ -478,6 +499,7 @@ static struct skin_element* skin_parse_sublines_optional(const char** document,
478 } 499 }
479#endif 500#endif
480 *document = cursor; 501 *document = cursor;
502 retval->children = skin_buffer_to_offset(children);
481 503
482 return retval; 504 return retval;
483} 505}
@@ -490,13 +512,13 @@ static int skin_parse_tag(struct skin_element* element, const char** document)
490 char tag_name[3]; 512 char tag_name[3];
491 char* tag_args; 513 char* tag_args;
492 const struct tag_info *tag; 514 const struct tag_info *tag;
515 struct skin_tag_parameter* params = NULL;
493 516
494 int num_args = 1; 517 int num_args = 1;
495 int i; 518 int i;
496 int star = 0; /* Flag for the all-or-none option */ 519 int star = 0; /* Flag for the all-or-none option */
497 520
498 int optional = 0; 521 int optional = 0;
499 tag_recursion_level++;
500 522
501 /* Checking the tag name */ 523 /* Checking the tag name */
502 tag_name[0] = cursor[0]; 524 tag_name[0] = cursor[0];
@@ -597,8 +619,8 @@ static int skin_parse_tag(struct skin_element* element, const char** document)
597 619
598 cursor = bookmark; /* Restoring the cursor */ 620 cursor = bookmark; /* Restoring the cursor */
599 element->params_count = num_args; 621 element->params_count = num_args;
600 element->params = skin_alloc_params(num_args, tag_recursion_level<=1); 622 params = skin_alloc_params(num_args);
601 if (!element->params) 623 if (!params)
602 return 0; 624 return 0;
603 625
604 /* Now we have to actually parse each argument */ 626 /* Now we have to actually parse each argument */
@@ -686,14 +708,14 @@ static int skin_parse_tag(struct skin_element* element, const char** document)
686 else 708 else
687 type_code = *tag_args; 709 type_code = *tag_args;
688 /* Storing the type code */ 710 /* Storing the type code */
689 element->params[i].type_code = type_code; 711 params[i].type_code = type_code;
690 712
691 /* Checking a nullable argument for null. */ 713 /* Checking a nullable argument for null. */
692 if(*cursor == DEFAULTSYM && !isdigit(cursor[1])) 714 if(*cursor == DEFAULTSYM && !isdigit(cursor[1]))
693 { 715 {
694 if(islower(type_code)) 716 if(islower(type_code))
695 { 717 {
696 element->params[i].type = DEFAULT; 718 params[i].type = DEFAULT;
697 cursor++; 719 cursor++;
698 } 720 }
699 else 721 else
@@ -711,8 +733,8 @@ static int skin_parse_tag(struct skin_element* element, const char** document)
711 return 0; 733 return 0;
712 } 734 }
713 735
714 element->params[i].type = INTEGER; 736 params[i].type = INTEGER;
715 element->params[i].data.number = scan_int(&cursor); 737 params[i].data.number = scan_int(&cursor);
716 } 738 }
717 else if(tolower(type_code) == 'd') 739 else if(tolower(type_code) == 'd')
718 { 740 {
@@ -738,23 +760,23 @@ static int skin_parse_tag(struct skin_element* element, const char** document)
738 } 760 }
739 if (have_tenth == false) 761 if (have_tenth == false)
740 val *= 10; 762 val *= 10;
741 element->params[i].type = DECIMAL; 763 params[i].type = DECIMAL;
742 element->params[i].data.number = val; 764 params[i].data.number = val;
743 } 765 }
744 else if(tolower(type_code) == 'n' || 766 else if(tolower(type_code) == 'n' ||
745 tolower(type_code) == 's' || tolower(type_code) == 'f') 767 tolower(type_code) == 's' || tolower(type_code) == 'f')
746 { 768 {
747 /* Scanning a string argument */ 769 /* Scanning a string argument */
748 element->params[i].type = STRING; 770 params[i].type = STRING;
749 element->params[i].data.text = scan_string(&cursor); 771 params[i].data.text = skin_buffer_to_offset(scan_string(&cursor));
750 772
751 } 773 }
752 else if(tolower(type_code) == 'c') 774 else if(tolower(type_code) == 'c')
753 { 775 {
754 /* Recursively parsing a code argument */ 776 /* Recursively parsing a code argument */
755 element->params[i].type = CODE; 777 params[i].type = CODE;
756 element->params[i].data.code = skin_parse_code_as_arg(&cursor); 778 params[i].data.code = skin_buffer_to_offset(skin_parse_code_as_arg(&cursor));
757 if(!element->params[i].data.code) 779 if(params[i].data.code < 0)
758 return 0; 780 return 0;
759 } 781 }
760 else if (tolower(type_code) == 't') 782 else if (tolower(type_code) == 't')
@@ -763,9 +785,9 @@ static int skin_parse_tag(struct skin_element* element, const char** document)
763 child->type = TAG; 785 child->type = TAG;
764 if (!skin_parse_tag(child, &cursor)) 786 if (!skin_parse_tag(child, &cursor))
765 return 0; 787 return 0;
766 child->next = NULL; 788 child->next = skin_buffer_to_offset(NULL);
767 element->params[i].type = CODE; 789 params[i].type = CODE;
768 element->params[i].data.code = child; 790 params[i].data.code = skin_buffer_to_offset(child);
769 } 791 }
770 792
771 793
@@ -796,6 +818,7 @@ static int skin_parse_tag(struct skin_element* element, const char** document)
796 tag_args++; 818 tag_args++;
797 } 819 }
798 } 820 }
821 element->params = skin_buffer_to_offset(params);
799 822
800 /* Checking for a premature end */ 823 /* Checking for a premature end */
801 if(*tag_args != '\0' && !optional) 824 if(*tag_args != '\0' && !optional)
@@ -811,7 +834,6 @@ static int skin_parse_tag(struct skin_element* element, const char** document)
811 } 834 }
812#endif 835#endif
813 *document = cursor; 836 *document = cursor;
814 tag_recursion_level--;
815 837
816 return 1; 838 return 1;
817} 839}
@@ -855,9 +877,10 @@ static int skin_parse_text(struct skin_element* element, const char** document,
855 /* Copying the text into the element struct */ 877 /* Copying the text into the element struct */
856 element->type = TEXT; 878 element->type = TEXT;
857 element->line = skin_line; 879 element->line = skin_line;
858 element->next = NULL; 880 element->next = skin_buffer_to_offset(NULL);
859 element->data = text = skin_alloc_string(length); 881 text = skin_alloc_string(length);
860 if (!element->data) 882 element->data = skin_buffer_to_offset(text);
883 if (element->data < 0)
861 return 0; 884 return 0;
862 885
863 for(dest = 0; dest < length; dest++) 886 for(dest = 0; dest < length; dest++)
@@ -896,6 +919,7 @@ static int skin_parse_conditional(struct skin_element* element, const char** doc
896 const char *false_branch = NULL; 919 const char *false_branch = NULL;
897 const char *conditional_end = NULL; 920 const char *conditional_end = NULL;
898#endif 921#endif
922 OFFSETTYPE(struct skin_element*)* children_array = NULL;
899 923
900 /* Some conditional tags allow for target feature checking, 924 /* Some conditional tags allow for target feature checking,
901 * so to handle that call the callback as usual with type == TAG 925 * so to handle that call the callback as usual with type == TAG
@@ -994,23 +1018,23 @@ static int skin_parse_conditional(struct skin_element* element, const char** doc
994 { 1018 {
995 const char* emptyline= ""; 1019 const char* emptyline= "";
996 children = 1; 1020 children = 1;
997 element->children = skin_alloc_children(children); 1021 children_array = skin_alloc_children(children);
998 if (!element->children) 1022 if (!children_array)
999 return 0; 1023 return 0;
1000 element->children_count = children; 1024 element->children_count = children;
1001 element->children[0] = skin_parse_code_as_arg(&emptyline); 1025 children_array[0] = skin_buffer_to_offset(skin_parse_code_as_arg(&emptyline));
1002 } 1026 }
1003 else 1027 else
1004 { 1028 {
1005 element->children = skin_alloc_children(children); 1029 children_array = skin_alloc_children(children);
1006 if (!element->children) 1030 if (!children_array)
1007 return 0; 1031 return 0;
1008 element->children_count = children; 1032 element->children_count = children;
1009 1033
1010 for(i = 0; i < children; i++) 1034 for(i = 0; i < children; i++)
1011 { 1035 {
1012 element->children[i] = skin_parse_code_as_arg(&cursor); 1036 children_array[i] = skin_buffer_to_offset(skin_parse_code_as_arg(&cursor));
1013 if (element->children[i] == NULL) 1037 if (children_array[i] < 0)
1014 return 0; 1038 return 0;
1015 skip_whitespace(&cursor); 1039 skip_whitespace(&cursor);
1016#ifdef ROCKBOX 1040#ifdef ROCKBOX
@@ -1035,6 +1059,7 @@ static int skin_parse_conditional(struct skin_element* element, const char** doc
1035 } 1059 }
1036 } 1060 }
1037 *document = cursor; 1061 *document = cursor;
1062 element->children = skin_buffer_to_offset(children_array);
1038 1063
1039 return 1; 1064 return 1;
1040} 1065}
@@ -1056,7 +1081,7 @@ static int skin_parse_comment(struct skin_element* element, const char** documen
1056 element->type = COMMENT; 1081 element->type = COMMENT;
1057 element->line = skin_line; 1082 element->line = skin_line;
1058#ifdef ROCKBOX 1083#ifdef ROCKBOX
1059 element->data = NULL; 1084 element->data = INVALID_OFFSET;
1060#else 1085#else
1061 element->data = text = skin_alloc_string(length); 1086 element->data = text = skin_alloc_string(length);
1062 if (!element->data) 1087 if (!element->data)
@@ -1122,7 +1147,6 @@ static struct skin_element* skin_parse_code_as_arg(const char** document)
1122 return skin_parse_line_optional(document, 1); 1147 return skin_parse_line_optional(document, 1);
1123} 1148}
1124 1149
1125
1126/* Memory management */ 1150/* Memory management */
1127struct skin_element* skin_alloc_element() 1151struct skin_element* skin_alloc_element()
1128{ 1152{
@@ -1131,10 +1155,12 @@ struct skin_element* skin_alloc_element()
1131 if (!retval) 1155 if (!retval)
1132 return NULL; 1156 return NULL;
1133 retval->type = UNKNOWN; 1157 retval->type = UNKNOWN;
1134 retval->next = NULL; 1158 retval->next = skin_buffer_to_offset(NULL);
1159 retval->params = skin_buffer_to_offset(NULL);
1135 retval->tag = NULL; 1160 retval->tag = NULL;
1136 retval->params_count = 0; 1161 retval->params_count = 0;
1137 retval->children_count = 0; 1162 retval->children_count = 0;
1163 retval->data = INVALID_OFFSET;
1138 1164
1139 return retval; 1165 return retval;
1140 1166
@@ -1144,16 +1170,8 @@ struct skin_element* skin_alloc_element()
1144 * enough for any tag. params should be used straight away by the callback 1170 * enough for any tag. params should be used straight away by the callback
1145 * so this is safe. 1171 * so this is safe.
1146 */ 1172 */
1147struct skin_tag_parameter* skin_alloc_params(int count, bool use_shared_params) 1173struct skin_tag_parameter* skin_alloc_params(int count)
1148{ 1174{
1149#ifdef ROCKBOX
1150 static struct skin_tag_parameter params[MAX_TAG_PARAMS];
1151 if (use_shared_params && count <= MAX_TAG_PARAMS)
1152 {
1153 memset(params, 0, sizeof(params));
1154 return params;
1155 }
1156#endif
1157 size_t size = sizeof(struct skin_tag_parameter) * count; 1175 size_t size = sizeof(struct skin_tag_parameter) * count;
1158 return (struct skin_tag_parameter*)skin_buffer_alloc(size); 1176 return (struct skin_tag_parameter*)skin_buffer_alloc(size);
1159 1177
@@ -1164,9 +1182,9 @@ char* skin_alloc_string(int length)
1164 return (char*)skin_buffer_alloc(sizeof(char) * (length + 1)); 1182 return (char*)skin_buffer_alloc(sizeof(char) * (length + 1));
1165} 1183}
1166 1184
1167struct skin_element** skin_alloc_children(int count) 1185OFFSETTYPE(struct skin_element*)* skin_alloc_children(int count)
1168{ 1186{
1169 return (struct skin_element**) 1187 return (OFFSETTYPE(struct skin_element*)*)
1170 skin_buffer_alloc(sizeof(struct skin_element*) * count); 1188 skin_buffer_alloc(sizeof(struct skin_element*) * count);
1171} 1189}
1172 1190
diff --git a/lib/skin_parser/skin_parser.h b/lib/skin_parser/skin_parser.h
index 3e0634976c..120112d995 100644
--- a/lib/skin_parser/skin_parser.h
+++ b/lib/skin_parser/skin_parser.h
@@ -29,6 +29,25 @@ extern "C"
29#include <stdlib.h> 29#include <stdlib.h>
30#include <stdbool.h> 30#include <stdbool.h>
31 31
32#if defined(ROCKBOX) && !defined(__PCTOOL__)
33/* Use this type and macro to convert a pointer from the
34 * skin buffer to a useable pointer */
35typedef long skinoffset_t;
36#define SKINOFFSETTOPTR(base, offset) ((offset) < 0 ? NULL : ((void*)&base[offset]))
37#define PTRTOSKINOFFSET(base, pointer) ((pointer) ? ((void*)pointer-(void*)base) : -1)
38/* Use this macro when declaring a variable to self-document the code.
39 * type is the actual type being pointed to (i.e OFFSETTYPE(char*) foo )
40 *
41 * WARNING: Don't use the PTRTOSKINOFFSET() around a function call as it wont
42 * do what you expect.
43 */
44#define OFFSETTYPE(type) skinoffset_t
45#else
46#define SKINOFFSETTOPTR(base, offset) offset
47#define PTRTOSKINOFFSET(base, pointer) pointer
48#define OFFSETTYPE(type) type
49#endif
50
32/******************************************************************** 51/********************************************************************
33 ****** Data Structures ********************************************* 52 ****** Data Structures *********************************************
34 *******************************************************************/ 53 *******************************************************************/
@@ -78,8 +97,8 @@ struct skin_tag_parameter
78 union 97 union
79 { 98 {
80 int number; 99 int number;
81 char* text; 100 OFFSETTYPE(char*) text;
82 struct skin_element* code; 101 OFFSETTYPE(struct skin_element*) code;
83 } data; 102 } data;
84 103
85 char type_code; 104 char type_code;
@@ -92,20 +111,20 @@ struct skin_tag_parameter
92struct skin_element 111struct skin_element
93{ 112{
94 /* Link to the next element */ 113 /* Link to the next element */
95 struct skin_element* next; 114 OFFSETTYPE(struct skin_element*) next;
96 /* Pointer to an array of children */ 115 /* Pointer to an array of children */
97 struct skin_element** children; 116 OFFSETTYPE(struct skin_element**) children;
98 /* Placeholder for element data 117 /* Placeholder for element data
99 * TEXT and COMMENT uses it for the text string 118 * TEXT and COMMENT uses it for the text string
100 * TAG, VIEWPORT, LINE, etc may use it for post parse extra storage 119 * TAG, VIEWPORT, LINE, etc may use it for post parse extra storage
101 */ 120 */
102 void* data; 121 OFFSETTYPE(void*) data;
103 122
104 /* The tag or conditional name */ 123 /* The tag or conditional name */
105 const struct tag_info *tag; 124 const struct tag_info *tag;
106 125
107 /* Pointer to an array of parameters */ 126 /* Pointer to an array of parameters */
108 struct skin_tag_parameter* params; 127 OFFSETTYPE(struct skin_tag_parameter*) params;
109 128
110 /* Number of elements in the children array */ 129 /* Number of elements in the children array */
111 short children_count; 130 short children_count;
@@ -140,8 +159,8 @@ struct skin_element* skin_parse(const char* document);
140#endif 159#endif
141/* Memory management functions */ 160/* Memory management functions */
142struct skin_element* skin_alloc_element(void); 161struct skin_element* skin_alloc_element(void);
143struct skin_element** skin_alloc_children(int count); 162OFFSETTYPE(struct skin_element*)* skin_alloc_children(int count);
144struct skin_tag_parameter* skin_alloc_params(int count, bool use_shared_params); 163struct skin_tag_parameter* skin_alloc_params(int count);
145char* skin_alloc_string(int length); 164char* skin_alloc_string(int length);
146 165
147void skin_free_tree(struct skin_element* root); 166void skin_free_tree(struct skin_element* root);
diff --git a/tools/checkwps/checkwps.c b/tools/checkwps/checkwps.c
index 846dd97191..ec0262bfe7 100644
--- a/tools/checkwps/checkwps.c
+++ b/tools/checkwps/checkwps.c
@@ -37,6 +37,7 @@
37 37
38bool debug_wps = true; 38bool debug_wps = true;
39int wps_verbose_level = 0; 39int wps_verbose_level = 0;
40char *skin_buffer;
40 41
41int errno; 42int errno;
42 43
@@ -252,8 +253,6 @@ int main(int argc, char **argv)
252 struct wps_data wps={0}; 253 struct wps_data wps={0};
253 enum screen_type screen = SCREEN_MAIN; 254 enum screen_type screen = SCREEN_MAIN;
254 struct screen* wps_screen; 255 struct screen* wps_screen;
255
256 char* buffer = NULL;
257 256
258 /* No arguments -> print the help text 257 /* No arguments -> print the help text
259 * Also print the help text upon -h or --help */ 258 * Also print the help text upon -h or --help */
@@ -278,14 +277,14 @@ int main(int argc, char **argv)
278 wps_verbose_level++; 277 wps_verbose_level++;
279 } 278 }
280 } 279 }
281 buffer = malloc(SKIN_BUFFER_SIZE); 280 skin_buffer = malloc(SKIN_BUFFER_SIZE);
282 if (!buffer) 281 if (!skin_buffer)
283 { 282 {
284 printf("mallloc fail!\n"); 283 printf("mallloc fail!\n");
285 return 1; 284 return 1;
286 } 285 }
287 286
288 skin_buffer_init(buffer, SKIN_BUFFER_SIZE); 287 skin_buffer_init(skin_buffer, SKIN_BUFFER_SIZE);
289 288
290 /* Go through every skin that was thrown at us, error out at the first 289 /* Go through every skin that was thrown at us, error out at the first
291 * flawed wps */ 290 * flawed wps */
@@ -311,7 +310,7 @@ int main(int argc, char **argv)
311 310
312 printf("WPS parsed OK\n\n"); 311 printf("WPS parsed OK\n\n");
313 if (wps_verbose_level>2) 312 if (wps_verbose_level>2)
314 skin_debug_tree(wps.tree); 313 skin_debug_tree(SKINOFFSETTOPTR(skin_buffer, wps.tree));
315 filearg++; 314 filearg++;
316 } 315 }
317 return 0; 316 return 0;