diff --git a/apps/gui/skin_engine/skin_parser.c b/apps/gui/skin_engine/skin_parser.c
index ed475ac..723c322 100644
--- a/apps/gui/skin_engine/skin_parser.c
+++ b/apps/gui/skin_engine/skin_parser.c
@@ -575,6 +575,108 @@ static int parse_timeout_tag(struct skin_element *element,
     return 0;
 }
 
+/* traverse the image linked-list for an image */
+static struct skin_setting* find_skinsetting(const char *name, struct wps_data *data)
+{
+    struct skin_token_list *list = data->skin_settings;
+    while (list)
+    {
+        struct skin_setting *setting = (struct skin_setting *)list->token->value.data;
+        if (!strcmp(setting->name, name))
+            return setting;
+        list = list->next;
+    }
+    return NULL;
+}
+static int parse_skin_setting_load_tag(struct skin_element *element,
+                                       struct wps_token *token,
+                                       struct wps_data *wps_data)
+{
+    int i;
+    char* defaultval;
+    struct skin_setting *setting = 
+        (struct skin_setting*)skin_buffer_alloc(sizeof(struct skin_setting));
+    if (!wps_data->skin_setting_dict)
+    {
+        wps_data->skin_setting_dict = 
+                        skin_buffer_alloc(sizeof(*wps_data->skin_setting_dict));
+        wps_data->skin_setting_dict->count = 0;
+    }
+    if (!setting || !wps_data->skin_setting_dict)
+        return -1;
+    /* TODO: special case for on/off yes/no */
+    
+    setting->count = 0;
+    setting->name = element->params[0].data.text;
+    defaultval = element->params[1].data.text;
+    i = 2;
+    while (i<element->params_count)
+    {
+        char* val = element->params[i].data.text;
+        setting->values[setting->count] = val;
+        if (!strcmp(defaultval, val))
+            setting->defaultval = setting->count;
+        setting->count++;
+        i++;
+    }
+    
+    struct skin_token_list *item = 
+            (struct skin_token_list *)new_skin_token_list_item(token, setting);
+    if (!item)
+        return WPS_ERROR_INVALID_PARAM;
+    add_to_ll_chain(&wps_data->skin_settings, item);
+    
+    return 0;
+}
+static int parse_skin_setting_tag(struct skin_element *element,
+                                  struct wps_token *token,
+                                  struct wps_data *wps_data)
+{
+    char* name = element->params[0].data.text;
+    struct skin_setting *setting = find_skinsetting(name, wps_data);
+    if (!setting)
+        return -1;
+    token->value.data = setting;
+    return 0;
+}
+
+static bool load_skin_settings(struct wps_data *wps_data)
+{
+    int fd;
+    char line[128];
+    char* name;
+    char* value;
+    int i;
+    struct skin_setting_dictionary *dict = wps_data->skin_setting_dict;
+
+    fd = open_utf8(SKIN_SETTINGS_FILE, O_RDONLY);
+    if (fd < 0)
+        return false;
+
+    while (read_line(fd, line, sizeof line) > 0)
+    {
+        if (!settings_parseline(line, &name, &value))
+            continue; 
+        for(i=0; i<dict->count && i<MAX_SKIN_SETTINGS ; i++)
+        {
+            if (!strcmp(name, dict->vals[i].name))
+            {
+                strcpy(dict->vals[i].value, value);
+                break;
+            }
+        }
+        if (i>=dict->count && i<MAX_SKIN_SETTINGS)
+        {
+            strcpy(dict->vals[i].name, name);
+            strcpy(dict->vals[i].value, value);
+            dict->count++;
+        }
+    }
+    close(fd);
+    return true;
+}
+            
+
 static int parse_progressbar_tag(struct skin_element* element,
                                  struct wps_token *token,
                                  struct wps_data *wps_data)
@@ -1465,6 +1567,12 @@ static int skin_element_callback(struct skin_element* element, void* data)
                     function = parse_albumart_load;
                     break;
 #endif
+                case SKIN_TOKEN_SKIN_SETTING_LOAD:
+                    function = parse_skin_setting_load_tag;
+                    break;
+                case SKIN_TOKEN_SKIN_SETTING:
+                    function = parse_skin_setting_tag;
+                    break;
                 default:
                     break;
             }
@@ -1614,6 +1722,9 @@ bool skin_data_load(enum screen_type screen, struct wps_data *wps_data,
         skin_buffer_restore_position();
         return false;
     }
+    
+    if (wps_data->skin_setting_dict)
+        load_skin_settings(wps_data);
 
 #ifdef HAVE_LCD_BITMAP
     char bmpdir[MAX_PATH];
diff --git a/apps/gui/skin_engine/skin_tokens.c b/apps/gui/skin_engine/skin_tokens.c
index 0af2e9d..d29eee5 100644
--- a/apps/gui/skin_engine/skin_tokens.c
+++ b/apps/gui/skin_engine/skin_tokens.c
@@ -1447,6 +1447,37 @@ const char *get_token_value(struct gui_wps *gwps,
             cfg_to_string(token->value.i,buf,buf_size);
             return buf;
         }
