summaryrefslogtreecommitdiff
path: root/apps/gui/skin_engine/skin_render.c
diff options
context:
space:
mode:
authorJonathan Gordon <rockbox@jdgordon.info>2011-11-15 14:11:08 +0000
committerJonathan Gordon <rockbox@jdgordon.info>2011-11-15 14:11:08 +0000
commit9e07ef2b0adb8fca7e5a9e516397e533653f8836 (patch)
tree0a283550421917e52ee04068b84a464976f0c4f2 /apps/gui/skin_engine/skin_render.c
parent101693fd3047fb64e766580e80635a424fa25c4d (diff)
downloadrockbox-9e07ef2b0adb8fca7e5a9e516397e533653f8836.tar.gz
rockbox-9e07ef2b0adb8fca7e5a9e516397e533653f8836.zip
Use buflib for all skin engine allocations.
Massive thanks to Michael Chicoine and other testers for finding the early bugs. This removes all skin memory limitations git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30991 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/gui/skin_engine/skin_render.c')
-rw-r--r--apps/gui/skin_engine/skin_render.c209
1 files changed, 122 insertions, 87 deletions
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';