diff --git a/apps/SOURCES b/apps/SOURCES
index 9bc8859..2a13b62 100644
--- a/apps/SOURCES
+++ b/apps/SOURCES
@@ -89,12 +89,12 @@ gui/statusbar.c
 #ifdef HAVE_LCD_BITMAP
 gui/statusbar-skinned.c
 #endif
-gui/theme_settings.c
 gui/yesno.c
 gui/viewport.c
 
 gui/skin_engine/skin_backdrops.c
 gui/skin_engine/skin_display.c
+gui/skin_engine/skin_engine.c
 #ifdef HAVE_LCD_BITMAP
 gui/skin_engine/skin_fonts.c
 #endif
diff --git a/apps/gui/skin_engine/skin_backdrops.c b/apps/gui/skin_engine/skin_backdrops.c
index 9ceee0c..5a8ae87 100644
--- a/apps/gui/skin_engine/skin_backdrops.c
+++ b/apps/gui/skin_engine/skin_backdrops.c
@@ -81,6 +81,7 @@ char* skin_backdrop_load(char* backdrop, char *bmpdir, enum screen_type screen)
             snprintf(filename, sizeof(filename), "%s/%s.bmp",
                      get_user_file_path(BACKDROP_DIR, 0, dir, sizeof(dir)),
                      global_settings.backdrop_file);
+            printf("%s\n", filename);
         }
     }
     else
@@ -91,7 +92,8 @@ char* skin_backdrop_load(char* backdrop, char *bmpdir, enum screen_type screen)
     
     for(i=0;i<SKINNABLE_SCREENS_COUNT*NB_SCREENS;i++)
     {
-        if (!strcmp(backdrops[i].name, filename) && backdrops[i].screen == screen)
+        if (!strcmp(backdrops[i].name, filename) &&
+            backdrops[i].screen == screen && backdrops[i].buffer)
         {
             return backdrops[i].buffer;
         }
@@ -112,6 +114,18 @@ char* skin_backdrop_load(char* backdrop, char *bmpdir, enum screen_type screen)
     
     return loaded ? bdrop->buffer : NULL;
 }
+
+void skin_backdrop_unload(char* buffer)
+{
+    int i;
+    for(i=0;i<SKINNABLE_SCREENS_COUNT*NB_SCREENS;i++)
+    {
+        if (backdrops[i].buffer == buffer)
+        {
+            backdrops[i].buffer = NULL;
+        }
+    }
+}
 #else
 
 void skin_backdrop_init(void)
diff --git a/apps/gui/skin_engine/skin_display.c b/apps/gui/skin_engine/skin_display.c
index d76b579..f001640 100644
--- a/apps/gui/skin_engine/skin_display.c
+++ b/apps/gui/skin_engine/skin_display.c
@@ -74,18 +74,21 @@ void skin_render(struct gui_wps *gwps, unsigned refresh_mode);
 
 /* update a skinned screen, update_type is WPS_REFRESH_* values.
  * Usually it should only be WPS_REFRESH_NON_STATIC
- * A full update will be done if required (state.do_full_update == true)
+ * A full update will be done if required (skin_do_full_update() == true)
  */
-void skin_update(struct gui_wps *gwps, unsigned int update_type)
+void skin_update(enum skinnable_screens skin, enum screen_type screen,
+                 unsigned int update_type)
 {
+    struct gui_wps *gwps = skin_get_gwps(skin, screen);
     /* This maybe shouldnt be here, 
      * This is also safe for skined screen which dont use the id3 */
-    struct mp3entry *id3 = gwps->state->id3;
+    struct mp3entry *id3 = skin_get_global_state()->id3;
     bool cuesheet_update = (id3 != NULL ? cuesheet_subtrack_changed(id3) : false);
-    gwps->sync_data->do_full_update |= cuesheet_update;
+    if (cuesheet_update)
+        skin_request_full_update(skin);
  
-    skin_render(gwps, gwps->sync_data->do_full_update ?
-                                        SKIN_REFRESH_ALL : update_type);
+    skin_render(gwps, skin_do_full_update(skin, screen) ? 
+                        SKIN_REFRESH_ALL : update_type);
 }
 
 #ifdef HAVE_LCD_BITMAP
@@ -126,7 +129,7 @@ void draw_progressbar(struct gui_wps *gwps, int line, struct progressbar *pb)
 {
     struct screen *display = gwps->display;
     struct viewport *vp = pb->vp;
-    struct wps_state *state = gwps->state;
+    struct wps_state *state = skin_get_global_state();
     struct mp3entry *id3 = state->id3;
     int y = pb->y, height = pb->height;
     unsigned long length, end;
@@ -729,11 +732,10 @@ bool skin_has_sbs(enum screen_type screen, struct wps_data *data)
 
 /* do the button loop as often as required for the peak meters to update
  * with a good refresh rate. 
- * gwps is really gwps[NB_SCREENS]! don't wrap this if FOR_NB_SCREENS()
  */
-int skin_wait_for_action(struct gui_wps *gwps, int context, int timeout)
+int skin_wait_for_action(enum skinnable_screens skin, int context, int timeout)
 {
-    (void)gwps; /* silence charcell warning */
+    (void)skin; /* silence charcell warning */
     int button = ACTION_NONE;
 #ifdef HAVE_LCD_BITMAP
     int i;
@@ -744,7 +746,7 @@ int skin_wait_for_action(struct gui_wps *gwps, int context, int timeout)
     bool pm=false;
     FOR_NB_SCREENS(i)
     {
-       if(gwps[i].data->peak_meter_enabled)
+       if(skin_get_gwps(skin, i)->data->peak_meter_enabled)
            pm = true;
     }
 
@@ -763,8 +765,8 @@ int skin_wait_for_action(struct gui_wps *gwps, int context, int timeout)
             if (TIME_AFTER(current_tick, next_refresh)) {
                 FOR_NB_SCREENS(i)
                 {
-                    if(gwps[i].data->peak_meter_enabled)
-                        skin_update(&gwps[i], SKIN_REFRESH_PEAK_METER);
+                    if(skin_get_gwps(skin, i)->data->peak_meter_enabled)
+                        skin_update(skin, i, SKIN_REFRESH_PEAK_METER);
                     next_refresh += HZ / PEAK_METER_FPS;
                 }
             }
@@ -781,3 +783,6 @@ int skin_wait_for_action(struct gui_wps *gwps, int context, int timeout)
     }
     return button;
 }
