diff --git a/apps/gui/bitmap/list-skinned.c b/apps/gui/bitmap/list-skinned.c
index 208b2df..1346ad3 100644
--- a/apps/gui/bitmap/list-skinned.c
+++ b/apps/gui/bitmap/list-skinned.c
@@ -182,15 +182,16 @@ bool skinlist_draw(struct screen *display, struct gui_synclist *list)
         is_selected = list->show_selection_marker &&
                 list_start_item+cur_line == list->selected_item;
         
-        for (viewport = listcfg[screen]->data->tree;
+        for (viewport = SKINOFFSETTOPTR(skin_buffer, listcfg[screen]->data->tree);
              viewport;
              viewport = viewport->next)
         {
             int origional_x, origional_y;
             int origional_w, origional_h;
+            char *viewport_label = SKINOFFSETTOPTR(skin_buffer, skin_viewport->label);
             skin_viewport = (struct skin_viewport*)viewport->data;
-            if (viewport->children == 0 || !skin_viewport->label ||
-                (skin_viewport->label && strcmp(label, skin_viewport->label))
+            if (viewport->children == 0 || !viewport_label ||
+                (skin_viewport->label && strcmp(label, viewport_label))
                 )
                 continue;
             if (is_selected)
@@ -220,12 +221,13 @@ bool skinlist_draw(struct screen *display, struct gui_synclist *list)
             display->set_viewport(&skin_viewport->vp);
 #ifdef HAVE_LCD_BITMAP
             /* Set images to not to be displayed */
-            struct skin_token_list *imglist = wps.data->images;
+            struct skin_token_list *imglist = SKINOFFSETTOPTR(skin_buffer, wps.data->images);
             while (imglist)
             {
-                struct gui_img *img = (struct gui_img *)imglist->token->value.data;
+                struct wps_token *token = SKINOFFSETTOPTR(skin_buffer, imglist->token);
+                struct gui_img *img = SKINOFFSETTOPTR(skin_buffer, token->value.data);
                 img->display = -1;
-                imglist = imglist->next;
+                imglist = SKINOFFSETTOPTR(skin_buffer, imglist->next);
             }
 #endif
             skin_render_viewport(viewport->children[0],
diff --git a/apps/gui/skin_engine/skin_display.c b/apps/gui/skin_engine/skin_display.c
index 95e4310..4ee7b25 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)
     struct wps_data *data = skin->data;
     const struct screen *display = skin->display;
     const int   screen = display->screen_type;
-    struct skin_viewport *svp = skin_find_item(VP_DEFAULT_LABEL, SKIN_FIND_VP, data);
+    struct skin_viewport *svp = skin_find_item(VP_DEFAULT_LABEL_STRING, SKIN_FIND_VP, data);
 
     struct viewport *vp = &svp->vp;
     viewport_set_defaults(vp, screen);
@@ -131,7 +131,7 @@ void skin_statusbar_changed(struct gui_wps *skin)
 void draw_progressbar(struct gui_wps *gwps, int line, struct progressbar *pb)
 {
     struct screen *display = gwps->display;
-    struct viewport *vp = pb->vp;
+    struct viewport *vp = SKINOFFSETTOPTR(skin_buffer, pb->vp);
     struct wps_state *state = skin_get_global_state();
     struct mp3entry *id3 = state->id3;
     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)
         flags |= INNER_NOFILL;
     }
 
-    if (pb->slider)
+    if (SKINOFFSETTOPTR(skin_buffer, pb->slider))
     {
-        struct gui_img *img = pb->slider;
+        struct gui_img *img = SKINOFFSETTOPTR(skin_buffer, pb->slider);
         /* clear the slider */
         screen_clear_area(display, x, y, width, height);
 
@@ -245,9 +245,9 @@ void draw_progressbar(struct gui_wps *gwps, int line, struct progressbar *pb)
         }
     }
     
-    if (pb->backdrop)
+    if (SKINOFFSETTOPTR(skin_buffer, pb->backdrop))
     {
-        struct gui_img *img = pb->backdrop;
+        struct gui_img *img = SKINOFFSETTOPTR(skin_buffer, pb->backdrop);
         char *img_data = core_get_data(img->buflib_handle);
 #if LCD_DEPTH > 1
         if(img->bm.format == FORMAT_MONO) {
@@ -269,11 +269,12 @@ void draw_progressbar(struct gui_wps *gwps, int line, struct progressbar *pb)
     
     if (!pb->nobar)
     {
-        if (pb->image)
+        struct gui_img *img = SKINOFFSETTOPTR(skin_buffer, pb->image);
+        if (img)
         {
-            char *img_data = core_get_data(pb->image->buflib_handle);
-            pb->image->bm.data = img_data;
-            gui_bitmap_scrollbar_draw(display, &pb->image->bm,
+            char *img_data = core_get_data(img->buflib_handle);
+            img->bm.data = img_data;
+            gui_bitmap_scrollbar_draw(display, &img->bm,
                                     x, y, width, height,
                                     length, 0, end, flags);
         }
@@ -282,11 +283,11 @@ void draw_progressbar(struct gui_wps *gwps, int line, struct progressbar *pb)
                                length, 0, end, flags);
     }
 
-    if (pb->slider)
+    if (SKINOFFSETTOPTR(skin_buffer, pb->slider))
     {
         int xoff = 0, yoff = 0;
         int w = width, h = height;
-        struct gui_img *img = pb->slider;
+        struct gui_img *img = SKINOFFSETTOPTR(skin_buffer, pb->slider);
         char *img_data = core_get_data(img->buflib_handle);
 
         if (flags&HORIZONTAL)
@@ -391,11 +392,12 @@ void wps_display_images(struct gui_wps *gwps, struct viewport* vp)
 
     struct wps_data *data = gwps->data;
     struct screen *display = gwps->display;
-    struct skin_token_list *list = data->images;
+    struct skin_token_list *list = SKINOFFSETTOPTR(skin_buffer, data->images);
 
     while (list)
     {
-        struct gui_img *img = (struct gui_img*)list->token->value.data;
+        struct wps_token *token = SKINOFFSETTOPTR(skin_buffer, list->token);
+        struct gui_img *img = (struct gui_img*)SKINOFFSETTOPTR(skin_buffer, token->value.data);
         if (img->using_preloaded_icons && img->display >= 0)
         {
             screen_put_icon(display, img->x, img->y, img->display);
@@ -406,20 +408,21 @@ void wps_display_images(struct gui_wps *gwps, struct viewport* vp)
             {
                 wps_draw_image(gwps, img, img->display);
             }
-            else if (img->always_display && img->vp == vp)
+            else if (img->always_display && SKINOFFSETTOPTR(skin_buffer, img->vp) == vp)
             {
                 wps_draw_image(gwps, img, 0);
             }
         }
-        list = list->next;
+        list = SKINOFFSETTOPTR(skin_buffer, list->next);
     }
 #ifdef HAVE_ALBUMART
     /* now draw the AA */
-    if (data->albumart && data->albumart->vp == vp
-        && data->albumart->draw_handle >= 0)
+    struct skin_albumart *aa = SKINOFFSETTOPTR(skin_buffer, data->albumart);
+    if (aa && SKINOFFSETTOPTR(skin_buffer, aa->vp) == vp
+        && aa->draw_handle >= 0)
     {
-        draw_album_art(gwps, data->albumart->draw_handle, false);
-        data->albumart->draw_handle = -1;
+        draw_album_art(gwps, aa->draw_handle, false);
+        aa->draw_handle = -1;
     }
 #endif
 
@@ -442,8 +445,8 @@ int evaluate_conditional(struct gui_wps *gwps, int offset,
 
     int intval = num_options < 2 ? 2 : num_options;
     /* get_token_value needs to know the number of options in the enum */
-    value = get_token_value(gwps, conditional->token, offset,
-                            result, sizeof(result), &intval);
+    value = get_token_value(gwps, SKINOFFSETTOPTR(skin_buffer, conditional->token),
+                    offset, result, sizeof(result), &intval);
 
     /* intval is now the number of the enum option we want to read,
        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 bd875fe..1e0304c 100644
--- a/apps/gui/skin_engine/skin_engine.c
+++ b/apps/gui/skin_engine/skin_engine.c
@@ -48,7 +48,7 @@ void theme_init_buffer(void)
     skins_initialising = false;
 }
 #else
-static char skin_buffer[SKIN_BUFFER_SIZE];
+char skin_buffer[SKIN_BUFFER_SIZE];
 void theme_init_buffer(void)
 {
     skins_initialising = false;
@@ -95,8 +95,13 @@ void gui_sync_skin_init(void)
             skins[j][i].gui_wps.display = &screens[i];
             memset(skins[j][i].gui_wps.data, 0, sizeof(struct wps_data));
             skins[j][i].data.wps_loaded = false;
+            skins[j][i].data.tree = PTRTOSKINOFFSET(skin_buffer, NULL);
+#ifdef HAVE_LCD_BITMAP
+            skins[j][i].data.font_ids = PTRTOSKINOFFSET(skin_buffer, NULL);
+            skins[j][i].data.images = PTRTOSKINOFFSET(skin_buffer, NULL);
+#endif
 #ifdef HAVE_ALBUMART
-            skins[j][i].data.albumart = NULL;
+            skins[j][i].data.albumart = PTRTOSKINOFFSET(skin_buffer, NULL);
             skins[j][i].data.playback_aa_slot = -1;
 #endif
         }
diff --git a/apps/gui/skin_engine/skin_parser.c b/apps/gui/skin_engine/skin_parser.c
index 1557783..3463e70 100644
--- a/apps/gui/skin_engine/skin_parser.c
+++ b/apps/gui/skin_engine/skin_parser.c
@@ -78,6 +78,10 @@
 
 #define GLYPHS_TO_CACHE 256
 
+#if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1))
+static char *backdrop_filename;
+#endif
+
 static bool isdefault(struct skin_tag_parameter *param)
 {
     return param->type == DEFAULT;
@@ -103,16 +107,19 @@ typedef int (*parse_function)(struct skin_element *element,
 /* add a skin_token_list item to the list chain. ALWAYS appended because some of the
  * chains require the order to be kept.
  */
-static void add_to_ll_chain(struct skin_token_list **list, struct skin_token_list *item)
+static void add_to_ll_chain(skinoffset *listoffset, struct skin_token_list *item)
 {
-    if (*list == NULL)
-        *list = item;
+    struct skin_token_list *list = SKINOFFSETTOPTR(skin_buffer, *listoffset);
+    if (list == NULL)
+    {
+        list = item;
+        *listoffset = PTRTOSKINOFFSET(skin_buffer, list);
+    }
     else
     {
-        struct skin_token_list *t = *list;
-        while (t->next)
-            t = t->next;
-        t->next = item;
+        while (SKINOFFSETTOPTR(skin_buffer, list->next))
+            list = SKINOFFSETTOPTR(skin_buffer, list->next);
+        list->next = PTRTOSKINOFFSET(skin_buffer, item);
     }
 }
 
@@ -133,22 +140,22 @@ void *skin_find_item(const char *label, enum skin_find_what what,
     {
         case SKIN_FIND_UIVP:
         case SKIN_FIND_VP:
-            list.vplist = data->tree;
+            list.vplist = SKINOFFSETTOPTR(skin_buffer, data->tree);
             isvplist = true;
         break;
 #ifdef HAVE_LCD_BITMAP
         case SKIN_FIND_IMAGE:
-            list.linkedlist = data->images;
+            list.linkedlist = SKINOFFSETTOPTR(skin_buffer, data->images);
         break;
 #endif
 #ifdef HAVE_TOUCHSCREEN
         case SKIN_FIND_TOUCHREGION:
-            list.linkedlist = data->touchregions;
+            list.linkedlist = SKINOFFSETTOPTR(skin_buffer, data->touchregions);
         break;
 #endif
 #ifdef HAVE_SKIN_VARIABLES
         case SKIN_VARIABLE:
-            list.linkedlist = data->skinvars;
+            list.linkedlist = SKINOFFSETTOPTR(skin_buffer, data->skinvars);
         break;
 #endif
     }
@@ -156,31 +163,37 @@ void *skin_find_item(const char *label, enum skin_find_what what,
     while (list.linkedlist)
     {
         bool skip = false;
+        struct wps_token *token;
+        if (!isvplist)
+            token = SKINOFFSETTOPTR(skin_buffer, list.linkedlist->token);
         switch (what)
         {
             case SKIN_FIND_UIVP:
             case SKIN_FIND_VP:
                 ret = list.vplist->data;
-                itemlabel = ((struct skin_viewport *)ret)->label;
+                if (((struct skin_viewport *)ret)->label == VP_DEFAULT_LABEL)
+                    itemlabel = VP_DEFAULT_LABEL_STRING;
+                else
+                    itemlabel = SKINOFFSETTOPTR(skin_buffer, ((struct skin_viewport *)ret)->label);
                 skip = !(((struct skin_viewport *)ret)->is_infovp == 
                     (what==SKIN_FIND_UIVP));
                 break;
 #ifdef HAVE_LCD_BITMAP
             case SKIN_FIND_IMAGE:
-                ret = list.linkedlist->token->value.data;
-                itemlabel = ((struct gui_img *)ret)->label;
+                ret = SKINOFFSETTOPTR(skin_buffer, token->value.data);
+                itemlabel = SKINOFFSETTOPTR(skin_buffer, ((struct gui_img *)ret)->label);
                 break;
 #endif
 #ifdef HAVE_TOUCHSCREEN
             case SKIN_FIND_TOUCHREGION:
-                ret = list.linkedlist->token->value.data;
-                itemlabel = ((struct touchregion *)ret)->label;
+                ret = SKINOFFSETTOPTR(skin_buffer, token->value.data);
+                itemlabel = SKINOFFSETTOPTR(skin_buffer, ((struct touchregion *)ret)->label);
                 break;
 #endif
 #ifdef HAVE_SKIN_VARIABLES
             case SKIN_VARIABLE:
-                ret = list.linkedlist->token->value.data;
-                itemlabel = ((struct skin_var *)ret)->label;
+                ret = SKINOFFSETTOPTR(skin_buffer, token->value.data);
+                itemlabel = SKINOFFSETTOPTR(skin_buffer, ((struct skin_var *)ret)->label);
                 break;
 #endif
                 
@@ -191,7 +204,7 @@ void *skin_find_item(const char *label, enum skin_find_what what,
         if (isvplist)
             list.vplist = list.vplist->next;
         else
-            list.linkedlist = list.linkedlist->next;
+            list.linkedlist = SKINOFFSETTOPTR(skin_buffer, list.linkedlist->next);
     }
     return NULL;
 }
@@ -212,10 +225,10 @@ static struct skin_token_list *new_skin_token_list_item(struct wps_token *token,
         token = (struct wps_token*)skin_buffer_alloc(sizeof(struct wps_token));
     if (!llitem || !token)
         return NULL;
-    llitem->next = NULL;
-    llitem->token = token;
+    llitem->next = PTRTOSKINOFFSET(skin_buffer, NULL);
+    llitem->token = PTRTOSKINOFFSET(skin_buffer, token);
     if (token_data)
-        llitem->token->value.data = token_data;
+        token->value.data = PTRTOSKINOFFSET(skin_buffer, token_data);
     return llitem;
 }
 
@@ -226,11 +239,11 @@ static int parse_statusbar_tags(struct skin_element* element,
     (void)element;
     if (token->type == SKIN_TOKEN_DRAW_INBUILTBAR)
     {
-        token->value.data = (void*)&curr_vp->vp;
+        token->value.data = PTRTOSKINOFFSET(skin_buffer, (void*)&curr_vp->vp);
     }
     else
     {
-        struct skin_element *def_vp = wps_data->tree;
+        struct skin_element *def_vp = SKINOFFSETTOPTR(skin_buffer, wps_data->tree);
         struct skin_viewport *default_vp = def_vp->data;
         if (def_vp->params_count == 0)
         {
@@ -295,9 +308,9 @@ static int parse_image_display(struct skin_element *element,
     {
         return WPS_ERROR_INVALID_PARAM;
     }
-    id->label = label;
+    id->label = PTRTOSKINOFFSET(skin_buffer, label);
     id->offset = 0;
-    id->token = NULL;
+    id->token = PTRTOSKINOFFSET(skin_buffer, NULL);
     if (img->using_preloaded_icons)
     {
         token->type = SKIN_TOKEN_IMAGE_DISPLAY_LISTICON;
@@ -306,7 +319,7 @@ static int parse_image_display(struct skin_element *element,
     if (element->params_count > 1)
     {
         if (element->params[1].type == CODE)
-            id->token = element->params[1].data.code->data;
+            id->token = PTRTOSKINOFFSET(skin_buffer, element->params[1].data.code->data);
         /* specify a number. 1 being the first subimage (i.e top) NOT 0 */
         else if (element->params[1].type == INTEGER)
             id->subimage = element->params[1].data.number - 1;
@@ -324,7 +337,7 @@ static int parse_image_display(struct skin_element *element,
             id->subimage = 0;
         }
     }
-    token->value.data = id;
+    token->value.data = PTRTOSKINOFFSET(skin_buffer, id);
     return 0;
 }
 
@@ -358,7 +371,7 @@ static int parse_image_load(struct skin_element *element,
         return WPS_ERROR_INVALID_PARAM;
     /* save a pointer to the filename */
     img->bm.data = (char*)filename;
-    img->label = id;
+    img->label = PTRTOSKINOFFSET(skin_buffer, id);
     img->x = x;
     img->y = y;
     img->num_subimages = 1;
@@ -368,7 +381,7 @@ static int parse_image_load(struct skin_element *element,
     img->buflib_handle = -1;
 
     /* save current viewport */
-    img->vp = &curr_vp->vp;
+    img->vp = PTRTOSKINOFFSET(skin_buffer, &curr_vp->vp);
 
     if (token->type == SKIN_TOKEN_IMAGE_DISPLAY)
     {
@@ -450,12 +463,12 @@ static int parse_playlistview(struct skin_element *element,
         (struct playlistviewer *)skin_buffer_alloc(sizeof(struct playlistviewer));
     if (!viewer)
         return WPS_ERROR_INVALID_PARAM;
-    viewer->vp = &curr_vp->vp;
+    viewer->vp = PTRTOSKINOFFSET(skin_buffer, &curr_vp->vp);
     viewer->show_icons = true;
     viewer->start_offset = element->params[0].data.number;
-    viewer->line = element->params[1].data.code;
+    viewer->line = PTRTOSKINOFFSET(skin_buffer, element->params[1].data.code);
     
-    token->value.data = (void*)viewer;
+    token->value.data = PTRTOSKINOFFSET(skin_buffer, (void*)viewer);
     
     return 0;
 }
@@ -485,7 +498,7 @@ static int parse_viewport_gradient_setup(struct skin_element *element,
         cfg->text = curr_vp->vp.fg_pattern;
     }
 
-    token->value.data = cfg;
+    token->value.data = PTRTOSKINOFFSET(skin_buffer, cfg);
     return 0; 
 }
 #endif
@@ -498,7 +511,7 @@ static int parse_listitem(struct skin_element *element,
     struct listitem *li = (struct listitem *)skin_buffer_alloc(sizeof(struct listitem));
     if (!li)
         return 1;
-    token->value.data = li;
+    token->value.data = PTRTOSKINOFFSET(skin_buffer, li);
     if (element->params_count == 0)
         li->offset = 0;
     else
@@ -534,7 +547,7 @@ static int parse_listitemviewport(struct skin_element *element,
     if (element->params_count > 3 &&
         !strcmp(element->params[3].data.text, "tile"))
         cfg->tile = true;
-    token->value.data = (void*)cfg;
+    token->value.data = PTRTOSKINOFFSET(skin_buffer, (void*)cfg);
 #endif
     return 0;
 }
@@ -603,8 +616,8 @@ static int parse_viewportcolour(struct skin_element *element,
         if (!parse_color(curr_screen, param->data.text, &colour->colour))
             return -1;
     }
-    colour->vp = &curr_vp->vp;
-    token->value.data = colour;
+    colour->vp = PTRTOSKINOFFSET(skin_buffer, &curr_vp->vp);
+    token->value.data = PTRTOSKINOFFSET(skin_buffer, colour);
     if (element->line == curr_viewport_element->line)
     {
         if (token->type == SKIN_TOKEN_VIEWPORT_FGCOLOUR)
@@ -643,7 +656,7 @@ static int parse_image_special(struct skin_element *element,
             if (!strcmp(filename, "d"))
                 filename = NULL;
         }
-        wps_data->backdrop = filename;
+        backdrop_filename = filename;
     }
 #endif
 
@@ -694,8 +707,8 @@ static int parse_logical_if(struct skin_element *element,
     struct logical_if *lif = skin_buffer_alloc(sizeof(struct logical_if));
     if (!lif)
         return -1;
-    token->value.data = lif;
-    lif->token = element->params[0].data.code->data;
+    token->value.data = PTRTOSKINOFFSET(skin_buffer, lif);
+    lif->token = PTRTOSKINOFFSET(skin_buffer, element->params[0].data.code->data);
     
     if (!strncmp(op, "=", 1))
         lif->op = IF_EQUALS;
@@ -759,8 +772,8 @@ static int parse_substring_tag(struct skin_element* element,
         ss->length = -1;
     else
         ss->length = element->params[1].data.number;
-    ss->token = element->params[2].data.code->data;
-    token->value.data = ss;
+    ss->token = PTRTOSKINOFFSET(skin_buffer, element->params[2].data.code->data);
+    token->value.data = PTRTOSKINOFFSET(skin_buffer, ss);
     return 0;
 }
 
@@ -780,17 +793,17 @@ static int parse_progressbar_tag(struct skin_element* element,
         return 0; /* nothing to do */
     pb = (struct progressbar*)skin_buffer_alloc(sizeof(struct progressbar));
     
-    token->value.data = pb;
+    token->value.data = PTRTOSKINOFFSET(skin_buffer, pb);
     
     if (!pb)
         return WPS_ERROR_INVALID_PARAM;
-    pb->vp = vp;
+    pb->vp = PTRTOSKINOFFSET(skin_buffer, vp);
     pb->follow_lang_direction = follow_lang_direction > 0;
     pb->nofill = false;
     pb->nobar = false;
-    pb->image = NULL;
-    pb->slider = NULL;
-    pb->backdrop = NULL;
+    pb->image = PTRTOSKINOFFSET(skin_buffer, NULL);
+    pb->slider = PTRTOSKINOFFSET(skin_buffer, NULL);
+    pb->backdrop = PTRTOSKINOFFSET(skin_buffer, NULL);
     pb->invert_fill_direction = false;
     pb->horizontal = true;
     
@@ -869,8 +882,9 @@ static int parse_progressbar_tag(struct skin_element* element,
             {
                 curr_param++;
                 param++;
-                pb->slider = skin_find_item(param->data.text, 
-                                            SKIN_FIND_IMAGE, wps_data);
+                pb->slider = PTRTOSKINOFFSET(skin_buffer,
+                        skin_find_item(param->data.text, 
+                                    SKIN_FIND_IMAGE, wps_data));
             }
             else /* option needs the next param */
                 return -1;
@@ -893,8 +907,9 @@ static int parse_progressbar_tag(struct skin_element* element,
             {
                 curr_param++;
                 param++;
-                pb->backdrop = skin_find_item(param->data.text, 
-                                              SKIN_FIND_IMAGE, wps_data);
+                pb->backdrop = PTRTOSKINOFFSET(skin_buffer, 
+                        skin_find_item(param->data.text, 
+                                        SKIN_FIND_IMAGE, wps_data));
                 
             }
             else /* option needs the next param */
@@ -916,15 +931,16 @@ static int parse_progressbar_tag(struct skin_element* element,
 
     if (image_filename)
     {
-        pb->image = skin_find_item(image_filename, SKIN_FIND_IMAGE, wps_data);
-        if (!pb->image) /* load later */
+        pb->image = PTRTOSKINOFFSET(skin_buffer, 
+                skin_find_item(image_filename, SKIN_FIND_IMAGE, wps_data));
+        if (!SKINOFFSETTOPTR(skin_buffer, pb->image)) /* load later */
         {           
             struct gui_img* img = (struct gui_img*)skin_buffer_alloc(sizeof(struct gui_img));
             if (!img)
                 return WPS_ERROR_INVALID_PARAM;
             /* save a pointer to the filename */
             img->bm.data = (char*)image_filename;
-            img->label = image_filename;
+            img->label = PTRTOSKINOFFSET(skin_buffer, image_filename);
             img->x = 0;
             img->y = 0;
             img->num_subimages = 1;
@@ -932,13 +948,13 @@ static int parse_progressbar_tag(struct skin_element* element,
             img->display = -1;
             img->using_preloaded_icons = false;
             img->buflib_handle = -1;
-            img->vp = &curr_vp->vp;
+            img->vp = PTRTOSKINOFFSET(skin_buffer, &curr_vp->vp);
             struct skin_token_list *item = 
                     (struct skin_token_list *)new_skin_token_list_item(NULL, img);
             if (!item)
                 return WPS_ERROR_INVALID_PARAM;
             add_to_ll_chain(&wps_data->images, item);
-            pb->image = img;
+            pb->image = PTRTOSKINOFFSET(skin_buffer, img);
         }
     }    
         
@@ -996,7 +1012,7 @@ static int parse_albumart_load(struct skin_element* element,
     aa->width = element->params[2].data.number;
     aa->height = element->params[3].data.number;
     
-    aa->vp = &curr_vp->vp;
+    aa->vp = PTRTOSKINOFFSET(skin_buffer, &curr_vp->vp);
     aa->draw_handle = -1;
 
     /* if we got here, we parsed everything ok .. ! */
@@ -1014,7 +1030,7 @@ static int parse_albumart_load(struct skin_element* element,
         aa->x = LCD_WIDTH - (aa->x + aa->width);
 
     aa->state = WPS_ALBUMART_LOAD;
-    wps_data->albumart = aa;
+    wps_data->albumart = PTRTOSKINOFFSET(skin_buffer, aa);
 
     dimensions.width = aa->width;
     dimensions.height = aa->height;
@@ -1080,7 +1096,7 @@ static struct skin_var* find_or_add_var(const char* label,
         ret = (struct skin_var*)skin_buffer_alloc(sizeof(struct skin_var));
         if (!ret)
             return NULL;
-        ret->label = label;
+        ret->label = PTRTOSKINOFFSET(skin_buffer, label);
         ret->value = 1;
         ret->last_changed = 0xffff;
         struct skin_token_list *item = new_skin_token_list_item(NULL, ret);
@@ -1101,7 +1117,7 @@ static int parse_skinvar(  struct skin_element *element,
     switch (token->type)
     {
         case SKIN_TOKEN_VAR_GETVAL:
-            token->value.data = var;
+            token->value.data = PTRTOSKINOFFSET(skin_buffer, var);
             break;
         case SKIN_TOKEN_VAR_SET:
         {
@@ -1110,7 +1126,7 @@ static int parse_skinvar(  struct skin_element *element,
                                             sizeof(struct skin_var_changer));
             if (!data)
                 return WPS_ERROR_INVALID_PARAM;
-            data->var = var;
+            data->var = PTRTOSKINOFFSET(skin_buffer, var);
             data->newval = element->params[2].data.number;
             data->max = 0;
             if (!strcmp(element->params[1].data.text, "set"))
@@ -1126,7 +1142,7 @@ static int parse_skinvar(  struct skin_element *element,
             }
             if (element->params_count > 3)
                 data->max = element->params[3].data.number;
-            token->value.data = data;
+            token->value.data = PTRTOSKINOFFSET(skin_buffer, data);
         }
         break;
         case SKIN_TOKEN_VAR_TIMEOUT:
@@ -1136,12 +1152,12 @@ static int parse_skinvar(  struct skin_element *element,
                                             sizeof(struct skin_var_lastchange));
             if (!data)
                 return WPS_ERROR_INVALID_PARAM;
-            data->var = var;
+            data->var = PTRTOSKINOFFSET(skin_buffer, var);
             data->timeout = 10;
             if (element->params_count > 1)
                 data->timeout = element->params[1].data.number;
             data->timeout *= TIMEOUT_UNIT;
-            token->value.data = data;
+            token->value.data = PTRTOSKINOFFSET(skin_buffer, data);
         }
         break;
         default: /* kill the warning */
@@ -1159,23 +1175,25 @@ static int parse_lasttouch(struct skin_element *element,
             (struct touchregion_lastpress*)skin_buffer_alloc(
                                 sizeof(struct touchregion_lastpress));
     int i;
+    struct touchregion *region = NULL;
     if (!data)
         return WPS_ERROR_INVALID_PARAM;
-    data->region = NULL;
+    
     data->timeout = 10;
     
     for (i=0; i<element->params_count; i++)
     {
         if (element->params[i].type == STRING)
-            data->region = skin_find_item(element->params[i].data.text,
+            region = skin_find_item(element->params[i].data.text,
                                           SKIN_FIND_TOUCHREGION, wps_data);
         else if (element->params[i].type == INTEGER ||
                  element->params[i].type == DECIMAL)
             data->timeout = element->params[i].data.number;
     }
 
+    data->region = PTRTOSKINOFFSET(skin_buffer, region);
     data->timeout *= TIMEOUT_UNIT;
-    token->value.data = data;
+    token->value.data = PTRTOSKINOFFSET(skin_buffer, data);
     return 0;
 }
 
@@ -1239,7 +1257,7 @@ static int touchregion_setup_setting(struct skin_element *element, int param_no,
         switch (settings[j].flags&F_T_MASK)
         {
         case F_T_CUSTOM:
-            setting->value.text = text;
+            setting->value.text = PTRTOSKINOFFSET(skin_buffer, text);
             break;                              
         case F_T_INT:
         case F_T_UINT:
@@ -1301,7 +1319,7 @@ static int parse_touchregion(struct skin_element *element,
     
     if (element->params[0].type == STRING)
     {
-        region->label = element->params[0].data.text;
+        region->label = PTRTOSKINOFFSET(skin_buffer, element->params[0].data.text);
         p = 1;
         /* "[SI]III[SI]|SS" is the param list. There MUST be 4 numbers
          * followed by at least one string. Verify that here */
@@ -1311,7 +1329,7 @@ static int parse_touchregion(struct skin_element *element,
     }
     else
     {
-        region->label = NULL;
+        region->label = PTRTOSKINOFFSET(skin_buffer, NULL);
         p = 0;
     }
     
@@ -1319,7 +1337,7 @@ static int parse_touchregion(struct skin_element *element,
     region->y = element->params[p++].data.number;
     region->width = element->params[p++].data.number;
     region->height = element->params[p++].data.number;
-    region->wvp = curr_vp;
+    region->wvp = PTRTOSKINOFFSET(skin_buffer, curr_vp);
     region->armed = false;
     region->reverse_bar = false;
     region->value = 0;
@@ -1439,21 +1457,23 @@ void skin_data_free_buflib_allocs(struct wps_data *wps_data)
     (void)wps_data;
 #ifdef HAVE_LCD_BITMAP
 #ifndef __PCTOOL__
-    struct skin_token_list *list = wps_data->images;
+    struct skin_token_list *list = SKINOFFSETTOPTR(skin_buffer, wps_data->images);
+    int *font_ids = SKINOFFSETTOPTR(skin_buffer, wps_data->font_ids);
     while (list)
     {
-        struct gui_img *img = (struct gui_img*)list->token->value.data;
+        struct wps_token *token = SKINOFFSETTOPTR(skin_buffer, list->token);
+        struct gui_img *img = (struct gui_img*)SKINOFFSETTOPTR(skin_buffer, token->value.data);
         if (img->buflib_handle > 0)
             core_free(img->buflib_handle);
-        list = list->next;
+        list = SKINOFFSETTOPTR(skin_buffer, list->next);
     }
-    wps_data->images = NULL;
-    if (wps_data->font_ids != NULL)
+    wps_data->images = PTRTOSKINOFFSET(skin_buffer, NULL);
+    if (font_ids != NULL)
     {
         while (wps_data->font_count > 0)
-            font_unload(wps_data->font_ids[--wps_data->font_count]);
+            font_unload(font_ids[--wps_data->font_count]);
     }
-    wps_data->font_ids = NULL;
+    wps_data->font_ids = PTRTOSKINOFFSET(skin_buffer, NULL);
 #endif
 #endif
 }
@@ -1467,22 +1487,22 @@ static void skin_data_reset(struct wps_data *wps_data)
 {
     skin_data_free_buflib_allocs(wps_data);
 #ifdef HAVE_LCD_BITMAP
-    wps_data->images = NULL;
+    wps_data->images = PTRTOSKINOFFSET(skin_buffer, NULL);
 #endif
-    wps_data->tree = NULL;
+    wps_data->tree = PTRTOSKINOFFSET(skin_buffer, NULL);
 #if LCD_DEPTH > 1 || defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1
     if (wps_data->backdrop_id >= 0)
         skin_backdrop_unload(wps_data->backdrop_id);
-    wps_data->backdrop = NULL;
+    backdrop_filename = NULL;
 #endif
 #ifdef HAVE_TOUCHSCREEN
-    wps_data->touchregions = NULL;
+    wps_data->touchregions = PTRTOSKINOFFSET(skin_buffer, NULL);
 #endif
 #ifdef HAVE_SKIN_VARIABLES
-    wps_data->skinvars = NULL;
+    wps_data->skinvars = PTRTOSKINOFFSET(skin_buffer, NULL);
 #endif
 #ifdef HAVE_ALBUMART
-    wps_data->albumart = NULL;
+    wps_data->albumart = PTRTOSKINOFFSET(skin_buffer, NULL);
     if (wps_data->playback_aa_slot >= 0)
     {
         playback_release_aa_slot(wps_data->playback_aa_slot);
@@ -1596,16 +1616,17 @@ static bool load_skin_bitmaps(struct wps_data *wps_data, char *bmpdir)
     bool retval = true; /* return false if a single image failed to load */
     
     /* regular images */
-    list = wps_data->images;
+    list = SKINOFFSETTOPTR(skin_buffer, wps_data->images);
     while (list)
     {
-        struct gui_img *img = (struct gui_img*)list->token->value.data;
+        struct wps_token *token = SKINOFFSETTOPTR(skin_buffer, list->token);
+        struct gui_img *img = (struct gui_img*)SKINOFFSETTOPTR(skin_buffer, token->value.data);
         if (img->bm.data)
         {
             if (img->using_preloaded_icons)
             {
                 img->loaded = true;
-                list->token->type = SKIN_TOKEN_IMAGE_DISPLAY_LISTICON;
+                token->type = SKIN_TOKEN_IMAGE_DISPLAY_LISTICON;
             }
             else
             {
@@ -1617,11 +1638,11 @@ static bool load_skin_bitmaps(struct wps_data *wps_data, char *bmpdir)
                     retval = false;
             }
         }
-        list = list->next;
+        list = SKINOFFSETTOPTR(skin_buffer, list->next);
     }
 
 #if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1))
-    wps_data->backdrop_id = skin_backdrop_assign(wps_data->backdrop, bmpdir, curr_screen);
+    wps_data->backdrop_id = skin_backdrop_assign(backdrop_filename, bmpdir, curr_screen);
 #endif /* has backdrop support */
     return retval;
 }
@@ -1635,7 +1656,7 @@ static bool skin_load_fonts(struct wps_data *data)
     struct skin_element *vp_list;
     int font_id;
     /* walk though each viewport and assign its font */
-    for(vp_list = data->tree; vp_list; vp_list = vp_list->next)
+    for(vp_list = SKINOFFSETTOPTR(skin_buffer, data->tree); vp_list; vp_list = vp_list->next)
     {
         /* first, find the viewports that have a non-sys/ui-font font */
         struct skin_viewport *skin_vp =
@@ -1695,19 +1716,20 @@ static bool skin_load_fonts(struct wps_data *data)
         /* finally, assign the font_id to the viewport */
         vp->font = font->id;
     }
-    data->font_ids = skin_buffer_alloc(font_count * sizeof(int));
-    if (!success || data->font_ids == NULL)
+    int *font_ids = skin_buffer_alloc(font_count * sizeof(int));
+    if (!success || font_ids == NULL)
     {
         while (font_count > 0)
         {
             if(id_array[--font_count] != -1)
                 font_unload(id_array[font_count]);
         }
-        data->font_ids = NULL;
+        data->font_ids = PTRTOSKINOFFSET(skin_buffer, NULL);
         return false;
     }
-    memcpy(data->font_ids, id_array, sizeof(int)*font_count);
+    memcpy(font_ids, id_array, sizeof(int)*font_count);
     data->font_count = font_count;
+    data->font_ids = PTRTOSKINOFFSET(skin_buffer, font_ids);
     return success;
 }
 
@@ -1722,7 +1744,7 @@ static int convert_viewport(struct wps_data *data, struct skin_element* element)
         return CALLBACK_ERROR;
         
     skin_vp->hidden_flags = 0;
-    skin_vp->label = NULL;
+    skin_vp->label = PTRTOSKINOFFSET(skin_buffer, NULL);
     skin_vp->is_infovp = false;
     skin_vp->parsed_fontid = 1;
     element->data = skin_vp;
@@ -1745,8 +1767,8 @@ static int convert_viewport(struct wps_data *data, struct skin_element* element)
     struct skin_tag_parameter *param = element->params;
     if (element->params_count == 0) /* default viewport */
     {
-        if (!data->tree) /* first viewport in the skin */
-            data->tree = element;
+        if (!SKINOFFSETTOPTR(skin_buffer, data->tree)) /* first viewport in the skin */
+            data->tree = PTRTOSKINOFFSET(skin_buffer, element);
         skin_vp->label = VP_DEFAULT_LABEL;
         return CALLBACK_OK;
     }
@@ -1764,13 +1786,13 @@ static int convert_viewport(struct wps_data *data, struct skin_element* element)
             else
             {
                 skin_vp->hidden_flags = VP_NEVER_VISIBLE;
-                skin_vp->label = param->data.text;
+                skin_vp->label = PTRTOSKINOFFSET(skin_buffer, param->data.text);
             }
         }
         else
         {
                 skin_vp->hidden_flags = VP_DRAW_HIDEABLE|VP_DRAW_HIDDEN;
-                skin_vp->label = param->data.text;
+                skin_vp->label = PTRTOSKINOFFSET(skin_buffer, param->data.text);
         }
         param++;
     }
@@ -1937,7 +1959,7 @@ static int skin_element_callback(struct skin_element* element, void* data)
                     break;
                 case SKIN_TOKEN_VIEWPORT_ENABLE:
                 case SKIN_TOKEN_UIVIEWPORT_ENABLE:
-                    token->value.data = element->params[0].data.text;
+                    token->value.data = PTRTOSKINOFFSET(skin_buffer, element->params[0].data.text);
                     break;
                 case SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY:
                     function = parse_image_display;
@@ -1960,8 +1982,11 @@ static int skin_element_callback(struct skin_element* element, void* data)
 #endif
 #ifdef HAVE_ALBUMART
                 case SKIN_TOKEN_ALBUMART_DISPLAY:
-                    if (wps_data->albumart)
-                        wps_data->albumart->vp = &curr_vp->vp;
+                    if (SKINOFFSETTOPTR(skin_buffer, wps_data->albumart))
+                    {
+                        struct skin_albumart *aa = SKINOFFSETTOPTR(skin_buffer, wps_data->albumart);
+                        aa->vp = PTRTOSKINOFFSET(skin_buffer, &curr_vp->vp);
+                    }
                     break;
                 case SKIN_TOKEN_ALBUMART_LOAD:
                     function = parse_albumart_load;
@@ -2017,7 +2042,7 @@ static int skin_element_callback(struct skin_element* element, void* data)
             struct conditional *conditional = 
                 (struct conditional *)skin_buffer_alloc(sizeof(struct conditional));
             conditional->last_value = -1;
-            conditional->token = element->data;
+            conditional->token = PTRTOSKINOFFSET(skin_buffer, element->data);
             element->data = conditional;
             if (!check_feature_tag(element->tag->type))
             {
@@ -2047,11 +2072,12 @@ bool skin_data_load(enum screen_type screen, struct wps_data *wps_data,
     struct mp3entry *curtrack;
     long offset;
     struct skin_albumart old_aa = {.state = WPS_ALBUMART_NONE};
-    if (wps_data->albumart)
+    struct skin_albumart *aa = SKINOFFSETTOPTR(skin_buffer, wps_data->albumart);
+    if (aa)
     {
-        old_aa.state = wps_data->albumart->state;
-        old_aa.height = wps_data->albumart->height;
-        old_aa.width = wps_data->albumart->width;
+        old_aa.state = aa->state;
+        old_aa.height = aa->height;
+        old_aa.width = aa->width;
     }
 #endif
 #ifdef HAVE_LCD_BITMAP
@@ -2112,15 +2138,16 @@ bool skin_data_load(enum screen_type screen, struct wps_data *wps_data,
         wps_buffer = (char*)buf;
     }
 #if LCD_DEPTH > 1 || defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1
-    wps_data->backdrop = "-";
+    backdrop_filename = "-";
     wps_data->backdrop_id = -1;
 #endif
     /* parse the skin source */
 #ifndef APPLICATION
     skin_buffer_save_position();
 #endif
-    wps_data->tree = skin_parse(wps_buffer, skin_element_callback, wps_data);
-    if (!wps_data->tree) {
+    struct skin_element *tree = skin_parse(wps_buffer, skin_element_callback, wps_data);
+    wps_data->tree = PTRTOSKINOFFSET(skin_buffer, tree);
+    if (!SKINOFFSETTOPTR(skin_buffer, wps_data->tree)) {
         skin_data_reset(wps_data);
 #ifndef APPLICATION
         skin_buffer_restore_position();
@@ -2155,7 +2182,7 @@ bool skin_data_load(enum screen_type screen, struct wps_data *wps_data,
     status = audio_status();
     if (status & AUDIO_STATUS_PLAY)
     {
-        struct skin_albumart *aa = wps_data->albumart;
+        struct skin_albumart *aa = SKINOFFSETTOPTR(skin_buffer, wps_data->albumart);
         if (aa && ((aa->state && !old_aa.state) ||
             (aa->state &&
             (((old_aa.height != aa->height) ||
diff --git a/apps/gui/skin_engine/skin_render.c b/apps/gui/skin_engine/skin_render.c
index 369bd46..7202de5 100644
--- a/apps/gui/skin_engine/skin_render.c
+++ b/apps/gui/skin_engine/skin_render.c
@@ -99,14 +99,16 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
 #if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1))
         case SKIN_TOKEN_VIEWPORT_FGCOLOUR:
         {
-            struct viewport_colour *col = token->value.data;
-            col->vp->fg_pattern = col->colour;
+            struct viewport_colour *col = SKINOFFSETTOPTR(skin_buffer, token->value.data);
+            struct viewport *vp = SKINOFFSETTOPTR(skin_buffer, col->vp);
+            vp->fg_pattern = col->colour;
         }
         break;
         case SKIN_TOKEN_VIEWPORT_BGCOLOUR:
         {
-            struct viewport_colour *col = token->value.data;
-            col->vp->bg_pattern = col->colour;
+            struct viewport_colour *col = SKINOFFSETTOPTR(skin_buffer, token->value.data);
+            struct viewport *vp = SKINOFFSETTOPTR(skin_buffer, col->vp);
+            vp->bg_pattern = col->colour;
         }
         break;
         case SKIN_TOKEN_VIEWPORT_TEXTSTYLE:
@@ -116,7 +118,7 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
 #ifdef HAVE_LCD_COLOR
         case SKIN_TOKEN_VIEWPORT_GRADIENT_SETUP:
         {
-            struct gradient_config *cfg = token->value.data;
+            struct gradient_config *cfg = SKINOFFSETTOPTR(skin_buffer, token->value.data);
             vp->lss_pattern = cfg->start;
             vp->lse_pattern = cfg->end;
             vp->lst_pattern = cfg->text;
@@ -125,14 +127,18 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
 #endif
         case SKIN_TOKEN_VIEWPORT_ENABLE:
         {
-            char *label = token->value.data;
+            char *label = SKINOFFSETTOPTR(skin_buffer, token->value.data);
             char temp = VP_DRAW_HIDEABLE;
-            struct skin_element *viewport = gwps->data->tree;
+            struct skin_element *viewport = SKINOFFSETTOPTR(skin_buffer, gwps->data->tree);
             while (viewport)
             {
                 struct skin_viewport *skinvp = (struct skin_viewport*)viewport->data;
-                if (skinvp->label && !skinvp->is_infovp &&
-                    !strcmp(skinvp->label, label))
+                
+                char *vplabel = SKINOFFSETTOPTR(skin_buffer, skinvp->label);
+                if (skinvp->label == VP_DEFAULT_LABEL)
+                    vplabel = VP_DEFAULT_LABEL_STRING;
+                if (vplabel && !skinvp->is_infovp &&
+                    !strcmp(vplabel, label))
                 {
                     if (skinvp->hidden_flags&VP_DRAW_HIDDEN)
                     {
@@ -148,11 +154,11 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
         case SKIN_TOKEN_LIST_ITEM_CFG:
             if (do_refresh)
                 skinlist_set_cfg(gwps->display->screen_type, 
-                                    token->value.data);
+                                    SKINOFFSETTOPTR(skin_buffer, token->value.data));
             break;
         case SKIN_TOKEN_UIVIEWPORT_ENABLE:
             sb_set_info_vp(gwps->display->screen_type, 
-                           token->value.data);
+                           SKINOFFSETTOPTR(skin_buffer, token->value.data));
             break;
         case SKIN_TOKEN_PEAKMETER:
             data->peak_meter_enabled = true;
@@ -173,7 +179,7 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
         case SKIN_TOKEN_TUNER_RSSI_BAR:
         case SKIN_TOKEN_LIST_SCROLLBAR:
         {
-            struct progressbar *bar = (struct progressbar*)token->value.data;
+            struct progressbar *bar = (struct progressbar*)SKINOFFSETTOPTR(skin_buffer, token->value.data);
             if (do_refresh)
                 draw_progressbar(gwps, info->line_number, bar);
         }
@@ -183,12 +189,12 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
         case SKIN_TOKEN_IMAGE_DISPLAY_LISTICON:
         case SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY:
         {
-            struct image_display *id = token->value.data;
-            const char* label = id->label;
+            struct image_display *id = SKINOFFSETTOPTR(skin_buffer, token->value.data);
+            const char* label = SKINOFFSETTOPTR(skin_buffer, id->label);
             struct gui_img *img = skin_find_item(label,SKIN_FIND_IMAGE, data);
             if (img && img->loaded)
             {
-                if (id->token == NULL)
+                if (SKINOFFSETTOPTR(skin_buffer, id->token) == NULL)
                 {
                     img->display = id->subimage;
                 }
@@ -197,8 +203,8 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
                     char buf[16];
                     const char *out;
                     int a = img->num_subimages;
-                    out = get_token_value(gwps, id->token, info->offset, 
-                                          buf, sizeof(buf), &a);
+                    out = get_token_value(gwps, SKINOFFSETTOPTR(skin_buffer, id->token),
+                            info->offset, buf, sizeof(buf), &a);
 
                     /* NOTE: get_token_value() returns values starting at 1! */
                     if (a == -1)
@@ -224,29 +230,32 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
         }
 #ifdef HAVE_ALBUMART
         case SKIN_TOKEN_ALBUMART_DISPLAY:
+        {
+            struct skin_albumart *aa = SKINOFFSETTOPTR(skin_buffer, data->albumart);
             /* now draw the AA */
-            if (do_refresh && data->albumart)
+            if (do_refresh && aa)
             {
                 int handle = playback_current_aa_hid(data->playback_aa_slot);
 #if CONFIG_TUNER
                 if (in_radio_screen() || (get_radio_status() != FMRADIO_OFF))
                 {
-                    struct dim dim = {data->albumart->width, data->albumart->height};
+                    struct dim dim = {aa->width, aa->height};
                     handle = radio_get_art_hid(&dim);
                 }
 #endif
-                data->albumart->draw_handle = handle;
+                aa->draw_handle = handle;
             }
             break;
+        }
 #endif
         case SKIN_TOKEN_DRAW_INBUILTBAR:
             gui_statusbar_draw(&(statusbars.statusbars[gwps->display->screen_type]),
                                info->refresh_type == SKIN_REFRESH_ALL,
-                               token->value.data);
+                               SKINOFFSETTOPTR(skin_buffer, token->value.data));
             break;
         case SKIN_TOKEN_VIEWPORT_CUSTOMLIST:
             if (do_refresh)
-                skin_render_playlistviewer(token->value.data, gwps,
+                skin_render_playlistviewer(SKINOFFSETTOPTR(skin_buffer, token->value.data), gwps,
                                            info->skin_vp, info->refresh_type);
             break;
         
@@ -255,23 +264,24 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
         case SKIN_TOKEN_VAR_SET:
             if (do_refresh)
             {
-                struct skin_var_changer *data = token->value.data;
+                struct skin_var_changer *data = SKINOFFSETTOPTR(skin_buffer, token->value.data);
+                struct skin_var *var = SKINOFFSETTOPTR(skin_buffer, data->var);
                 if (data->direct)
-                    data->var->value = data->newval;
+                    var->value = data->newval;
                 else
                 {
-                    data->var->value += data->newval;
+                    var->value += data->newval;
                     if (data->max)
                     {
-                        if (data->var->value > data->max)
-                            data->var->value = 1;
-                        else if (data->var->value < 1)
-                            data->var->value = data->max;
+                        if (var->value > data->max)
+                            var->value = 1;
+                        else if (var->value < 1)
+                            var->value = data->max;
                     }
                 }
-                if (data->var->value < 1)
-                    data->var->value = 1;
-                data->var->last_changed = current_tick;
+                if (var->value < 1)
+                    var->value = 1;
+                var->last_changed = current_tick;
             }
             break;
 #endif
@@ -330,8 +340,8 @@ static void do_tags_in_hidden_conditional(struct skin_element* branch,
             /* clear all pictures in the conditional and nested ones */
             if (token->type == SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY)
             {
-                struct image_display *id = token->value.data;
-                struct gui_img *img = skin_find_item(id->label, 
+                struct image_display *id = SKINOFFSETTOPTR(skin_buffer, token->value.data);
+                struct gui_img *img = skin_find_item(SKINOFFSETTOPTR(skin_buffer, id->label), 
                                                      SKIN_FIND_IMAGE, data);
                 clear_image_pos(gwps, img);
             }
@@ -341,14 +351,18 @@ static void do_tags_in_hidden_conditional(struct skin_element* branch,
             }
             else if (token->type == SKIN_TOKEN_VIEWPORT_ENABLE)
             {
-                char *label = token->value.data;
+                char *label = SKINOFFSETTOPTR(skin_buffer, token->value.data);
                 struct skin_element *viewport;
-                for (viewport = data->tree;
+                for (viewport = SKINOFFSETTOPTR(skin_buffer, data->tree);
                      viewport;
                      viewport = viewport->next)
                 {
                     struct skin_viewport *skin_viewport = (struct skin_viewport*)viewport->data;
-                    if (skin_viewport->label && strcmp(skin_viewport->label, label))
+                    
+                    char *vplabel = SKINOFFSETTOPTR(skin_buffer, skin_viewport->label);
+                    if (skin_viewport->label == VP_DEFAULT_LABEL)
+                        vplabel = VP_DEFAULT_LABEL_STRING;
+                    if (vplabel && strcmp(vplabel, label))
                         continue;
                     if (skin_viewport->hidden_flags&VP_NEVER_VISIBLE)
                     {
@@ -648,12 +662,13 @@ void skin_render_viewport(struct skin_element* viewport, struct gui_wps *gwps,
     bool needs_update;
 #ifdef HAVE_LCD_BITMAP
     /* Set images to not to be displayed */
-    struct skin_token_list *imglist = gwps->data->images;
+    struct skin_token_list *imglist = SKINOFFSETTOPTR(skin_buffer, gwps->data->images);
     while (imglist)
     {
-        struct gui_img *img = (struct gui_img *)imglist->token->value.data;
+        struct wps_token *token = SKINOFFSETTOPTR(skin_buffer, imglist->token);
+        struct gui_img *img = (struct gui_img *)SKINOFFSETTOPTR(skin_buffer, token->value.data);
         img->display = -1;
-        imglist = imglist->next;
+        imglist = SKINOFFSETTOPTR(skin_buffer, imglist->next);
     }
 
     /* fix font ID's */
@@ -730,6 +745,7 @@ void skin_render(struct gui_wps *gwps, unsigned refresh_mode)
     
     struct skin_element* viewport;
     struct skin_viewport* skin_viewport;
+    char *label;
     
     int old_refresh_mode = refresh_mode;
     
@@ -741,13 +757,16 @@ void skin_render(struct gui_wps *gwps, unsigned refresh_mode)
             data->wps_progress_pat[i] = display->get_locked_pattern();
     }
 #endif
-    viewport = data->tree;
+    viewport = SKINOFFSETTOPTR(skin_buffer, data->tree);
     skin_viewport = (struct skin_viewport *)viewport->data;
-    if (skin_viewport->label && viewport->next &&
-        !strcmp(skin_viewport->label,VP_DEFAULT_LABEL))
+    label = SKINOFFSETTOPTR(skin_buffer, skin_viewport->label);
+    if (skin_viewport->label == VP_DEFAULT_LABEL)
+        label = VP_DEFAULT_LABEL_STRING;
+    if (label && viewport->next &&
+        !strcmp(label,VP_DEFAULT_LABEL_STRING))
         refresh_mode = 0;
     
-    for (viewport = data->tree;
+    for (viewport = SKINOFFSETTOPTR(skin_buffer, data->tree);
          viewport;
          viewport = viewport->next)
     {
@@ -826,7 +845,7 @@ void skin_render_playlistviewer(struct playlistviewer* viewer,
     struct align_pos * align = &info.align;
     bool needs_update;
     int cur_pos, start_item, max;
-    int nb_lines = viewport_get_nb_lines(viewer->vp);
+    int nb_lines = viewport_get_nb_lines(SKINOFFSETTOPTR(skin_buffer, viewer->vp));
 #if CONFIG_TUNER
     if (get_current_activity() == ACTIVITY_FM)
     {
@@ -848,7 +867,7 @@ void skin_render_playlistviewer(struct playlistviewer* viewer,
     if (max-start_item > nb_lines)
         max = start_item + nb_lines;
     
-    line = viewer->line;
+    line = SKINOFFSETTOPTR(skin_buffer, viewer->line);
     while (start_item < max)
     {
         linebuf[0] = '\0';
diff --git a/apps/gui/skin_engine/skin_tokens.c b/apps/gui/skin_engine/skin_tokens.c
index 7c43045..75e0a9e 100644
--- a/apps/gui/skin_engine/skin_tokens.c
+++ b/apps/gui/skin_engine/skin_tokens.c
@@ -732,9 +732,9 @@ static const char* NOINLINE get_lif_token_value(struct gui_wps *gwps,
 {
     int a = lif->num_options;
     int b;
-    const char* out_text = get_token_value(gwps, lif->token, offset,
-                                           buf, buf_size, &a);            
-    if (a == -1 && lif->token->type != SKIN_TOKEN_VOLUME)
+    struct wps_token *liftoken = SKINOFFSETTOPTR(skin_buffer, lif->token);
+    const char* out_text = get_token_value(gwps, liftoken, offset, buf, buf_size, &a);            
+    if (a == -1 && liftoken->type != SKIN_TOKEN_VOLUME)
         a = (out_text && *out_text) ? 1 : 0;
     switch (lif->operand.type)
     {
@@ -756,7 +756,7 @@ static const char* NOINLINE get_lif_token_value(struct gui_wps *gwps,
             b = lif->num_options;
             outb = get_token_value(gwps, token, offset, temp_buf,
                                    sizeof(temp_buf), &b);            
-            if (b == -1 && lif->token->type != SKIN_TOKEN_VOLUME)
+            if (b == -1 && liftoken->type != SKIN_TOKEN_VOLUME)
             {
                 if (!out_text || !outb)
                     return (lif->op == IF_EQUALS) ? NULL : "neq";
@@ -865,14 +865,15 @@ const char *get_token_value(struct gui_wps *gwps,
     {
         case SKIN_TOKEN_LOGICAL_IF:
         {
-            struct logical_if *lif = token->value.data;
+            struct logical_if *lif = SKINOFFSETTOPTR(skin_buffer, token->value.data);
             return get_lif_token_value(gwps, lif, offset, buf, buf_size);
         }
         break;
         case SKIN_TOKEN_SUBSTRING:
         {
-            struct substring *ss = token->value.data;
-            const char *token_val = get_token_value(gwps, ss->token, offset,
+            struct substring *ss = SKINOFFSETTOPTR(skin_buffer, token->value.data);
+            const char *token_val = get_token_value(gwps, 
+                            SKINOFFSETTOPTR(skin_buffer, ss->token), offset,
                                                     buf, buf_size, intval);
             if (token_val)
             {
@@ -909,7 +910,7 @@ const char *get_token_value(struct gui_wps *gwps,
             return &(token->value.c);
 
         case SKIN_TOKEN_STRING:
-            return (char*)token->value.data;
+            return (char*)SKINOFFSETTOPTR(skin_buffer, token->value.data);
             
         case SKIN_TOKEN_TRANSLATEDSTRING:
             return (char*)P2STR(ID2P(token->value.i));
@@ -929,7 +930,7 @@ const char *get_token_value(struct gui_wps *gwps,
             return buf;
         case SKIN_TOKEN_LIST_ITEM_TEXT:
         {
-            struct listitem *li = (struct listitem *)token->value.data;
+            struct listitem *li = (struct listitem *)SKINOFFSETTOPTR(skin_buffer, token->value.data);
             return skinlist_get_item_text(li->offset, li->wrap, buf, buf_size);
         }
         case SKIN_TOKEN_LIST_ITEM_NUMBER:
@@ -941,7 +942,7 @@ const char *get_token_value(struct gui_wps *gwps,
             return skinlist_is_selected_item()?"s":"";
         case SKIN_TOKEN_LIST_ITEM_ICON:
         {
-            struct listitem *li = (struct listitem *)token->value.data;
+            struct listitem *li = (struct listitem *)SKINOFFSETTOPTR(skin_buffer, token->value.data);
             int icon = skinlist_get_item_icon(li->offset, li->wrap);
             if (intval)
                 *intval = icon;
@@ -997,14 +998,15 @@ const char *get_token_value(struct gui_wps *gwps,
             return buf;
 #ifdef HAVE_ALBUMART
         case SKIN_TOKEN_ALBUMART_FOUND:
-            if (data->albumart)
+            if (SKINOFFSETTOPTR(skin_buffer, data->albumart))
             {
                 int handle = -1;
                 handle = playback_current_aa_hid(data->playback_aa_slot);
 #if CONFIG_TUNER
                 if (in_radio_screen() || (get_radio_status() != FMRADIO_OFF))
                 {
-                    struct dim dim = {data->albumart->width, data->albumart->height};
+                    struct skin_albumart *aa = SKINOFFSETTOPTR(skin_buffer, data->albumart);
+                    struct dim dim = {aa->width, aa->height};
                     handle = radio_get_art_hid(&dim);
                 }
 #endif
@@ -1473,9 +1475,10 @@ const char *get_token_value(struct gui_wps *gwps,
             {
 #ifdef HAVE_TOUCHSCREEN
             unsigned int last_touch = touchscreen_last_touch();
-            struct touchregion_lastpress *data = token->value.data;
-            if (data->region)
-                last_touch = data->region->last_press;
+            struct touchregion_lastpress *data = SKINOFFSETTOPTR(skin_buffer, token->value.data);
+            struct touchregion *region = SKINOFFSETTOPTR(skin_buffer, data->region);
+            if (region)
+                last_touch = region->last_press;
 
             if (last_touch != 0xffff &&
                 TIME_BEFORE(current_tick, data->timeout + last_touch))
@@ -1805,7 +1808,7 @@ const char *get_token_value(struct gui_wps *gwps,
 #ifdef HAVE_SKIN_VARIABLES
         case SKIN_TOKEN_VAR_GETVAL:
         {
-            struct skin_var* var = token->value.data;
+            struct skin_var* var = SKINOFFSETTOPTR(skin_buffer, token->value.data);
             if (intval)
                 *intval = var->value;
             snprintf(buf, buf_size, "%d", var->value);
@@ -1814,8 +1817,9 @@ const char *get_token_value(struct gui_wps *gwps,
         break;
         case SKIN_TOKEN_VAR_TIMEOUT:
             {
-            struct skin_var_lastchange *data = token->value.data;
-            unsigned int last_change = data->var->last_changed;
+            struct skin_var_lastchange *data = SKINOFFSETTOPTR(skin_buffer, token->value.data);
+            struct skin_var* var = SKINOFFSETTOPTR(skin_buffer, data->var);
+            unsigned int last_change = var->last_changed;
 
             if (last_change != 0xffff &&
                 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 bfca7b7..0000000
--- a/apps/gui/skin_engine/skin_tokens.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2007 Nicolas Pennequin
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ****************************************************************************/
- 
-#ifndef _SKIN_TOKENS_H_
-#define _SKIN_TOKENS_H_
-
-#include <stdbool.h>
-#include "tag_table.h"
-
-struct wps_token {
-    union {
-        char c;
-        unsigned short i;
-        long l;
-        void* data;
-    } value;
-
-    enum skin_token_type type; /* enough to store the token type */
-    /* Whether the tag (e.g. track name or the album) refers the
-       current or the next song (false=current, true=next) */
-    bool next;
-};
-
-struct skin_token_list {
-    struct wps_token *token;
-    struct skin_token_list *next;
-};
-
-char* get_dir(char* buf, int buf_size, const char* path, int level);
-
-#endif
diff --git a/apps/gui/skin_engine/skin_touchsupport.c b/apps/gui/skin_engine/skin_touchsupport.c
index 64c7979..3714f8c 100644
--- a/apps/gui/skin_engine/skin_touchsupport.c
+++ b/apps/gui/skin_engine/skin_touchsupport.c
@@ -37,11 +37,12 @@
 /** Disarms all touchregions. */
 void skin_disarm_touchregions(struct wps_data *data)
 {
-    struct skin_token_list *regions = data->touchregions;
+    struct skin_token_list *regions = SKINOFFSETTOPTR(skin_buffer, data->touchregions);
     while (regions)
     {
-        ((struct touchregion *)regions->token->value.data)->armed = false;
-        regions = regions->next;
+        struct wps_token *token = SKINOFFSETTOPTR(skin_buffer, regions->token);
+        ((struct touchregion *)token->value.data)->armed = false;
+        regions = SKINOFFSETTOPTR(skin_buffer, regions->next);
     }
 }
 
@@ -56,35 +57,38 @@ int skin_get_touchaction(struct wps_data *data, int* edge_offset,
     short x,y;
     short vx, vy;
     int type = action_get_touchscreen_press(&x, &y);
+    struct skin_viewport *wvp;
     struct touchregion *r, *temp = NULL;
     bool repeated = (type == BUTTON_REPEAT);
     bool released = (type == BUTTON_REL);
     bool pressed = (type == BUTTON_TOUCHSCREEN);
-    struct skin_token_list *regions = data->touchregions;
+    struct skin_token_list *regions = SKINOFFSETTOPTR(skin_buffer, data->touchregions);
     bool needs_repeat;
 
     while (regions)
     {
-        r = (struct touchregion *)regions->token->value.data;
+        struct wps_token *token = SKINOFFSETTOPTR(skin_buffer, regions->token);
+        r = (struct touchregion *)token->value.data;
+        wvp = SKINOFFSETTOPTR(skin_buffer, r->wvp);
         /* make sure this region's viewport is visible */
-        if (r->wvp->hidden_flags&VP_DRAW_HIDDEN)
+        if (wvp->hidden_flags&VP_DRAW_HIDDEN)
         {
-            regions = regions->next;
+            regions = SKINOFFSETTOPTR(skin_buffer, regions->next);
             continue;
         }
         if (data->touchscreen_locked && 
             (r->action != ACTION_TOUCH_SOFTLOCK && !r->allow_while_locked))
         {
-            regions = regions->next;
+            regions = SKINOFFSETTOPTR(skin_buffer, regions->next);
             continue;
         }
         needs_repeat = r->press_length != PRESS;
         /* check if it's inside this viewport */
-        if (viewport_point_within_vp(&(r->wvp->vp), x, y))
+        if (viewport_point_within_vp(&(wvp->vp), x, y))
         {   /* reposition the touch inside the viewport since touchregions
              * are relative to a preceding viewport */
-            vx = x - r->wvp->vp.x;
-            vy = y - r->wvp->vp.y;
+            vx = x - wvp->vp.x;
+            vy = y - wvp->vp.y;
             /* now see if the point is inside this region */
             if (vx >= r->x && vx < r->x+r->width &&
                 vy >= r->y && vy < r->y+r->height)
@@ -127,7 +131,7 @@ int skin_get_touchaction(struct wps_data *data, int* edge_offset,
                 }
             }
         }
-        regions = regions->next;
+        regions = SKINOFFSETTOPTR(skin_buffer, regions->next);
     }
 
     /* On release, all regions are disarmed. */
@@ -214,7 +218,7 @@ int skin_get_touchaction(struct wps_data *data, int* edge_offset,
                 {
                     case F_T_CUSTOM:
                         s->custom_setting
-                            ->load_from_cfg(s->setting, data->value.text);
+                            ->load_from_cfg(s->setting, SKINOFFSETTOPTR(skin_buffer, data->value.text));
                         break;                          
                     case F_T_INT:
                     case F_T_UINT:
diff --git a/apps/gui/skin_engine/wps_internals.h b/apps/gui/skin_engine/wps_internals.h
index ed09ad0..1096b26 100644
--- a/apps/gui/skin_engine/wps_internals.h
+++ b/apps/gui/skin_engine/wps_internals.h
@@ -25,6 +25,22 @@
 #ifndef _WPS_ENGINE_INTERNALS_
 #define _WPS_ENGINE_INTERNALS_
 
+#include "tag_table.h"
+#include "skin_parser.h"
+
+/* Use this type and macro to convert a pointer from the
+ * skin buffer to a useable pointer */
+typedef long skinoffset;
+#define SKINOFFSETTOPTR(base, offset) ((offset) < 0 ? NULL : ((void*)&base[offset]))
+#define PTRTOSKINOFFSET(base, pointer) ((pointer) ? ((void*)pointer-(void*)base) : -1)
+/* Use this macro when declaring a variable to self-document the code.
+ * type is the actual type being pointed to (i.e OFFSETTYPE(char*) foo )
+ * 
+ * WARNING: Don't use the PTRTOSKINOFFSET() around a function call as it wont
+ * do what you expect.
+ */
+#define OFFSETTYPE(type) skinoffset
+extern char skin_buffer[];
 
 /* Timeout unit expressed in HZ. In WPS, all timeouts are given in seconds
    (possibly with a decimal fraction) but stored as integer values.
@@ -33,9 +49,6 @@
 #define TIMEOUT_UNIT (HZ/10) /* I.e. 0.1 sec */
 #define DEFAULT_SUBLINE_TIME_MULTIPLIER 20 /* In TIMEOUT_UNIT's */
 
-#include "skin_tokens.h"
-#include "tag_table.h"
-#include "skin_parser.h"
 
 
 /* TODO: sort this mess out */
@@ -44,41 +57,43 @@
 #include "statusbar.h"
 #include "metadata.h"
 
-/* alignments */
-#define WPS_ALIGN_RIGHT 32
-#define WPS_ALIGN_CENTER 64
-#define WPS_ALIGN_LEFT 128
-
 
 #define TOKEN_VALUE_ONLY 0x0DEADC0D
 
-#ifdef HAVE_ALBUMART
 
-/* albumart definitions */
-#define WPS_ALBUMART_NONE           0      /* WPS does not contain AA tag */
-#define WPS_ALBUMART_CHECK          1      /* WPS contains AA conditional tag */
-#define WPS_ALBUMART_LOAD           2      /* WPS contains AA tag */
+/* wps_data*/
+struct wps_token {
+    union {
+        char c;
+        unsigned short i;
+        long l;
+        OFFSETTYPE(void*) data;
+    } value;
+
+    enum skin_token_type type; /* enough to store the token type */
+    /* Whether the tag (e.g. track name or the album) refers the
+       current or the next song (false=current, true=next) */
+    bool next;
+};
 
-#define WPS_ALBUMART_ALIGN_RIGHT    1    /* x align:   right */
-#define WPS_ALBUMART_ALIGN_CENTER   2    /* x/y align: center */
-#define WPS_ALBUMART_ALIGN_LEFT     4    /* x align:   left */
-#define WPS_ALBUMART_ALIGN_TOP      1    /* y align:   top */
-#define WPS_ALBUMART_ALIGN_BOTTOM   4    /* y align:   bottom */
+char* get_dir(char* buf, int buf_size, const char* path, int level);
 
-#endif /* HAVE_ALBUMART */
 
-/* wps_data*/
+struct skin_token_list {
+    OFFSETTYPE(struct wps_token *) token;
+    OFFSETTYPE(struct skin_token_list *) next;
+};
 
 #ifdef HAVE_LCD_BITMAP
 struct gui_img {
-    struct viewport* vp;    /* The viewport to display this image in */
+    OFFSETTYPE(struct viewport*) vp;    /* The viewport to display this image in */
     short int x;                  /* x-pos */
     short int y;                  /* y-pos */
     short int num_subimages;      /* number of sub-images */
     short int subimage_height;    /* height of each sub-image */
     struct bitmap bm;
     int buflib_handle;
-    const char *label;
+    OFFSETTYPE(char*) label;
     bool loaded;            /* load state */
     bool always_display;    /* not using the preload/display mechanism */
     int display;
@@ -86,15 +101,15 @@ struct gui_img {
 };
 
 struct image_display {
-    const char *label;
+    OFFSETTYPE(char*) label;
     int subimage;
-    struct wps_token *token; /* the token to get the subimage number from */
+    OFFSETTYPE(struct wps_token*) token; /* the token to get the subimage number from */
     int offset; /* offset into the bitmap strip to start */
 };
 
 struct progressbar {
     enum skin_token_type type;
-    struct viewport *vp;
+    OFFSETTYPE(struct viewport *) vp;
     /* regular pb */
     short x;
     /* >=0: explicitly set in the tag -> y-coord within the viewport
@@ -105,14 +120,14 @@ struct progressbar {
     short height;
     bool  follow_lang_direction;
     
-    struct gui_img *image;
+    OFFSETTYPE(struct gui_img *) image;
     
     bool invert_fill_direction;
     bool nofill;
     bool nobar;
-    struct gui_img *slider;
+    OFFSETTYPE(struct gui_img *) slider;
     bool horizontal;
-    struct gui_img *backdrop;
+    OFFSETTYPE(struct gui_img *) backdrop;
 };
 #endif
 
@@ -125,35 +140,11 @@ struct align_pos {
 };
 
 #ifdef HAVE_LCD_BITMAP
-
-#define MAX_IMAGES (26*2) /* a-z and A-Z */
-#define MAX_PROGRESSBARS 3
-
-/* The image buffer is big enough to store one full-screen native bitmap,
-   plus two full-screen mono bitmaps. */
-
-#define WPS_MAX_VIEWPORTS   24
-#define WPS_MAX_LINES       ((LCD_HEIGHT/5+1) * 2)
-#define WPS_MAX_SUBLINES    (WPS_MAX_LINES*3)
 #define WPS_MAX_TOKENS      1150
-#define WPS_MAX_STRINGS     128
-#define STRING_BUFFER_SIZE  1024
-#define WPS_MAX_COND_LEVEL  10
-
 #else
-
-#define WPS_MAX_VIEWPORTS   2
-#define WPS_MAX_LINES       2
-#define WPS_MAX_SUBLINES    12
 #define WPS_MAX_TOKENS      64
-#define WPS_MAX_STRINGS     32
-#define STRING_BUFFER_SIZE  64
-#define WPS_MAX_COND_LEVEL  5
-
 #endif
 
-#define SUBLINE_RESET -1
-
 enum wps_parse_error {
     PARSE_OK,
     PARSE_FAIL_UNCLOSED_COND,
@@ -176,12 +167,13 @@ struct gradient_config {
 #define VP_DRAW_WASHIDDEN   0x4
 /* these are never drawn, nor cleared, i.e. just ignored */
 #define VP_NEVER_VISIBLE    0x8
-#define VP_DEFAULT_LABEL    "|"
+#define VP_DEFAULT_LABEL    -200
+#define VP_DEFAULT_LABEL_STRING "|"
 struct skin_viewport {
     struct viewport vp;   /* The LCD viewport struct */
     char hidden_flags;
     bool is_infovp;
-    char* label;
+    OFFSETTYPE(char*) label;
     int   parsed_fontid;
 #if LCD_DEPTH > 1
     unsigned start_fgcolour;
@@ -192,14 +184,14 @@ struct skin_viewport {
 #endif
 };
 struct viewport_colour {
-    struct viewport *vp;
+    OFFSETTYPE(struct viewport *) vp;
     unsigned colour;
 };
 
 #ifdef HAVE_TOUCHSCREEN
 struct touchregion {
-    char* label;            /* label to identify this region */
-    struct skin_viewport* wvp;/* The viewport this region is in */
+    OFFSETTYPE(char*) label;            /* label to identify this region */
+    OFFSETTYPE(struct skin_viewport*) wvp;/* The viewport this region is in */
     short int x;             /* x-pos */
     short int y;             /* y-pos */
     short int width;         /* width */
@@ -219,7 +211,7 @@ struct touchregion {
             const struct settings_list *setting; /* setting being controlled */
             union {         /* Value to set the setting to for ACTION_SETTING_SET */
                 int number;
-                char* text;
+                OFFSETTYPE(char*) text;
             } value;
         } setting_data;
         int   value;
@@ -230,20 +222,32 @@ struct touchregion {
 
 
 struct touchregion_lastpress {
-    struct touchregion *region;
+    OFFSETTYPE(struct touchregion *) region;
     long timeout;
 };
 #endif
 
 struct playlistviewer {
-    struct viewport *vp;
+    OFFSETTYPE(struct viewport *) vp;
     bool show_icons;
     int start_offset;
-    struct skin_element *line;
+    OFFSETTYPE(struct skin_element *) line;
 };
 
 
 #ifdef HAVE_ALBUMART
+
+/* albumart definitions */
+#define WPS_ALBUMART_NONE           0      /* WPS does not contain AA tag */
+#define WPS_ALBUMART_CHECK          1      /* WPS contains AA conditional tag */
+#define WPS_ALBUMART_LOAD           2      /* WPS contains AA tag */
+
+#define WPS_ALBUMART_ALIGN_RIGHT    1    /* x align:   right */
+#define WPS_ALBUMART_ALIGN_CENTER   2    /* x/y align: center */
+#define WPS_ALBUMART_ALIGN_LEFT     4    /* x align:   left */
+#define WPS_ALBUMART_ALIGN_TOP      1    /* y align:   top */
+#define WPS_ALBUMART_ALIGN_BOTTOM   4    /* y align:   bottom */
+
 struct skin_albumart {
     /* Album art support */
     int x;
@@ -255,7 +259,7 @@ struct skin_albumart {
     unsigned char yalign; /* WPS_ALBUMART_ALIGN_TOP, _CENTER, _BOTTOM */
     unsigned char state; /* WPS_ALBUMART_NONE, _CHECK, _LOAD */
     
-    struct viewport *vp;
+    OFFSETTYPE(struct viewport *) vp;
     int draw_handle;
 };
 #endif
@@ -272,11 +276,11 @@ struct line_alternator {
 
 struct conditional {
     int last_value;
-    struct wps_token *token;
+    OFFSETTYPE(struct wps_token *) token;
 };
 
 struct logical_if {
-    struct wps_token *token;
+    OFFSETTYPE(struct wps_token *) token;
     enum {
         IF_EQUALS, /* == */
         IF_NOTEQUALS, /* != */
@@ -292,7 +296,7 @@ struct logical_if {
 struct substring {
     int start;
     int length;
-    struct wps_token *token;
+    OFFSETTYPE(struct wps_token *) token;
 };
 
 struct listitem {
@@ -302,16 +306,16 @@ struct listitem {
 
 #ifdef HAVE_SKIN_VARIABLES
 struct skin_var {
-    const char *label;
+    OFFSETTYPE(const char *) label;
     int value;
     long last_changed;
 };
 struct skin_var_lastchange {
-    struct skin_var *var;
+    OFFSETTYPE(struct skin_var *) var;
     long timeout;
 };
 struct skin_var_changer {
-    struct skin_var *var;
+    OFFSETTYPE(struct skin_var *) var;
     int newval;
     bool direct; /* true to make val=newval, false for val += newval */
     int max;
@@ -323,30 +327,27 @@ struct skin_var_changer {
    viewable content of a wps */
 struct wps_data
 {
-    struct skin_element *tree;
+    OFFSETTYPE(struct skin_element *) tree;
 #ifdef HAVE_LCD_BITMAP
-    struct skin_token_list *images;
-    int *font_ids;
+    OFFSETTYPE(struct skin_token_list *) images;
+    OFFSETTYPE(int *) font_ids;
     int font_count;
 #endif
 #if LCD_DEPTH > 1 || defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1
-    struct {
-        char *backdrop;
-        int backdrop_id;
-    };
+    int backdrop_id;
 #endif
 
 #ifdef HAVE_TOUCHSCREEN
-    struct skin_token_list *touchregions;
+    OFFSETTYPE(struct skin_token_list *) touchregions;
     bool touchscreen_locked;
 #endif
 #ifdef HAVE_ALBUMART
-    struct skin_albumart *albumart;
+    OFFSETTYPE(struct skin_albumart *) albumart;
     int    playback_aa_slot;
 #endif
 
 #ifdef HAVE_SKIN_VARIABLES
-    struct skin_token_list *skinvars;
+    OFFSETTYPE(struct skin_token_list *) skinvars;
 #endif
 
 #ifdef HAVE_LCD_BITMAP
diff --git a/apps/gui/statusbar-skinned.c b/apps/gui/statusbar-skinned.c
index 7850e7c..ff14512 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)
         /* hide the sb's default viewport because it has nasty effect with stuff
         * not part of the statusbar,
         * hence .sbs's without any other vps are unsupported*/
-        struct skin_viewport *vp = skin_find_item(VP_DEFAULT_LABEL, SKIN_FIND_VP, data);
-        struct skin_element *next_vp = data->tree->next;
+        struct skin_viewport *vp = skin_find_item(VP_DEFAULT_LABEL_STRING, SKIN_FIND_VP, data);
+        struct skin_element *tree = SKINOFFSETTOPTR(skin_buffer, data->tree);
+        struct skin_element *next_vp = tree->next;
         
         if (vp)
         {
@@ -99,7 +100,7 @@ int sb_postproccess(enum screen_type screen, struct wps_data *data)
             /* hide this viewport, forever */
             vp->hidden_flags = VP_NEVER_VISIBLE;
         }
-        sb_set_info_vp(screen, VP_DEFAULT_LABEL);
+        sb_set_info_vp(screen, VP_DEFAULT_LABEL_STRING);
     }
     viewportmanager_theme_undo(screen, false);
     return 1;
diff --git a/apps/gui/wps.c b/apps/gui/wps.c
index 6486e42..97c945d 100644
--- a/apps/gui/wps.c
+++ b/apps/gui/wps.c
@@ -667,7 +667,7 @@ static void gwps_enter_wps(void)
 #if LCD_DEPTH > 1
         if (display->depth > 1)
         {
-            struct skin_viewport *svp = skin_find_item(VP_DEFAULT_LABEL, 
+            struct skin_viewport *svp = skin_find_item(VP_DEFAULT_LABEL_STRING, 
                                                        SKIN_FIND_VP, gwps->data);
             if (svp)
             {
diff --git a/apps/recorder/albumart.c b/apps/recorder/albumart.c
index 43f18cd..af1aac9 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)
         return;
 
     struct wps_data *data = gwps->data;
-    struct skin_albumart *aa = data->albumart;
+    struct skin_albumart *aa = SKINOFFSETTOPTR(skin_buffer, data->albumart);
 
     if (!aa)
         return;