+        case SKIN_TOKEN_SKIN_SETTING:
+        {
+            struct skin_setting *setting = (struct skin_setting *)token->value.data;
+            struct skin_setting_dictionary *dict = data->skin_setting_dict;
+            int i, val = setting->defaultval;
+            char* value = setting->values[val], *usersval = NULL;
+            for(i=0; i<dict->count; i++)
+            {
+                if (!strcmp(dict->vals[i].name, setting->name))
+                {
+                    usersval = dict->vals[i].value;
+                    break;
+                }
+            }
+            if (i < dict->count)
+            {
+                for(i=0; i<setting->count; i++)
+                {
+                    if (!strcmp(setting->values[i], usersval))
+                    {
+                        val = i;
+                        break;
+                    }
+                }
+            }
+            if (intval)
+                *intval = val;
+            value = setting->values[val];
+            return value;
+        }
+        
         case SKIN_TOKEN_HAVE_TUNER:
 #if CONFIG_TUNER
             if (radio_hardware_present())
diff --git a/apps/gui/skin_engine/wps_internals.h b/apps/gui/skin_engine/wps_internals.h
index 24edde7..44632cb 100644
--- a/apps/gui/skin_engine/wps_internals.h
+++ b/apps/gui/skin_engine/wps_internals.h
@@ -254,6 +254,22 @@ struct logical_if {
     int num_options;
 };
 
+#define MAX_SKIN_SETTINGS 32
+#define MAX_SETTING_LEN 12
+struct skin_setting {
+    int count; /* number of possible options */
+    char *name;
+    int defaultval;
+    char *values[MAX_SKIN_SETTINGS];
+};
+struct skin_setting_dictionary {
+    int count;
+    struct {
+        char name[MAX_SETTING_LEN];
+        char value[MAX_SETTING_LEN];
+    } vals[MAX_SKIN_SETTINGS];
+};
+
 /* wps_data
    this struct holds all necessary data which describes the
    viewable content of a wps */
@@ -277,6 +293,8 @@ struct wps_data
     struct skin_albumart *albumart;
     int    playback_aa_slot;
 #endif
+    struct skin_token_list *skin_settings;
+    struct skin_setting_dictionary *skin_setting_dict;
 
 #ifdef HAVE_LCD_BITMAP
     bool peak_meter_enabled;
diff --git a/firmware/export/rbpaths.h b/firmware/export/rbpaths.h
index cd87888..efc7e16 100644
--- a/firmware/export/rbpaths.h
+++ b/firmware/export/rbpaths.h
@@ -108,6 +108,7 @@ extern const char* get_user_file_path(const char *path,
 
 #define WPS_DIR             ROCKBOX_DIR "/wps"
 #define SBS_DIR             WPS_DIR
+#define SKIN_SETTINGS_FILE  WPS_DIR "/skinsettings.txt"
 #define THEME_DIR           ROCKBOX_DIR "/themes"
 #define FONT_DIR            ROCKBOX_DIR "/fonts"
 #define ICON_DIR            ROCKBOX_DIR "/icons"
diff --git a/lib/skin_parser/tag_table.c b/lib/skin_parser/tag_table.c
index 8b31ada..e21512d 100644
--- a/lib/skin_parser/tag_table.c
+++ b/lib/skin_parser/tag_table.c
@@ -193,6 +193,8 @@ static const struct tag_info legal_tags[] =
     
     { SKIN_TOKEN_IMAGE_BACKDROP,        "X"  , "f", SKIN_REFRESH_STATIC|NOBREAK },
     
+    { SKIN_TOKEN_SKIN_SETTING_LOAD,     "Sl" , "SS|N", SKIN_REFRESH_STATIC },
+    { SKIN_TOKEN_SKIN_SETTING,          "Sv" , "S", SKIN_REFRESH_STATIC },
     { SKIN_TOKEN_SETTING,               "St" , "S", SKIN_REFRESH_DYNAMIC },
     { SKIN_TOKEN_TRANSLATEDSTRING,      "Sx" , "S", SKIN_REFRESH_STATIC },
     { SKIN_TOKEN_LANG_IS_RTL,           "Sr" , "", SKIN_REFRESH_STATIC },
diff --git a/lib/skin_parser/tag_table.h b/lib/skin_parser/tag_table.h
index f16709d..4f839fe 100644
--- a/lib/skin_parser/tag_table.h
+++ b/lib/skin_parser/tag_table.h
@@ -224,6 +224,8 @@ enum skin_token_type {
     SKIN_TOKEN_REMOTE_HOLD,
 
     /* Setting option */
+    SKIN_TOKEN_SKIN_SETTING_LOAD,
+    SKIN_TOKEN_SKIN_SETTING,
     SKIN_TOKEN_SETTING,
     SKIN_TOKEN_CURRENT_SCREEN,
     SKIN_TOKEN_LANG_IS_RTL,