+
+
+
diff --git a/apps/gui/skin_engine/skin_engine.c b/apps/gui/skin_engine/skin_engine.c
new file mode 100644
index 0000000..657078d
--- /dev/null
+++ b/apps/gui/skin_engine/skin_engine.c
@@ -0,0 +1,245 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright (C) 2002 by Stuart Martin
+ * RTC config saving code (C) 2002 by hessu@hes.iki.fi
+ *
+ * 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.
+ *
+ ****************************************************************************/
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <limits.h>
+#include "inttypes.h"
+#include "config.h"
+#include "action.h"
+#include "crc32.h"
+#include "settings.h"
+#include "wps.h"
+#include "file.h"
+#include "buffer.h"
+#if CONFIG_TUNER
+#include "radio.h"
+#endif
+#include "skin_engine.h"
+#include "skin_buffer.h"
+#include "statusbar-skinned.h"
+
+static char *skin_buffer = NULL;
+void theme_init_buffer(void)
+{
+    skin_buffer = buffer_alloc(SKIN_BUFFER_SIZE);
+}
+
+void settings_apply_skins(void)
+{
+    int i, j;
+    skin_buffer_init(skin_buffer, SKIN_BUFFER_SIZE);
+    
+#ifdef HAVE_LCD_BITMAP
+    skin_backdrop_init();
+    skin_font_init();
+#endif
+    gui_sync_skin_init();
+
+    /* Make sure each skin is loaded */
+    for (i=0; i<SKINNABLE_SCREENS_COUNT; i++)
+    {
+        FOR_NB_SCREENS(j)
+            skin_get_gwps(i, j);
+    }
+    viewportmanager_theme_changed(THEME_STATUSBAR);
+#if LCD_DEPTH > 1 || defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1
+    FOR_NB_SCREENS(i)
+        screens[i].backdrop_show(sb_get_backdrop(i));
+#endif
+}
+
+
+char* wps_default_skin(enum screen_type screen);
+char* default_radio_skin(enum screen_type screen);
+int sb_preproccess(enum screen_type screen, struct wps_data *data);
+int sb_postproccess(enum screen_type screen, struct wps_data *data);
+struct wps_state     wps_state               = { .id3 = NULL };
+static struct gui_skin_helper {
+    int (*preproccess)(enum screen_type screen, struct wps_data *data);
+    int (*postproccess)(enum screen_type screen, struct wps_data *data);
+    char* (*default_skin)(enum screen_type screen);
+} skin_helpers[SKINNABLE_SCREENS_COUNT] = {
+    [CUSTOM_STATUSBAR] = { sb_preproccess, sb_postproccess, sb_create_from_settings },
+    [WPS] = { NULL, NULL, wps_default_skin },
+#if CONFIG_TUNER
+    [FM_SCREEN] = { NULL, NULL, default_radio_skin }
+#endif
+};
+    
+struct gui_skin {
+    struct gui_wps      gui_wps;
+    struct wps_data     data;
+    char                *buffer_start;
+    size_t              buffer_usage;
+    
+    bool                needs_full_update;
+} skins[SKINNABLE_SCREENS_COUNT][NB_SCREENS];
+
+
+void gui_sync_skin_init(void)
+{
+    int i, j;
+    for(j=0; j<SKINNABLE_SCREENS_COUNT; j++)
+    {
+        FOR_NB_SCREENS(i)
+        {
+            skins[j][i].buffer_start = NULL;
+            skins[j][i].needs_full_update = true;
+#ifdef HAVE_ALBUMART
+            skins[j][i].data.albumart = NULL;
+            skins[j][i].data.playback_aa_slot = -1;
+#endif
+            skins[j][i].gui_wps.data = &skins[j][i].data;
+            skins[j][i].data.wps_loaded = false;
+            skins[j][i].gui_wps.display = &screens[i];
+        }
+    }
+}
+
+void skin_load(enum skinnable_screens skin, enum screen_type screen,
+               const char *buf, bool isfile)
+{
+    bool loaded = false;
+    
+    if (skin_helpers[skin].preproccess)
+        skin_helpers[skin].preproccess(screen, &skins[skin][screen].data);
+    
+    if (buf && *buf)
+        loaded = skin_data_load(screen, &skins[skin][screen].data, buf, isfile);
+
+    if (!loaded && skin_helpers[skin].default_skin)
+        loaded = skin_data_load(screen, &skins[skin][screen].data,
+                                skin_helpers[skin].default_skin(screen), false);
+    
+    skins[skin][screen].needs_full_update = true;
+    if (skin_helpers[skin].postproccess)
+        skin_helpers[skin].postproccess(screen, &skins[skin][screen].data);
+}
+
+static bool loading_a_sbs = false;
+struct gui_wps *skin_get_gwps(enum skinnable_screens skin, enum screen_type screen)
+{
+    if (!loading_a_sbs && skins[skin][screen].data.wps_loaded == false)
+    {
+        char buf[MAX_PATH*2], path[MAX_PATH];
+        char *setting, *ext;
+        switch (skin)
+        {
+            case CUSTOM_STATUSBAR:
+                if (skin_buffer == NULL)
+                {
+                    /* still loading, buffers not initialised yet,
+                     * viewport manager calls into the sbs code, not really
+                     * caring if the sbs has loaded or not, so just return
+                     * the gwps, this is safe. */
+                    return &skins[skin][screen].gui_wps;
+                }
+                /* during the sbs load it will call skin_get_gwps() a few times
+                 * which will eventually stkov the viewportmanager, so make
+                 * sure we don't let that happen */
+                loading_a_sbs = true;
+#if defined(HAVE_REMOTE_LCD) && NB_SCREENS > 1
+                if (screen == SCREEN_REMOTE)
+                {
+                    setting = global_settings.rsbs_file;
+                    ext = "rsbs";
+                }
+                else
+#endif
+                {
+                    setting = global_settings.sbs_file;
+                    ext = "sbs";
+                }
+                break;
+            case WPS:
+#if defined(HAVE_REMOTE_LCD) && NB_SCREENS > 1
+                if (screen == SCREEN_REMOTE)
+                {
+                    setting = global_settings.rwps_file;
+                    ext = "rwps";
+                }
+                else
+#endif
+                {
+                    setting = global_settings.wps_file;
+                    ext = "wps";
+                }
+                break;
+#if CONFIG_TUNER
+            case FM_SCREEN:
+#if defined(HAVE_REMOTE_LCD) && NB_SCREENS > 1
+                if (screen == SCREEN_REMOTE)
+                {
+                    setting = global_settings.rfms_file;
+                    ext = "rfms";
+                }
+                else
+#endif
+                {
+                    setting = global_settings.fms_file;
+                    ext = "fms";
+                }
+                break;
+#endif
+            default:
+                return NULL;
+        }
+        
+        buf[0] = '\0'; /* force it to reload the default */
+        if (strcmp(setting, "rockbox_failsafe"))
+        {
+            snprintf(buf, sizeof buf, "%s/%s.%s",
+                 get_user_file_path(WPS_DIR, false, path, sizeof(path)),
+                 setting, ext);
+        }
+        cpu_boost(true);
+        skin_load(skin, screen, buf, true);
+        cpu_boost(false);
+        loading_a_sbs = false;
+    }
+        
+    return &skins[skin][screen].gui_wps;
+}
+
+struct wps_state *skin_get_global_state(void)
+{
+    return &wps_state;
+}
+
+/* This is called to find out if we the screen needs a full update.
+ * if true you MUST do a full update as the next call will return false */
+bool skin_do_full_update(enum skinnable_screens skin,
+                            enum screen_type screen)
+{
+    bool ret = skins[skin][screen].needs_full_update;
+    skins[skin][screen].needs_full_update = false;
+    return ret;
+}
+
+/* tell a skin to do a full update next time */
+void skin_request_full_update(enum skinnable_screens skin)
+{
+    int i;
+    FOR_NB_SCREENS(i)
+        skins[skin][i].needs_full_update = true;
+}
diff --git a/apps/gui/skin_engine/skin_engine.h b/apps/gui/skin_engine/skin_engine.h
index 6beedd9..42c291a 100644
--- a/apps/gui/skin_engine/skin_engine.h
+++ b/apps/gui/skin_engine/skin_engine.h
@@ -73,7 +73,8 @@ void skin_disarm_touchregions(struct wps_data *data);
 #endif
 
 /* Do a update_type update of the skinned screen */
-void skin_update(struct gui_wps *gwps, unsigned int update_type);
+void skin_update(enum skinnable_screens skin, enum screen_type screen,
+                 unsigned int update_type);
 
 /*
  * setup up the skin-data from a format-buffer (isfile = false)
@@ -98,7 +99,17 @@ void skin_backdrop_init(void);
  * with a good refresh rate. 
  * gwps is really gwps[NB_SCREENS]! don't wrap this in FOR_NB_SCREENS()
  */
-int skin_wait_for_action(struct gui_wps *gwps, int context, int timeout);
-#endif
+int skin_wait_for_action(enum skinnable_screens skin, int context, int timeout);
+
+void skin_load(enum skinnable_screens skin, enum screen_type screen,
+               const char *buf, bool isfile);
+struct gui_wps *skin_get_gwps(enum skinnable_screens skin, enum screen_type screen);
+struct wps_state *skin_get_global_state(void);
+void gui_sync_skin_init(void);
+
+
+bool skin_do_full_update(enum skinnable_screens skin, enum screen_type screen);
+void skin_request_full_update(enum skinnable_screens skin);
 
+#endif /* !PLUGIN */
 #endif
diff --git a/apps/gui/skin_engine/skin_parser.c b/apps/gui/skin_engine/skin_parser.c
index a6d4c79..dd087a0 100644
--- a/apps/gui/skin_engine/skin_parser.c
+++ b/apps/gui/skin_engine/skin_parser.c
@@ -1010,6 +1010,8 @@ static void skin_data_reset(struct wps_data *wps_data)
     wps_data->progressbars = NULL;
 #endif
 #if LCD_DEPTH > 1 || defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1
+    if (wps_data->backdrop)
+        skin_backdrop_unload(wps_data->backdrop);
     wps_data->backdrop = NULL;
 #endif
 #ifdef HAVE_TOUCHSCREEN
@@ -1602,6 +1604,7 @@ bool skin_data_load(enum screen_type screen, struct wps_data *wps_data,
     if (!load_skin_bitmaps(wps_data, bmpdir) ||
         !skin_load_fonts(wps_data)) 
     {
+        printf("failed\n");
         skin_data_reset(wps_data);
         skin_buffer_restore_position();
         return false;
diff --git a/apps/gui/skin_engine/skin_render.c b/apps/gui/skin_engine/skin_render.c
index 9f392f1..4fbd550 100644
--- a/apps/gui/skin_engine/skin_render.c
+++ b/apps/gui/skin_engine/skin_render.c
@@ -749,7 +749,8 @@ static void skin_render_playlistviewer(struct playlistviewer* viewer,
     else
 #endif
     {
-        struct cuesheet *cue = gwps->state->id3 ? gwps->state->id3->cuesheet:NULL;
+        struct cuesheet *cue = skin_get_global_state()->id3 ? 
+                               skin_get_global_state()->id3->cuesheet : NULL;
         cur_pos = playlist_get_display_index();
         max = playlist_amount()+1;
         if (cue)
diff --git a/apps/gui/skin_engine/skin_tokens.c b/apps/gui/skin_engine/skin_tokens.c
index 3de6630..0e98c2d 100644
--- a/apps/gui/skin_engine/skin_tokens.c
+++ b/apps/gui/skin_engine/skin_tokens.c
@@ -515,18 +515,18 @@ const char *get_radio_token(struct wps_token *token, int preset_offset,
 }
 #endif
 
-static struct mp3entry* get_mp3entry_from_offset(struct gui_wps *gwps,
-                                                 int offset, char **filename)
+static struct mp3entry* get_mp3entry_from_offset(int offset, char **filename)
 {
     struct mp3entry* pid3 = NULL;
-    struct cuesheet *cue = gwps->state->id3 ? gwps->state->id3->cuesheet:NULL;
+    struct wps_state *state = skin_get_global_state();
+    struct cuesheet *cue = state->id3 ? state->id3->cuesheet : NULL;
     const char *fname = NULL;
     if (cue && cue->curr_track_idx + offset < cue->track_count)
-        pid3 = gwps->state->id3;
+        pid3 = state->id3;
     else if (offset == 0)
-        pid3 = gwps->state->id3;
+        pid3 = state->id3;
     else if (offset == 1)
-        pid3 = gwps->state->nid3;
+        pid3 = state->nid3;
     else
     {
         static char filename_buf[MAX_PATH + 1];
@@ -568,7 +568,7 @@ const char *get_token_value(struct gui_wps *gwps,
         return NULL;
 
     struct wps_data *data = gwps->data;
-    struct wps_state *state = gwps->state;
+    struct wps_state *state = skin_get_global_state();
     struct mp3entry *id3; /* Think very carefully about using this. 
                              maybe get_id3_token() is the better place? */
     const char *out_text = NULL;
@@ -577,7 +577,7 @@ const char *get_token_value(struct gui_wps *gwps,
     if (!data || !state)
         return NULL;
 
-    id3 = get_mp3entry_from_offset(gwps, token->next? 1: offset, &filename);
+    id3 = get_mp3entry_from_offset(token->next? 1: offset, &filename);
     if (id3)
         filename = id3->path;
         
diff --git a/apps/gui/skin_engine/wps_internals.h b/apps/gui/skin_engine/wps_internals.h
index 0767f50..6d83d77 100644
--- a/apps/gui/skin_engine/wps_internals.h
+++ b/apps/gui/skin_engine/wps_internals.h
@@ -305,18 +305,6 @@ struct wps_state
     bool is_fading;
 };
 
-/* Holds data for all screens in a skin. */
-struct wps_sync_data
-{
-    /* suitable for the viewportmanager, possibly only temporary here
-     * needs to be same for all screens! can't be split up for screens
-     * due to what viewportmanager_set_statusbar() accepts
-     * (FIXME?) */
-    int statusbars;
-    /* indicates whether the skin needs a full update for all screens */
-    bool do_full_update;
-};
-
 /* change the ff/rew-status
    if ff_rew = true then we are in skipping mode
    else we are in normal mode */
@@ -334,9 +322,6 @@ struct gui_wps
 {
     struct screen *display;
     struct wps_data *data;
-    struct wps_state *state;
-    /* must point to the same struct for all screens */
-    struct wps_sync_data *sync_data;
 };
 
 /* gui_wps end */
diff --git a/apps/gui/statusbar-skinned.c b/apps/gui/statusbar-skinned.c
index e22ab28..cd681cb 100644
--- a/apps/gui/statusbar-skinned.c
+++ b/apps/gui/statusbar-skinned.c
@@ -40,13 +40,6 @@
 #include "icon.h"
 #include "option_select.h"
 
-
-/* currently only one wps_state is needed */
-extern struct wps_state     wps_state; /* from wps.c */
-static struct gui_wps       sb_skin[NB_SCREENS]      = {{ .data = NULL }};
-static struct wps_data      sb_skin_data[NB_SCREENS] = {{ .wps_loaded = 0 }};
-static struct wps_sync_data sb_skin_sync_data        = { .do_full_update = false };
-
 /* initial setup of wps_data  */
 static int update_delay = DEFAULT_UPDATE_DELAY;
 static int set_title_worker(char* title, enum themable_icons icon, 
@@ -102,26 +95,26 @@ static int set_title_worker(char* title, enum themable_icons icon,
 
 bool sb_set_title_text(char* title, enum themable_icons icon, enum screen_type screen)
 {
-    bool retval = set_title_worker(title, icon, &sb_skin_data[screen], 
-                                   sb_skin_data[screen].tree) > 0;
+    struct wps_data *data = skin_get_gwps(CUSTOM_STATUSBAR, screen)->data;
+    bool retval = data->wps_loaded && 
+        set_title_worker(title, icon, data, data->tree) > 0;
     return retval;
 }
     
-
-void sb_skin_data_load(enum screen_type screen, const char *buf, bool isfile)
+int sb_preproccess(enum screen_type screen, struct wps_data *data)
 {
-    struct wps_data *data = sb_skin[screen].data;
-
-    int success;
+    (void)data;
     /* We need to disable the theme here or else viewport_set_defaults() 
      * (which is called in the viewport tag parser) will crash because
      * the theme is enabled but sb_set_info_vp() isnt set untill after the sbs
      * is parsed. This only affects the default viewport which is ignored
      * int he sbs anyway */
     viewportmanager_theme_enable(screen, false, NULL);
-    success = buf && skin_data_load(screen, data, buf, isfile);
-
-    if (success)
+    return 1;
+}
+int sb_postproccess(enum screen_type screen, struct wps_data *data)
+{
+    if (data->wps_loaded)
     {  
         /* hide the sb's default viewport because it has nasty effect with stuff
         * not part of the statusbar,
@@ -133,18 +126,17 @@ void sb_skin_data_load(enum screen_type screen, const char *buf, bool isfile)
         {
             if (!next_vp)
             {    /* no second viewport, let parsing fail */
-                success = false;
+                return 0;
             }
             /* hide this viewport, forever */
             vp->hidden_flags = VP_NEVER_VISIBLE;
         }
         sb_set_info_vp(screen, VP_DEFAULT_LABEL);
     }
-
-    if (!success && isfile)
-        sb_create_from_settings(screen);
     viewportmanager_theme_undo(screen, false);
+    return 1;
 }
+
 static char *infovp_label[NB_SCREENS];
 static char *oldinfovp_label[NB_SCREENS];
 void sb_set_info_vp(enum screen_type screen, char *label)
@@ -154,6 +146,7 @@ void sb_set_info_vp(enum screen_type screen, char *label)
     
 struct viewport *sb_skin_get_info_vp(enum screen_type screen)
 {
+    struct wps_data *data = skin_get_gwps(CUSTOM_STATUSBAR, screen)->data;
     if (oldinfovp_label[screen] &&
         strcmp(oldinfovp_label[screen], infovp_label[screen]))
     {
@@ -162,23 +155,27 @@ struct viewport *sb_skin_get_info_vp(enum screen_type screen)
         viewportmanager_theme_enable(screen, false, NULL);
         viewportmanager_theme_undo(screen, true);
     }        
-    return &find_viewport(infovp_label[screen], true, sb_skin[screen].data)->vp;
+    return &find_viewport(infovp_label[screen], true, data)->vp;
 }
 
 #if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1)
 char* sb_get_backdrop(enum screen_type screen)
 {
-    return sb_skin[screen].data->backdrop;
+    if (skin_get_gwps(CUSTOM_STATUSBAR, screen)->data->wps_loaded)
+        return skin_get_gwps(CUSTOM_STATUSBAR, screen)->data->backdrop;
+    else
+        return NULL;
 }
 
 bool sb_set_backdrop(enum screen_type screen, char* filename)
 {
+    struct wps_data *data = skin_get_gwps(CUSTOM_STATUSBAR, screen)->data;
     if (!filename)
     {
-        sb_skin[screen].data->backdrop = NULL;
+        data->backdrop = NULL;
         return true;
     }
-    else if (!sb_skin[screen].data->backdrop)
+    else if (!data->backdrop)
     {
         /* need to make room on the buffer */
         size_t buf_size;
@@ -188,22 +185,23 @@ bool sb_set_backdrop(enum screen_type screen, char* filename)
         else
 #endif
             buf_size = LCD_BACKDROP_BYTES;
-        sb_skin[screen].data->backdrop = (char*)skin_buffer_alloc(buf_size);
-        if (!sb_skin[screen].data->backdrop)
+        data->backdrop = (char*)skin_buffer_alloc(buf_size);
+        if (!data->backdrop)
             return false;          
     }
   
-    if (!screens[screen].backdrop_load(filename, sb_skin[screen].data->backdrop))
-        sb_skin[screen].data->backdrop = NULL;
-    return sb_skin[screen].data->backdrop != NULL;
+    if (!screens[screen].backdrop_load(filename, data->backdrop))
+        data->backdrop = NULL;
+    return data->backdrop != NULL;
 }
         
 #endif
 void sb_skin_update(enum screen_type screen, bool force)
 {
+    struct wps_data *data = skin_get_gwps(CUSTOM_STATUSBAR, screen)->data;
     static long next_update[NB_SCREENS] = {0};
     int i = screen;
-    if (!sb_skin_data[screen].wps_loaded)
+    if (!data->wps_loaded)
         return;
     if (TIME_AFTER(current_tick, next_update[i]) || force)
     {
@@ -213,24 +211,9 @@ void sb_skin_update(enum screen_type screen, bool force)
         if (lcd_active() || (i != SCREEN_MAIN))
 #endif
         {
-            bool full_update = sb_skin[i].sync_data->do_full_update;
-#if NB_SCREENS > 1
-            if (i==SCREEN_MAIN && sb_skin[i].sync_data->do_full_update)
-            {
-                sb_skin[i].sync_data->do_full_update = false;
-                /* we need to make sure the remote gets a full update
-                 * next time it is drawn also. so quick n dirty hack */
-                next_update[SCREEN_REMOTE] = 0;
-            }
-            else if (next_update[SCREEN_REMOTE] == 0)
-            {
-                full_update = true;
-            }
-#else
-            sb_skin[i].sync_data->do_full_update = false;
-#endif
-            skin_update(&sb_skin[i], force || full_update?
-                    SKIN_REFRESH_ALL : SKIN_REFRESH_NON_STATIC);
+            bool full_update = skin_do_full_update(CUSTOM_STATUSBAR, screen);
+            skin_update(CUSTOM_STATUSBAR, screen, force || 
+                        full_update ? SKIN_REFRESH_ALL : SKIN_REFRESH_NON_STATIC);
         }
         next_update[i] = current_tick + update_delay; /* don't update too often */
     }
@@ -241,7 +224,7 @@ void do_sbs_update_callback(void *param)
     (void)param;
     /* the WPS handles changing the actual id3 data in the id3 pointers
      * we imported, we just want a full update */
-    sb_skin_sync_data.do_full_update = true;
+    skin_request_full_update(CUSTOM_STATUSBAR);
     /* force timeout in wps main loop, so that the update is instantly */
     queue_post(&button_queue, BUTTON_NONE, 0);
 }
@@ -257,9 +240,10 @@ void sb_skin_set_update_delay(int delay)
  *  - ui viewport
  *  - backdrop
  */
-void sb_create_from_settings(enum screen_type screen)
+char* sb_create_from_settings(enum screen_type screen)
 {
-    char buf[128], *ptr, *ptr2;
+    static char buf[128];
+    char *ptr, *ptr2;
     int len, remaining = sizeof(buf);
     int bar_position = statusbar_position(screen);
     ptr = buf;
@@ -329,7 +313,7 @@ void sb_create_from_settings(enum screen_type screen)
         len = snprintf(ptr, remaining, "%%ax%%Vi(-,0,%d,-,%d,1)\n", 
                        y, height);
     }
-    sb_skin_data_load(screen, buf, false);
+    return buf;
 }
 
 void sb_skin_init(void)
@@ -338,16 +322,6 @@ void sb_skin_init(void)
     FOR_NB_SCREENS(i)
     {
         oldinfovp_label[i] = NULL;
-#ifdef HAVE_ALBUMART
-        sb_skin_data[i].albumart = NULL;
-        sb_skin_data[i].playback_aa_slot = -1;
-#endif
-        sb_skin[i].data = &sb_skin_data[i];
-        sb_skin[i].display = &screens[i];
-        /* Currently no seperate wps_state needed/possible
-           so use the only available ( "global" ) one */
-        sb_skin[i].state = &wps_state;
-        sb_skin[i].sync_data = &sb_skin_sync_data;
     }
 }
 
@@ -367,9 +341,10 @@ int sb_touch_to_button(int context)
         return ACTION_TOUCHSCREEN;
     
     if (last_context != context)
-        skin_disarm_touchregions(&sb_skin_data[SCREEN_MAIN]);
+        skin_disarm_touchregions(skin_get_gwps(CUSTOM_STATUSBAR, SCREEN_MAIN)->data);
     last_context = context;
-    button = skin_get_touchaction(&sb_skin_data[SCREEN_MAIN], &offset, &region);
+    button = skin_get_touchaction(skin_get_gwps(CUSTOM_STATUSBAR, SCREEN_MAIN)->data,
+                                  &offset, &region);
     
     switch (button)
     {
diff --git a/apps/gui/statusbar-skinned.h b/apps/gui/statusbar-skinned.h
index 893d489..983b371 100644
--- a/apps/gui/statusbar-skinned.h
+++ b/apps/gui/statusbar-skinned.h
@@ -34,7 +34,7 @@
 
 void sb_skin_data_load(enum screen_type screen, const char *buf, bool isfile);
 
-void sb_create_from_settings(enum screen_type screen);
+char* sb_create_from_settings(enum screen_type screen);
 void sb_skin_init(void) INIT_ATTR;
 void sb_set_info_vp(enum screen_type screen, char *label);
 struct viewport *sb_skin_get_info_vp(enum screen_type screen);
diff --git a/apps/gui/theme_settings.c b/apps/gui/theme_settings.c
deleted file mode 100644
index a975c21..0000000
--- a/apps/gui/theme_settings.c
+++ /dev/null
@@ -1,117 +0,0 @@
-/***************************************************************************
- *             __________               __   ___.
- *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
- *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
- *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
- *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
- *                     \/            \/     \/    \/            \/
- * $Id$
- *
- * Copyright (C) 2002 by Stuart Martin
- * RTC config saving code (C) 2002 by hessu@hes.iki.fi
- *
- * 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.
- *
- ****************************************************************************/
-#include <stdio.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <limits.h>
-#include "inttypes.h"
-#include "config.h"
-#include "action.h"
-#include "crc32.h"
-#include "settings.h"
-#include "wps.h"
-#include "file.h"
-#include "buffer.h"
-#if CONFIG_TUNER
-#include "radio.h"
-#endif
-#include "skin_engine/skin_engine.h"
-#include "skin_buffer.h"
-#include "statusbar-skinned.h"
-#include "bootchart.h"
-
-static char *skin_buffer = NULL;
-void theme_init_buffer(void)
-{
-    skin_buffer = buffer_alloc(SKIN_BUFFER_SIZE);
-}
-
-
-/* call this after loading a .wps/.rwps or other skin files, so that the
- * skin buffer is reset properly
- */
-struct skin_load_setting {
-    char* setting;
-    char* suffix;
-    void (*loadfunc)(enum screen_type screen, const char *buf, bool isfile);
-};
-
-static const struct skin_load_setting skins[] = {
-    /* This determins the load order. *sbs must be loaded before any other
-     * skin on that screen */
-#ifdef HAVE_LCD_BITMAP
-    { global_settings.sbs_file, "sbs", sb_skin_data_load},
-#endif    
-    { global_settings.wps_file, "wps", wps_data_load},
-#if CONFIG_TUNER
-    { global_settings.fms_file, "fms", fms_data_load},
-#endif
-#if defined(HAVE_REMOTE_LCD) && NB_SCREENS > 1
-    { global_settings.rsbs_file, "rsbs", sb_skin_data_load},
-    { global_settings.rwps_file, "rwps", wps_data_load},
-#if CONFIG_TUNER
-    { global_settings.rfms_file, "rfms", fms_data_load},
-#endif
-#endif
-};
-
-void settings_apply_skins(void)
-{
-    char buf[MAX_PATH];
-    /* re-initialize the skin buffer before we start reloading skins */
-    enum screen_type screen = SCREEN_MAIN;
-    unsigned int i;
-    
-    skin_buffer_init(skin_buffer, SKIN_BUFFER_SIZE);
-#ifdef HAVE_LCD_BITMAP
-    skin_backdrop_init();
-    skin_font_init();
-#endif
-#if CONFIG_TUNER
-    fms_skin_init();
-#endif
-    for (i=0; i<ARRAYLEN(skins); i++)
-    {
-#ifdef HAVE_REMOTE_LCD
-        screen = skins[i].suffix[0] == 'r' ? SCREEN_REMOTE : SCREEN_MAIN;
-#endif
-        CHART2(">skin load ", skins[i].suffix);
-        if (skins[i].setting[0] && skins[i].setting[0] != '-')
-        {
-            char path[MAX_PATH];
-            snprintf(buf, sizeof buf, "%s/%s.%s",
-                     get_user_file_path(WPS_DIR, false, path, sizeof(path)),
-                     skins[i].setting, skins[i].suffix);
-            skins[i].loadfunc(screen, buf, true);
-        }
-        else
-        {
-            skins[i].loadfunc(screen, NULL, true);
-        }
-        CHART2("<skin load ", skins[i].suffix);
-    }
-    viewportmanager_theme_changed(THEME_STATUSBAR);
-#if LCD_DEPTH > 1 || defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1
-    FOR_NB_SCREENS(i)
-        screens[i].backdrop_show(sb_get_backdrop(i));
-#endif
-}
diff --git a/apps/gui/wps.c b/apps/gui/wps.c
index 1489ff0..2625b45 100644
--- a/apps/gui/wps.c
+++ b/apps/gui/wps.c
@@ -74,12 +74,6 @@
                                 /* 3% of 30min file == 54s step size */
 #define MIN_FF_REWIND_STEP 500
 
-/* currently only one wps_state is needed, initialize to 0 */
-       struct wps_state     wps_state               = { .id3 = NULL };
-static struct gui_wps       gui_wps[NB_SCREENS]     = {{ .data = NULL }};
-static struct wps_data      wps_datas[NB_SCREENS]   = {{ .wps_loaded = 0 }};
-static struct wps_sync_data wps_sync_data           = { .do_full_update = false };
-
 /* initial setup of wps_data  */
 static void wps_state_init(void);
 static void track_changed_callback(void *param);
@@ -94,35 +88,9 @@ static void nextid3available_callback(void* param);
 #define DEFAULT_WPS(screen) (WPS_DEFAULTCFG)
 #endif
 
-void wps_data_load(enum screen_type screen, const char *buf, bool isfile)
+char* wps_default_skin(enum screen_type screen)
 {
-    bool loaded_ok;
-
-#ifndef __PCTOOL__
-    /*
-     * Hardcode loading WPS_DEFAULTCFG to cause a reset ideally this
-     * wants to be a virtual file.  Feel free to modify dirbrowse()
-     * if you're feeling brave.
-     */
-
-    if (buf && ! strcmp(buf, DEFAULT_WPS(screen)) )
-    {
-#ifdef HAVE_REMOTE_LCD
-        if (screen == SCREEN_REMOTE)
-            global_settings.rwps_file[0] = '\0';
-        else
-#endif
-            global_settings.wps_file[0] = '\0';
-        buf = NULL;
-    }
-
-#endif /* __PCTOOL__ */
-
-    loaded_ok = buf && skin_data_load(screen, gui_wps[screen].data, buf, isfile);
-
-    if (!loaded_ok) /* load the hardcoded default */
-    {
-        char *skin_buf[NB_SCREENS] = {
+    static char *skin_buf[NB_SCREENS] = {
 #ifdef HAVE_LCD_BITMAP
 #if LCD_DEPTH > 1
             "%X(d)\n"
@@ -148,8 +116,7 @@ void wps_data_load(enum screen_type screen, const char *buf, bool isfile)
             "%pb\n",
 #endif
         };
-        skin_data_load(screen, gui_wps[screen].data, skin_buf[screen], false);
-    }
+    return skin_buf[screen];
 }
 
 void fade(bool fade_in, bool updatewps)
@@ -158,7 +125,7 @@ void fade(bool fade_in, bool updatewps)
     int fp_min_vol = sound_min(SOUND_VOLUME) << 8;
     int fp_step = (fp_global_vol - fp_min_vol) / 30;
     int i;
-    wps_state.is_fading = !fade_in;
+    skin_get_global_state()->is_fading = !fade_in;
     if (fade_in) {
         /* fade in */
         int fp_volume = fp_min_vol;
@@ -175,7 +142,7 @@ void fade(bool fade_in, bool updatewps)
             if (updatewps)
             {
                 FOR_NB_SCREENS(i)
-                    skin_update(&gui_wps[i], SKIN_REFRESH_NON_STATIC);
+                    skin_update(WPS, i, SKIN_REFRESH_NON_STATIC);
             }
             sleep(1);
         }
@@ -191,12 +158,12 @@ void fade(bool fade_in, bool updatewps)
             if (updatewps)
             {
                 FOR_NB_SCREENS(i)
-                    skin_update(&gui_wps[i], SKIN_REFRESH_NON_STATIC);
+                    skin_update(WPS, i, SKIN_REFRESH_NON_STATIC);
             }
             sleep(1);
         }
         audio_pause();
-        wps_state.is_fading = false;
+        skin_get_global_state()->is_fading = false;
 #if CONFIG_CODEC != SWCODEC
 #ifndef SIMULATOR
         /* let audio thread run and wait for the mas to run out of data */
@@ -210,9 +177,9 @@ void fade(bool fade_in, bool updatewps)
     }
 }
 
-static bool update_onvol_change(struct gui_wps * gwps)
+static bool update_onvol_change(enum screen_type screen)
 {
-    skin_update(gwps, SKIN_REFRESH_NON_STATIC);
+    skin_update(WPS, screen, SKIN_REFRESH_NON_STATIC);
 
 #ifdef HAVE_LCD_CHARCELLS
     splashf(0, "Vol: %3d dB",
@@ -250,16 +217,16 @@ static int skintouch_to_wps(struct wps_data *data)
             return ACTION_WPS_HOTKEY;
 #endif
         case WPS_TOUCHREGION_SCROLLBAR:
-            wps_state.id3->elapsed = wps_state.id3->length*offset/100;
-            if (!wps_state.paused)
+            skin_get_global_state()->id3->elapsed = skin_get_global_state()->id3->length*offset/100;
+            if (!skin_get_global_state()->paused)
 #if (CONFIG_CODEC == SWCODEC)
                 audio_pre_ff_rewind();
 #else
                 audio_pause();
 #endif
-            audio_ff_rewind(wps_state.id3->elapsed);
+            audio_ff_rewind(skin_get_global_state()->id3->elapsed);
 #if (CONFIG_CODEC != SWCODEC)
-            if (!wps_state.paused)
+            if (!skin_get_global_state()->paused)
                 audio_resume();
 #endif
             return ACTION_TOUCHSCREEN;
@@ -307,20 +274,20 @@ bool ffwd_rew(int button)
             case ACTION_WPS_SEEKFWD:
                  direction = 1;
             case ACTION_WPS_SEEKBACK:
-                if (wps_state.ff_rewind)
+                if (skin_get_global_state()->ff_rewind)
                 {
                     if (direction == 1)
                     {
                         /* fast forwarding, calc max step relative to end */
-                        max_step = (wps_state.id3->length - 
-                                    (wps_state.id3->elapsed +
+                        max_step = (skin_get_global_state()->id3->length - 
+                                    (skin_get_global_state()->id3->elapsed +
                                      ff_rewind_count)) *
                                      FF_REWIND_MAX_PERCENT / 100;
                     }
                     else
                     {
                         /* rewinding, calc max step relative to start */
-                        max_step = (wps_state.id3->elapsed + ff_rewind_count) *
+                        max_step = (skin_get_global_state()->id3->elapsed + ff_rewind_count) *
                                     FF_REWIND_MAX_PERCENT / 100;
                     }
 
@@ -337,9 +304,9 @@ bool ffwd_rew(int button)
                 else
                 {
                     if ( (audio_status() & AUDIO_STATUS_PLAY) &&
-                          wps_state.id3 && wps_state.id3->length )
+                          skin_get_global_state()->id3 && skin_get_global_state()->id3->length )
                     {
-                        if (!wps_state.paused)
+                        if (!skin_get_global_state()->paused)
 #if (CONFIG_CODEC == SWCODEC)
                             audio_pre_ff_rewind();
 #else
@@ -347,14 +314,14 @@ bool ffwd_rew(int button)
 #endif
 #if CONFIG_KEYPAD == PLAYER_PAD
                         FOR_NB_SCREENS(i)
-                            gui_wps[i].display->stop_scroll();
+                            skin_get_gwps(WPS, i)->display->stop_scroll();
 #endif
                         if (direction > 0) 
                             status_set_ffmode(STATUS_FASTFORWARD);
                         else
                             status_set_ffmode(STATUS_FASTBACKWARD);
 
-                        wps_state.ff_rewind = true;
+                        skin_get_global_state()->ff_rewind = true;
 
                         step = 1000 * global_settings.ff_rewind_min_step;
                     }
@@ -363,23 +330,23 @@ bool ffwd_rew(int button)
                 }
 
                 if (direction > 0) {
-                    if ((wps_state.id3->elapsed + ff_rewind_count) >
-                        wps_state.id3->length)
-                        ff_rewind_count = wps_state.id3->length -
-                            wps_state.id3->elapsed;
+                    if ((skin_get_global_state()->id3->elapsed + ff_rewind_count) >
+                        skin_get_global_state()->id3->length)
+                        ff_rewind_count = skin_get_global_state()->id3->length -
+                            skin_get_global_state()->id3->elapsed;
                 }
                 else {
-                    if ((int)(wps_state.id3->elapsed + ff_rewind_count) < 0)
-                        ff_rewind_count = -wps_state.id3->elapsed;
+                    if ((int)(skin_get_global_state()->id3->elapsed + ff_rewind_count) < 0)
+                        ff_rewind_count = -skin_get_global_state()->id3->elapsed;
                 }
 
                 /* set the wps state ff_rewind_count so the progess info
                    displays corectly */
-                wps_state.ff_rewind_count = (wps_state.wps_time_countup == false)?
+                skin_get_global_state()->ff_rewind_count = (skin_get_global_state()->wps_time_countup == false)?
                                             ff_rewind_count:-ff_rewind_count;
                 FOR_NB_SCREENS(i)
                 {
-                    skin_update(&gui_wps[i],
+                    skin_update(WPS, i,
                                 SKIN_REFRESH_PLAYER_PROGRESS |
                                 SKIN_REFRESH_DYNAMIC);
                 }
@@ -387,18 +354,18 @@ bool ffwd_rew(int button)
                 break;
 
             case ACTION_WPS_STOPSEEK:
-                wps_state.id3->elapsed = wps_state.id3->elapsed+ff_rewind_count;
-                audio_ff_rewind(wps_state.id3->elapsed);
-                wps_state.ff_rewind_count = 0;
-                wps_state.ff_rewind = false;
+                skin_get_global_state()->id3->elapsed = skin_get_global_state()->id3->elapsed+ff_rewind_count;
+                audio_ff_rewind(skin_get_global_state()->id3->elapsed);
+                skin_get_global_state()->ff_rewind_count = 0;
+                skin_get_global_state()->ff_rewind = false;
                 status_set_ffmode(0);
 #if (CONFIG_CODEC != SWCODEC)
-                if (!wps_state.paused)
+                if (!skin_get_global_state()->paused)
                     audio_resume();
 #endif
 #ifdef HAVE_LCD_CHARCELLS
                 FOR_NB_SCREENS(i)
-                    skin_update(&gui_wps[i], SKIN_REFRESH_ALL);
+                    skin_update(WPS, i, SKIN_REFRESH_ALL);
 #endif
                 exit = true;
                 break;
@@ -416,7 +383,7 @@ bool ffwd_rew(int button)
             button = get_action(CONTEXT_WPS|ALLOW_SOFTLOCK,TIMEOUT_BLOCK);
 #ifdef HAVE_TOUCHSCREEN
             if (button == ACTION_TOUCHSCREEN)
-                button = skintouch_to_wps(gui_wps[SCREEN_MAIN].data);
+                button = skintouch_to_wps(skin_get_gwps(WPS, SCREEN_MAIN)->data);
             if (button != ACTION_WPS_SEEKFWD &&
                 button != ACTION_WPS_SEEKBACK)
                 button = ACTION_WPS_STOPSEEK;
@@ -431,7 +398,7 @@ void display_keylock_text(bool locked)
 {
     int i;
     FOR_NB_SCREENS(i)
-        gui_wps[i].display->stop_scroll();
+        skin_get_gwps(WPS, i)->display->stop_scroll();
 
     splash(HZ, locked ? ID2P(LANG_KEYLOCK_ON) : ID2P(LANG_KEYLOCK_OFF));
 }
@@ -497,20 +464,21 @@ static void change_dir(int direction)
 
 static void prev_track(unsigned long skip_thresh)
 {
-    if (wps_state.id3->elapsed < skip_thresh)
+    struct wps_state *state = skin_get_global_state();
+    if (state->id3->elapsed < skip_thresh)
     {
         audio_prev();
         return;
     }
     else
     {
-        if (wps_state.id3->cuesheet)
+        if (state->id3->cuesheet)
         {
-            curr_cuesheet_skip(wps_state.id3->cuesheet, -1, wps_state.id3->elapsed);
+            curr_cuesheet_skip(state->id3->cuesheet, -1, state->id3->elapsed);
             return;
         }
 
-        if (!wps_state.paused)
+        if (!state->paused)
 #if (CONFIG_CODEC == SWCODEC)
             audio_pre_ff_rewind();
 #else
@@ -520,7 +488,7 @@ static void prev_track(unsigned long skip_thresh)
         audio_ff_rewind(0);
 
 #if (CONFIG_CODEC != SWCODEC)
-        if (!wps_state.paused)
+        if (!state->paused)
             audio_resume();
 #endif
     }
@@ -528,10 +496,11 @@ static void prev_track(unsigned long skip_thresh)
 
 static void next_track(void)
 {
+    struct wps_state *state = skin_get_global_state();
     /* take care of if we're playing a cuesheet */
-    if (wps_state.id3->cuesheet)
+    if (state->id3->cuesheet)
     {
-        if (curr_cuesheet_skip(wps_state.id3->cuesheet, 1, wps_state.id3->elapsed))
+        if (curr_cuesheet_skip(state->id3->cuesheet, 1, state->id3->elapsed))
         {
             /* if the result was false, then we really want
                to skip to the next track */
@@ -544,9 +513,10 @@ static void next_track(void)
 
 static void play_hop(int direction)
 {
+    struct wps_state *state = skin_get_global_state();
     long step = global_settings.skip_length*1000;
-    long elapsed = wps_state.id3->elapsed;
-    long remaining = wps_state.id3->length - elapsed;
+    long elapsed = state->id3->elapsed;
+    long remaining = state->id3->length - elapsed;
 
     if (step < 0)
     {
@@ -590,7 +560,7 @@ static void play_hop(int direction)
     {
         elapsed += step * direction;
     }
-    if((audio_status() & AUDIO_STATUS_PLAY) && !wps_state.paused)
+    if((audio_status() & AUDIO_STATUS_PLAY) && !state->paused)
     {
 #if (CONFIG_CODEC == SWCODEC)
         audio_pre_ff_rewind();
@@ -598,9 +568,9 @@ static void play_hop(int direction)
         audio_pause();
 #endif
     }
-    audio_ff_rewind(wps_state.id3->elapsed = elapsed);
+    audio_ff_rewind(state->id3->elapsed = elapsed);
 #if (CONFIG_CODEC != SWCODEC)
-    if (!wps_state.paused)
+    if (!state->paused)
         audio_resume();
 #endif
 }
@@ -615,7 +585,7 @@ static void play_hop(int direction)
 static void wps_lcd_activation_hook(void *param)
 {
     (void)param;
-    wps_sync_data.do_full_update = true;
+    skin_request_full_update(WPS);
     /* force timeout in wps main loop, so that the update is instantly */
     queue_post(&button_queue, BUTTON_NONE, 0);
 }
@@ -627,11 +597,11 @@ static void gwps_leave_wps(void)
 
     FOR_NB_SCREENS(i)
     {
-        gui_wps[i].display->stop_scroll();
+        skin_get_gwps(WPS, i)->display->stop_scroll();
 #if LCD_DEPTH > 1 || defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1
-        gui_wps[i].display->backdrop_show(sb_get_backdrop(i));
+        skin_get_gwps(WPS, i)->display->backdrop_show(sb_get_backdrop(i));
 #endif
-        viewportmanager_theme_undo(i, skin_has_sbs(i, gui_wps[i].data));
+        viewportmanager_theme_undo(i, skin_has_sbs(i, skin_get_gwps(WPS, i)->data));
         
     }
 
@@ -651,12 +621,14 @@ static void gwps_leave_wps(void)
 static void gwps_enter_wps(void)
 {
     int i;
+    struct gui_wps *gwps;
+    struct screen *display;
     FOR_NB_SCREENS(i)
     {
-        struct gui_wps *gwps = &gui_wps[i];
-        struct screen *display = gwps->display;
+        gwps = skin_get_gwps(WPS, i);
+        display = gwps->display;
         display->stop_scroll();
-        viewportmanager_theme_enable(i, skin_has_sbs(i, gui_wps[i].data), NULL);
+        viewportmanager_theme_enable(i, skin_has_sbs(i, skin_get_gwps(WPS, i)->data), NULL);
 
         /* Update the values in the first (default) viewport - in case the user
            has modified the statusbar or colour settings */
@@ -678,12 +650,13 @@ static void gwps_enter_wps(void)
         display->backdrop_show(gwps->data->backdrop);
 #endif
         display->clear_display();
-        skin_update(gwps, SKIN_REFRESH_ALL);
+        skin_update(WPS, i, SKIN_REFRESH_ALL);
 
     }
 #ifdef HAVE_TOUCHSCREEN
-    skin_disarm_touchregions(gui_wps[SCREEN_MAIN].data);
-    if (!gui_wps[SCREEN_MAIN].data->touchregions)
+    gwps = skin_get_gwps(WPS, SCREEN_MAIN);
+    skin_disarm_touchregions(gwps->data);
+    if (!gwps->data->touchregions)
         touchscreen_set_mode(TOUCHSCREEN_BUTTON);
 #endif
     /* force statusbar/skin update since we just cleared the whole screen */
@@ -710,6 +683,7 @@ long gui_wps_show(void)
     bool vol_changed = false;
     int i;
     long last_left = 0, last_right = 0;
+    struct wps_state *state = skin_get_global_state();
 
 #ifdef HAVE_LCD_CHARCELLS
     status_set_audio(true);
@@ -727,19 +701,19 @@ long gui_wps_show(void)
         bool audio_paused = (audio_status() & AUDIO_STATUS_PAUSE)?true:false;
 
         /* did someone else (i.e power thread) change audio pause mode? */
-        if (wps_state.paused != audio_paused) {
-            wps_state.paused = audio_paused;
+        if (state->paused != audio_paused) {
+            state->paused = audio_paused;
 
             /* if another thread paused audio, we are probably in car mode,
                about to shut down. lets save the settings. */
-            if (wps_state.paused) {
+            if (state->paused) {
                 settings_save();
 #if !defined(HAVE_RTC_RAM) && !defined(HAVE_SW_POWEROFF)
                 call_storage_idle_notifys(true);
 #endif
             }
         }
-        button = skin_wait_for_action(gui_wps, CONTEXT_WPS|ALLOW_SOFTLOCK, 
+        button = skin_wait_for_action(WPS, CONTEXT_WPS|ALLOW_SOFTLOCK, 
                                       restore ? 1 : HZ/5);
 
         /* Exit if audio has stopped playing. This happens e.g. at end of
@@ -748,7 +722,7 @@ long gui_wps_show(void)
             exit = true;
 #ifdef HAVE_TOUCHSCREEN
         if (button == ACTION_TOUCHSCREEN)
-            button = skintouch_to_wps(gui_wps[SCREEN_MAIN].data);
+            button = skintouch_to_wps(skin_get_gwps(WPS, SCREEN_MAIN)->data);
 #endif
 /* The iPods/X5/M5 use a single button for the A-B mode markers,
    defined as ACTION_WPSAB_SINGLE in their config files. */
@@ -786,7 +760,7 @@ long gui_wps_show(void)
             {
                 bool hotkey = button == ACTION_WPS_HOTKEY;
                 gwps_leave_wps();
-                int retval = onplay(wps_state.id3->path, 
+                int retval = onplay(state->id3->path, 
                            FILE_ATTR_AUDIO, CONTEXT_WPS, hotkey);
                 /* if music is stopped in the context menu we want to exit the wps */
                 if (retval == ONPLAY_MAINMENU 
@@ -815,9 +789,9 @@ long gui_wps_show(void)
             case ACTION_WPS_PLAY:
                 if (global_settings.party_mode)
                     break;
-                if ( wps_state.paused )
+                if ( state->paused )
                 {
-                    wps_state.paused = false;
+                    state->paused = false;
                     if ( global_settings.fade_on_stop )
                         fade(true, true);
                     else
@@ -825,7 +799,7 @@ long gui_wps_show(void)
                 }
                 else
                 {
-                    wps_state.paused = true;
+                    state->paused = true;
                     if ( global_settings.fade_on_stop )
                         fade(false, true);
                     else
@@ -852,7 +826,7 @@ long gui_wps_show(void)
                     break;
                 if (current_tick -last_right < HZ)
                 {
-                    if (wps_state.id3->cuesheet)
+                    if (state->id3->cuesheet)
                     {
                         audio_next();
                     }
@@ -872,9 +846,9 @@ long gui_wps_show(void)
                     break;
                 if (current_tick -last_left < HZ)
                 {
-                    if (wps_state.id3->cuesheet)
+                    if (state->id3->cuesheet)
                     {
-                        if (!wps_state.paused)
+                        if (!state->paused)
 #if (CONFIG_CODEC == SWCODEC)
                             audio_pre_ff_rewind();
 #else
@@ -902,7 +876,7 @@ long gui_wps_show(void)
                    is past the A marker, jump back to the A marker... */
                 if ( ab_repeat_mode_enabled() )
                 {
-                    if ( ab_after_A_marker(wps_state.id3->elapsed) )
+                    if ( ab_after_A_marker(state->id3->elapsed) )
                     {
                         ab_jump_to_A_marker();
                         break;
@@ -925,7 +899,7 @@ long gui_wps_show(void)
                    before the A marker, jump to the A marker... */
                 if ( ab_repeat_mode_enabled() )
                 {
-                    if ( ab_before_A_marker(wps_state.id3->elapsed) )
+                    if ( ab_before_A_marker(state->id3->elapsed) )
                     {
                         ab_jump_to_A_marker();
                         break;
@@ -944,7 +918,7 @@ long gui_wps_show(void)
 #if defined(AB_REPEAT_ENABLE)
                 if (ab_repeat_mode_enabled())
                 {
-                    ab_set_B_marker(wps_state.id3->elapsed);
+                    ab_set_B_marker(state->id3->elapsed);
                     ab_jump_to_A_marker();
                 }
                 else
@@ -958,7 +932,7 @@ long gui_wps_show(void)
                     break;
 #if defined(AB_REPEAT_ENABLE)
                 if (ab_repeat_mode_enabled())
-                    ab_set_A_marker(wps_state.id3->elapsed);
+                    ab_set_A_marker(state->id3->elapsed);
                 else
 #endif
                 {
@@ -1060,7 +1034,7 @@ long gui_wps_show(void)
              /* this case is used by the softlock feature
               * it requests a full update here */
             case ACTION_REDRAW:
-                wps_sync_data.do_full_update = true;
+                skin_request_full_update(WPS);
                 break;
             case ACTION_NONE: /* Timeout, do a partial update */
                 update = true;
@@ -1095,7 +1069,7 @@ long gui_wps_show(void)
             setvol();
             FOR_NB_SCREENS(i)
             {
-                if(update_onvol_change(&gui_wps[i]))
+                if(update_onvol_change(i))
                     res = true;
             }
             if (res) {
@@ -1117,15 +1091,15 @@ long gui_wps_show(void)
         /* we remove the update delay since it's not very usable in the wps,
          * e.g. during volume changing or ffwd/rewind */
             sb_skin_set_update_delay(0);
-            wps_sync_data.do_full_update = update = false;
+            skin_request_full_update(WPS);
+            update = true;
             gwps_enter_wps();
         }
-        else if (wps_sync_data.do_full_update || update)
+        else
         {
 #if defined(HAVE_BACKLIGHT) || defined(HAVE_REMOTE_LCD)
-            gwps_caption_backlight(&wps_state);
+            gwps_caption_backlight(state);
 #endif
-            bool full_update = wps_sync_data.do_full_update;
             FOR_NB_SCREENS(i)
             {
 #if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
@@ -1134,17 +1108,12 @@ long gui_wps_show(void)
                 if (lcd_active() || (i != SCREEN_MAIN))
 #endif
                 {
-#if NB_SCREENS > 1
-                    if (i==SCREEN_MAIN && wps_sync_data.do_full_update)
+                    bool full_update = skin_do_full_update(WPS, i);
+                    if (update || full_update)
                     {
-                        wps_sync_data.do_full_update = false;
-                    }
-                    
-#else
-                    wps_sync_data.do_full_update = false;
-#endif
-                    skin_update(&gui_wps[i], full_update ?
+                        skin_update(WPS, i, full_update ?
                                      SKIN_REFRESH_ALL : SKIN_REFRESH_NON_STATIC);
+                    }
                 }
             }
             update = false;
@@ -1183,72 +1152,54 @@ long gui_wps_show(void)
 /* this is called from the playback thread so NO DRAWING! */
 static void track_changed_callback(void *param)
 {
-    wps_state.id3 = (struct mp3entry*)param;
-    wps_state.nid3 = audio_next_track();
-    if (wps_state.id3->cuesheet)
+    struct wps_state *state = skin_get_global_state();
+    state->id3 = (struct mp3entry*)param;
+    state->nid3 = audio_next_track();
+    if (state->id3->cuesheet)
     {
-        cue_find_current_track(wps_state.id3->cuesheet, wps_state.id3->elapsed);
+        cue_find_current_track(state->id3->cuesheet, state->id3->elapsed);
     }
-    wps_sync_data.do_full_update = true;
+    skin_request_full_update(WPS);
 }
 static void nextid3available_callback(void* param)
 {
     (void)param;
-    wps_state.nid3 = audio_next_track();
-    wps_sync_data.do_full_update = true;
+    skin_get_global_state()->nid3 = audio_next_track();
+    skin_request_full_update(WPS);
 }
 
 
 static void wps_state_init(void)
 {
-    wps_state.ff_rewind = false;
-    wps_state.paused = false;
+    struct wps_state *state = skin_get_global_state();
+    state->ff_rewind = false;
+    state->paused = false;
     if(audio_status() & AUDIO_STATUS_PLAY)
     {
-        wps_state.id3 = audio_current_track();
-        wps_state.nid3 = audio_next_track();
+        state->id3 = audio_current_track();
+        state->nid3 = audio_next_track();
     }
     else
     {
-        wps_state.id3 = NULL;
-        wps_state.nid3 = NULL;
+        state->id3 = NULL;
+        state->nid3 = NULL;
     }
     /* We'll be updating due to restore initialized with true */
-    wps_sync_data.do_full_update = false;
+    skin_request_full_update(WPS);
     /* add the WPS track event callbacks */
     add_event(PLAYBACK_EVENT_TRACK_CHANGE, false, track_changed_callback);
     add_event(PLAYBACK_EVENT_NEXTTRACKID3_AVAILABLE, false, nextid3available_callback);
 }
 
 
-void gui_sync_wps_init(void)
-{
-    int i;
-    FOR_NB_SCREENS(i)
-    {
-#ifdef HAVE_ALBUMART
-        wps_datas[i].albumart = NULL;
-        wps_datas[i].playback_aa_slot = -1;
-#endif
-        gui_wps[i].data = &wps_datas[i];
-        gui_wps[i].display = &screens[i];
-        /* Currently no seperate wps_state needed/possible
-           so use the only available ( "global" ) one */
-        gui_wps[i].state = &wps_state;
-        /* must point to the same struct for both screens */
-        gui_wps[i].sync_data = &wps_sync_data;
-    }
-}
-
-
 #ifdef IPOD_ACCESSORY_PROTOCOL
 bool is_wps_fading(void)
 {
-    return wps_state.is_fading;
+    return skin_get_global_state()->is_fading;
 }
 
 int wps_get_ff_rewind_count(void)
 {
-    return wps_state.ff_rewind_count;
+    return skin_get_global_state()->ff_rewind_count;
 }
 #endif
diff --git a/apps/main.c b/apps/main.c
index 5f2c9e5..4c05b43 100644
--- a/apps/main.c
+++ b/apps/main.c
@@ -358,7 +358,7 @@ static void init(void)
     /* Keep the order of this 3 (viewportmanager handles statusbars)
      * Must be done before any code uses the multi-screen API */
     gui_syncstatusbar_init(&statusbars);
-    gui_sync_wps_init();
+    gui_sync_skin_init();
     sb_skin_init();
     viewportmanager_init();
 
@@ -510,7 +510,7 @@ static void init(void)
     sb_skin_init();
     CHART("<sb_skin_init");
     CHART(">gui_sync_wps_init");
-    gui_sync_wps_init();
+    gui_sync_skin_init();
     CHART("<gui_sync_wps_init");
     CHART(">viewportmanager_init");
     viewportmanager_init();
diff --git a/apps/radio/radio.c b/apps/radio/radio.c
index 74bdb4b..e5badb1 100644
--- a/apps/radio/radio.c
+++ b/apps/radio/radio.c
@@ -422,7 +422,7 @@ int radio_screen(void)
     {
         radio_load_presets(global_settings.fmr_file);
     }
-    fms_get(SCREEN_MAIN)->state->id3 = NULL;
+    skin_get_global_state()->id3 = NULL;
 #ifdef HAVE_ALBUMART
     radioart_init(true);
 #endif    
@@ -469,7 +469,7 @@ int radio_screen(void)
 #endif
     fms_fix_displays(FMS_ENTER);
     FOR_NB_SCREENS(i)
-        skin_update(fms_get(i), SKIN_REFRESH_ALL);
+        skin_update(FM_SCREEN, i, SKIN_REFRESH_ALL);
 
     if(radio_preset_count() < 1 && yesno_pop(ID2P(LANG_FM_FIRST_AUTOSCAN)))
         presets_scan(NULL);
@@ -800,7 +800,7 @@ int radio_screen(void)
             {
 #endif
                 FOR_NB_SCREENS(i)
-                    skin_update(fms_get(i), update_type);
+                    skin_update(FM_SCREEN, i, update_type);
             }
         }
         update_type = 0;
diff --git a/apps/radio/radio.h b/apps/radio/radio.h
index 7c263ce..daeaee9 100644
--- a/apps/radio/radio.h
+++ b/apps/radio/radio.h
@@ -50,10 +50,6 @@ int radio_current_preset(void);
 int radio_preset_count(void);
 const struct fmstation *radio_get_preset(int preset);
 
-/* skin functions */
-void fms_data_load(enum screen_type screen, const char *buf, bool isfile);
-void fms_skin_init(void);
-
 /* callbacks for the radio settings */
 void set_radio_region(int region);
 void toggle_mono_mode(bool mono);
diff --git a/apps/radio/radio_skin.c b/apps/radio/radio_skin.c
index 28bd784..c2acaa8 100644
--- a/apps/radio/radio_skin.c
+++ b/apps/radio/radio_skin.c
@@ -33,45 +33,37 @@
 #include "option_select.h"
 
 
-extern struct wps_state     wps_state; /* from wps.c */
-static struct gui_wps       fms_skin[NB_SCREENS]      = {{ .data = NULL }};
-static struct wps_data      fms_skin_data[NB_SCREENS] = {{ .wps_loaded = 0 }};
-static struct wps_sync_data fms_skin_sync_data        = { .do_full_update = false };
-
-void fms_data_load(enum screen_type screen, const char *buf, bool isfile)
+char* default_radio_skin(enum screen_type screen)
 {
-    struct wps_data *data = fms_skin[screen].data;
-    int success;
-    success = buf && skin_data_load(screen, data, buf, isfile);
-
-    if (!success ) /* load the default */
-    {  
-        const char default_fms[] =  "%s%?Ti<%Ti. |>%?Tn<%Tn|%Tf>\n"
-                                    "%Sx(Station:) %tf MHz\n"
-                                    "%?St(force fm mono)<%Sx(Force Mono)|%?ts<%Sx(Stereo)|%Sx(Mono)>>\n"
-                                    "%Sx(Mode:) %?tm<%Sx(Scan)|%Sx(Preset)>\n"
+    (void)screen;
+    static char default_fms[] = 
+        "%s%?Ti<%Ti. |>%?Tn<%Tn|%Tf>\n"
+        "%Sx(Station:) %tf MHz\n"
+        "%?St(force fm mono)<%Sx(Force Mono)|%?ts<%Sx(Stereo)|%Sx(Mono)>>\n"
+        "%Sx(Mode:) %?tm<%Sx(Scan)|%Sx(Preset)>\n"
 #if CONFIG_CODEC != SWCODEC && !defined(SIMULATOR)
-                                    "%?Rr<%Sx(Time:) %Rh:%Rn:%Rs|%?St(prerecording time)<%pm|%Sx(Prerecord Time) %Rs>>\n"
+        "%?Rr<%Sx(Time:) %Rh:%Rn:%Rs|%?St(prerecording time)<%pm|%Sx(Prerecord Time) %Rs>>\n"
 #endif
-                                    "%pb\n"
+        "%pb\n"
 #ifdef HAVE_RDS_CAP
-                                    "\n%s%ty\n"
-                                    "%s%tz\n"
+        "\n%s%ty\n"
+        "%s%tz\n"
 #endif
-                                    ;
-        skin_data_load(screen, data, default_fms, false);
-    }
+        ;
+    return default_fms;
 }
+
 void fms_fix_displays(enum fms_exiting toggle_state)
 {
     int i;
     FOR_NB_SCREENS(i)
     {
+        struct wps_data *data = skin_get_gwps(FM_SCREEN, i)->data;
         if (toggle_state == FMS_ENTER)
         {
-            viewportmanager_theme_enable(i, skin_has_sbs(i, fms_skin[i].data), NULL);  
+            viewportmanager_theme_enable(i, skin_has_sbs(i, data), NULL);  
 #if LCD_DEPTH > 1 || defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1
-            screens[i].backdrop_show(fms_skin[i].data->backdrop);
+            screens[i].backdrop_show(data->backdrop);
 #endif
             screens[i].clear_display();
             /* force statusbar/skin update since we just cleared the whole screen */
@@ -83,44 +75,27 @@ void fms_fix_displays(enum fms_exiting toggle_state)
 #if LCD_DEPTH > 1 || defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1
             screens[i].backdrop_show(sb_get_backdrop(i));
 #endif
-            viewportmanager_theme_undo(i, skin_has_sbs(i, fms_skin[i].data));
+            viewportmanager_theme_undo(i, skin_has_sbs(i, data));
         }
     }
 #ifdef HAVE_TOUCHSCREEN
-    if (!fms_skin[SCREEN_MAIN].data->touchregions)
+    if (i==SCREEN_MAIN && !data->touchregions)
         touchscreen_set_mode(toggle_state == FMS_ENTER ? 
                               TOUCHSCREEN_BUTTON : global_settings.touch_mode);
 #endif
 }
         
 
-void fms_skin_init(void)
-{
-    int i;
-    FOR_NB_SCREENS(i)
-    {
-#ifdef HAVE_ALBUMART
-        fms_skin_data[i].albumart = NULL;
-        fms_skin_data[i].playback_aa_slot = -1;
-#endif
-        fms_skin[i].data = &fms_skin_data[i];
-        fms_skin[i].display = &screens[i];
-        /* Currently no seperate wps_state needed/possible
-           so use the only available ( "global" ) one */
-        fms_skin[i].state = &wps_state;
-        fms_skin[i].sync_data = &fms_skin_sync_data;
-    }
-}
-
 int fms_do_button_loop(bool update_screen)
 {
-    int button = skin_wait_for_action(fms_skin, CONTEXT_FM, 
+    int button = skin_wait_for_action(FM_SCREEN, CONTEXT_FM, 
                                       update_screen ? TIMEOUT_NOBLOCK : HZ/5);
 #ifdef HAVE_TOUCHSCREEN
     struct touchregion *region;
     int offset;
     if (button == ACTION_TOUCHSCREEN)
-        button = skin_get_touchaction(&fms_skin_data[SCREEN_MAIN], &offset, &region);
+        button = skin_get_touchaction(skin_get_gwps(FM_SCREEN, SCREEN_MAIN)->data,
+                                      &offset, &region)
     switch (button)
     {
         case ACTION_WPS_STOP:
@@ -152,5 +127,5 @@ int fms_do_button_loop(bool update_screen)
 
 struct gui_wps *fms_get(enum screen_type screen)
 {
-    return &fms_skin[screen];
+    return skin_get_gwps(FM_SCREEN, screen);
 }
diff --git a/tools/buildzip.pl b/tools/buildzip.pl
index e0b0bbb..e299d7c 100755
--- a/tools/buildzip.pl
+++ b/tools/buildzip.pl
@@ -305,6 +305,47 @@ sub filesize {
     return $size;
 }
 
+sub create_failsafefiles {
+    my ($dir) = @_;
+    my $text = "# Dummy file to allow Rockbox to reset to the default skin config.
+# Do not edit this file.  It's never actually loaded by Rockbox.";
+    open (FOO, ">$dir/wps/rockbox_failsafe.wps");
+    print FOO $text;
+    close(FOO);
+    open (FOO, ">$dir/wps/rockbox_failsafe.rwps");
+    print FOO $text;
+    close(FOO);
+    open (FOO, ">$dir/wps/rockbox_failsafe.sbs");
+    print FOO $text;
+    close(FOO);
+    open (FOO, ">$dir/wps/rockbox_failsafe.rsbs");
+    print FOO $text;
+    close(FOO);
+    open (FOO, ">$dir/wps/rockbox_failsafe.fms");
+    print FOO $text;
+    close(FOO);
+    open (FOO, ">$dir/wps/rockbox_failsafe.rfms");
+    print FOO $text;
+    close(FOO);
+    open (FOO, ">$dir/themes/rockbox_failsafe.cfg");
+    print FOO <<STOP
+# This config has been autogenerated to reload the failsafe setup
+wps: $dir/wps/rockbox_failsafe.wps
+rwps: $dir/wps/rockbox_failsafe.rwps
+sbs: $dir/wps/rockbox_failsafe.sbs
+rsbs: $dir/wps/rockbox_failsafe.rsbs
+fms: $dir/wps/rockbox_failsafe.fms
+rfms: $dir/wps/rockbox_failsafe.rfms
+statusbar: top
+font: 08-Schumacher-Clean.fnt
+foreground color: 000000
+background color: B6C6E5
+selector type: bar (inverse)
+STOP
+;
+    close(FOO);
+}
+
 sub buildzip {
     my ($image, $fonts)=@_;    
     my $libdir = $install;
@@ -508,6 +549,7 @@ STOP
              "$temp_dir/rocks/demos/pictureflow_splash.bmp");
 
     }
+    create_failsafefiles($temp_dir);
 
     if($image) {
         # image is blank when this is a simulator
@@ -572,7 +614,6 @@ STOP
     } else {
         copy("$ROOT/wps/classic_statusbar.112x64x1.sbs", "$temp_dir/wps/classic_statusbar.sbs");
     }
-    system("touch $temp_dir/wps/rockbox_none.sbs");
     if ($remote_depth != $depth) {
 		copy("$ROOT/wps/classic_statusbar.mono.sbs", "$temp_dir/wps/classic_statusbar.rsbs");
 	} else {
diff --git a/wps/WPSLIST b/wps/WPSLIST
index e382368..362df12 100644
--- a/wps/WPSLIST
+++ b/wps/WPSLIST
@@ -42,23 +42,6 @@ selector type: bar (inverse)
 </wps>
 
 <wps>
-Name: rockbox_default.wps
-RWPS: rockbox_default.rwps
-SBS:
-RSBS:
-Author: Rockbox team
-Font: 08-Schumacher-Clean.fnt
-Font.11x2x1:
-Statusbar: on
-Foreground Color: 000000
-Background Color: B6C6E5
-backdrop:
-iconset:
-viewers iconset:
-selector type: bar (inverse)
-</wps>
-
-<wps>
 Name: boxes.wps
 rwps: boxes.rwps
 SBS:
