summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/gui/skin_engine/skin_backdrops.c56
-rw-r--r--apps/gui/skin_engine/skin_engine.c245
-rw-r--r--apps/gui/skin_engine/skin_parser.c4
-rw-r--r--apps/gui/statusbar-skinned.c5
-rw-r--r--apps/main.c2
-rw-r--r--apps/settings.h1
-rw-r--r--apps/settings_list.c2
7 files changed, 175 insertions, 140 deletions
diff --git a/apps/gui/skin_engine/skin_backdrops.c b/apps/gui/skin_engine/skin_backdrops.c
index 0b67125bbf..0433d0258d 100644
--- a/apps/gui/skin_engine/skin_backdrops.c
+++ b/apps/gui/skin_engine/skin_backdrops.c
@@ -37,6 +37,7 @@ static struct skin_backdrop {
enum screen_type screen;
bool loaded;
int buflib_handle;
+ int ref_count;
} backdrops[NB_BDROPS];
#define NB_BDROPS SKINNABLE_SCREENS_COUNT*NB_SCREENS
@@ -63,21 +64,21 @@ static struct buflib_callbacks buflib_ops = {buflib_move_callback, NULL};
static bool first_go = true;
void skin_backdrop_init(void)
{
- for (int i=0; i<NB_BDROPS; i++)
+ if (first_go)
{
- if (first_go)
+ for (int i=0; i<NB_BDROPS; i++)
+ {
backdrops[i].buflib_handle = -1;
- else
- skin_backdrop_unload(i);
- backdrops[i].name[0] = '\0';
- backdrops[i].buffer = NULL;
- backdrops[i].loaded = false;
-
+ backdrops[i].name[0] = '\0';
+ backdrops[i].buffer = NULL;
+ backdrops[i].loaded = false;
+ backdrops[i].ref_count = 0;
+ }
+ FOR_NB_SCREENS(i)
+ current_lcd_backdrop[i] = -1;
+ handle_being_loaded = -1;
+ first_go = false;
}
- first_go = false;
- FOR_NB_SCREENS(i)
- current_lcd_backdrop[i] = -1;
- handle_being_loaded = -1;
}
int skin_backdrop_assign(char* backdrop, char *bmpdir,
@@ -101,22 +102,26 @@ int skin_backdrop_assign(char* backdrop, char *bmpdir,
for (i=0; i<NB_BDROPS; i++)
{
if (!backdrops[i].name[0] && free < 0)
+ {
free = i;
- if (!strcmp(backdrops[i].name, filename) && backdrops[i].screen == screen)
+ break;
+ }
+ else if (!strcmp(backdrops[i].name, filename) && backdrops[i].screen == screen)
{
+ backdrops[i].ref_count++;
break;
}
}
- if (i < NB_BDROPS)
- return i;
- else if (free >= 0)
+ if (free >= 0)
{
- strlcpy(backdrops[free].name, filename,
- sizeof (backdrops[free].name));
+ strlcpy(backdrops[free].name, filename, MAX_PATH);
backdrops[free].buffer = NULL;
backdrops[free].screen = screen;
+ backdrops[free].ref_count = 1;
return free;
}
+ else if (i < NB_BDROPS)
+ return i;
return -1;
}
@@ -188,10 +193,17 @@ void skin_backdrop_show(int backdrop_id)
void skin_backdrop_unload(int backdrop_id)
{
- if (backdrops[backdrop_id].buflib_handle > 0)
- core_free(backdrops[backdrop_id].buflib_handle);
- backdrops[backdrop_id].buffer = NULL;
- backdrops[backdrop_id].buflib_handle = -1;
+ backdrops[backdrop_id].ref_count--;
+ if (backdrops[backdrop_id].ref_count <= 0)
+ {
+ if (backdrops[backdrop_id].buflib_handle > 0)
+ core_free(backdrops[backdrop_id].buflib_handle);
+ backdrops[backdrop_id].buffer = NULL;
+ backdrops[backdrop_id].buflib_handle = -1;
+ backdrops[backdrop_id].loaded = false;
+ backdrops[backdrop_id].name[0] = '\0';
+ backdrops[backdrop_id].ref_count = 0;
+ }
}
void skin_backdrop_load_setting(void)
diff --git a/apps/gui/skin_engine/skin_engine.c b/apps/gui/skin_engine/skin_engine.c
index c6791cac09..ce6c985e16 100644
--- a/apps/gui/skin_engine/skin_engine.c
+++ b/apps/gui/skin_engine/skin_engine.c
@@ -38,18 +38,15 @@
#include "skin_buffer.h"
#include "statusbar-skinned.h"
-static bool skins_initialising = true;
-
-/* App uses the host malloc to manage the buffer */
-void theme_init_buffer(void)
-{
- skins_initialising = false;
-}
+#define FAILSAFENAME "rockbox_failsafe"
void skin_data_free_buflib_allocs(struct wps_data *wps_data);
char* wps_default_skin(enum screen_type screen);
char* default_radio_skin(enum screen_type screen);
+static char* get_skin_filename(char *buf, size_t buf_size,
+ enum skinnable_screens skin, enum screen_type screen);
+
struct wps_state wps_state = { .id3 = NULL };
static struct gui_skin_helper {
int (*preproccess)(enum screen_type screen, struct wps_data *data);
@@ -62,82 +59,110 @@ static struct gui_skin_helper {
[FM_SCREEN] = { NULL, NULL, default_radio_skin }
#endif
};
-
+
static struct gui_skin {
+ char filename[MAX_PATH];
struct gui_wps gui_wps;
struct wps_data data;
char *buffer_start;
size_t buffer_usage;
-
+ bool failsafe_loaded;
+
bool needs_full_update;
} skins[SKINNABLE_SCREENS_COUNT][NB_SCREENS];
-void gui_sync_skin_init(void)
+void gui_skin_reset(struct gui_skin *skin)
{
- int 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;
- skins[j][i].gui_wps.data = &skins[j][i].data;
- 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.buflib_handle = -1;
- skins[j][i].data.tree = -1;
+ skin->filename[0] = '\0';
+ skin->buffer_start = NULL;
+ skin->failsafe_loaded = false;
+ skin->needs_full_update = true;
+ skin->gui_wps.data = &skin->data;
+ memset(skin->gui_wps.data, 0, sizeof(struct wps_data));
+ skin->data.wps_loaded = false;
+ skin->data.buflib_handle = -1;
+ skin->data.tree = -1;
#ifdef HAVE_TOUCHSCREEN
- skins[j][i].data.touchregions = -1;
+ skin->data.touchregions = -1;
#endif
#ifdef HAVE_SKIN_VARIABLES
- skins[j][i].data.skinvars = -1;
+ skin->data.skinvars = -1;
#endif
#ifdef HAVE_LCD_BITMAP
- skins[j][i].data.font_ids = -1;
- skins[j][i].data.images = -1;
+ skin->data.font_ids = -1;
+ skin->data.images = -1;
#endif
#ifdef HAVE_ALBUMART
- skins[j][i].data.albumart = -1;
- skins[j][i].data.playback_aa_slot = -1;
+ skin->data.albumart = -1;
+ skin->data.playback_aa_slot = -1;
+#endif
+#ifdef HAVE_BACKDROP_IMAGE
+ skin->gui_wps.data->backdrop_id = -1;
#endif
- }
- }
}
-void skin_unload_all(void)
+void gui_sync_skin_init(void)
{
int j;
-
for(j=0; j<SKINNABLE_SCREENS_COUNT; j++)
{
FOR_NB_SCREENS(i)
+ {
skin_data_free_buflib_allocs(&skins[j][i].data);
+ gui_skin_reset(&skins[j][i]);
+ skins[j][i].gui_wps.display = &screens[i];
+ }
}
+}
-#ifdef HAVE_LCD_BITMAP
- skin_backdrop_init();
-#endif
+void skin_unload_all(void)
+{
gui_sync_skin_init();
}
void settings_apply_skins(void)
{
int i;
+ char filename[MAX_PATH];
+ static bool first_run = true;
- skin_unload_all();
+#ifdef HAVE_LCD_BITMAP
+ skin_backdrop_init();
+#endif
/* Make sure each skin is loaded */
for (i=0; i<SKINNABLE_SCREENS_COUNT; i++)
{
FOR_NB_SCREENS(j)
- skin_get_gwps(i, j);
- }
+ {
+ bool load = false;
+ get_skin_filename(filename, MAX_PATH, i,j);
+
+ if (filename[0] && (strcmp(filename, skins[i][j].filename) || skins[i][j].failsafe_loaded))
+ load = true;
+ else if (first_run || (!filename[0] && !skins[i][j].failsafe_loaded))
+ load = true;
+
+ if (load)
+ {
+ if (!first_run)
+ {
+ skin_data_free_buflib_allocs(&skins[i][j].data);
#ifdef HAVE_BACKDROP_IMAGE
- skin_backdrops_preload(); /* should maybe check the retval here... */
+ if (skins[i][j].data.backdrop_id >= 0)
+ skin_backdrop_unload(skins[i][j].data.backdrop_id);
#endif
+ }
+ gui_skin_reset(&skins[i][j]);
+ skins[i][j].gui_wps.display = &screens[j];
+ skin_get_gwps(i, j);
+ }
+ }
+ }
+ first_run = false;
viewportmanager_theme_changed(THEME_STATUSBAR);
#ifdef HAVE_BACKDROP_IMAGE
+ skin_backdrops_preload(); /* should maybe check the retval here... */
FOR_NB_SCREENS(i)
skin_backdrop_show(sb_get_backdrop(i));
#endif
@@ -147,104 +172,100 @@ 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)
+ strcpy(skins[skin][screen].filename, buf);
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].failsafe_loaded = loaded;
+ }
+
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)
+static char* get_skin_filename(char *buf, size_t buf_size,
+ enum skinnable_screens skin, enum screen_type screen)
{
- if (!loading_a_sbs && skins[skin][screen].data.wps_loaded == false)
+ (void)screen;
+ char *setting = NULL, *ext = NULL;
+ switch (skin)
{
- char buf[MAX_PATH*2];
- char *setting = NULL, *ext = NULL;
- switch (skin)
- {
- case CUSTOM_STATUSBAR:
-#ifdef HAVE_LCD_BITMAP
- if (skins_initialising)
- {
- /* 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;
+ case CUSTOM_STATUSBAR:
#if defined(HAVE_REMOTE_LCD) && NB_SCREENS > 1
- if (screen == SCREEN_REMOTE)
- {
- setting = global_settings.rsbs_file;
- ext = "rsbs";
- }
- else
+ if (screen == SCREEN_REMOTE)
+ {
+ setting = global_settings.rsbs_file;
+ ext = "rsbs";
+ }
+ else
#endif
- {
- setting = global_settings.sbs_file;
- ext = "sbs";
- }
-#else
- return &skins[skin][screen].gui_wps;
-#endif /* HAVE_LCD_BITMAP */
- break;
- case WPS:
+ {
+ 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
+ if (screen == SCREEN_REMOTE)
+ {
+ setting = global_settings.rwps_file;
+ ext = "rwps";
+ }
+ else
#endif
- {
- setting = global_settings.wps_file;
- ext = "wps";
- }
- break;
+ {
+ setting = global_settings.wps_file;
+ ext = "wps";
+ }
+ break;
#if CONFIG_TUNER
- case FM_SCREEN:
+ case FM_SCREEN:
#if defined(HAVE_REMOTE_LCD) && NB_SCREENS > 1
- if (screen == SCREEN_REMOTE)
- {
- setting = global_settings.rfms_file;
- ext = "rfms";
- }
- else
+ if (screen == SCREEN_REMOTE)
+ {
+ setting = global_settings.rfms_file;
+ ext = "rfms";
+ }
+ else
#endif
- {
- setting = global_settings.fms_file;
- ext = "fms";
- }
- break;
+ {
+ 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, WPS_DIR "/%s.%s", setting, ext);
- }
+ default:
+ return NULL;
+ }
+
+ buf[0] = '\0'; /* force it to reload the default */
+ if (strcmp(setting, FAILSAFENAME) && strcmp(setting, "-"))
+ {
+ snprintf(buf, buf_size, WPS_DIR "/%s.%s", setting, ext);
+ }
+ return buf;
+}
+
+struct gui_wps *skin_get_gwps(enum skinnable_screens skin, enum screen_type screen)
+{
+ if (skins[skin][screen].data.wps_loaded == false)
+ {
+ char filename[MAX_PATH];
+ char *buf = get_skin_filename(filename, MAX_PATH, skin, screen);
cpu_boost(true);
+ skins[skin][screen].filename[0] = '\0';
skin_load(skin, screen, buf, true);
cpu_boost(false);
- loading_a_sbs = false;
}
return &skins[skin][screen].gui_wps;
}
diff --git a/apps/gui/skin_engine/skin_parser.c b/apps/gui/skin_engine/skin_parser.c
index ef365720b4..0118977be5 100644
--- a/apps/gui/skin_engine/skin_parser.c
+++ b/apps/gui/skin_engine/skin_parser.c
@@ -1687,7 +1687,7 @@ static bool load_skin_bitmaps(struct wps_data *wps_data, char *bmpdir)
list = SKINOFFSETTOPTR(skin_buffer, list->next);
}
-#if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1))
+#ifdef HAVE_BACKDROP_IMAGE
wps_data->backdrop_id = skin_backdrop_assign(backdrop_filename, bmpdir, curr_screen);
#endif /* has backdrop support */
return retval;
@@ -1986,7 +1986,7 @@ static int skin_element_callback(struct skin_element* element, void* data)
case SKIN_TOKEN_FILE_DIRECTORY:
token->value.i = get_param(element, 0)->data.number;
break;
-#if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1))
+#ifdef HAVE_BACKDROP_IMAGE
case SKIN_TOKEN_VIEWPORT_FGCOLOUR:
case SKIN_TOKEN_VIEWPORT_BGCOLOUR:
function = parse_viewportcolour;
diff --git a/apps/gui/statusbar-skinned.c b/apps/gui/statusbar-skinned.c
index 960cf67d4d..fc9735da21 100644
--- a/apps/gui/statusbar-skinned.c
+++ b/apps/gui/statusbar-skinned.c
@@ -50,6 +50,7 @@ static int update_delay = DEFAULT_UPDATE_DELAY;
static bool sbs_has_title[NB_SCREENS];
static char* sbs_title[NB_SCREENS];
static enum themable_icons sbs_icon[NB_SCREENS];
+static bool sbs_loaded[NB_SCREENS] = { false };
bool sb_set_title_text(char* title, enum themable_icons icon, enum screen_type screen)
{
@@ -76,6 +77,7 @@ enum themable_icons sb_get_icon(enum screen_type screen)
int sb_preproccess(enum screen_type screen, struct wps_data *data)
{
(void)data;
+ sbs_loaded[screen] = false;
sbs_has_title[screen] = false;
viewportmanager_theme_enable(screen, false, NULL);
return 1;
@@ -101,6 +103,7 @@ int sb_postproccess(enum screen_type screen, struct wps_data *data)
vp->hidden_flags = VP_NEVER_VISIBLE;
}
sb_set_info_vp(screen, VP_DEFAULT_LABEL);
+ sbs_loaded[screen] = true;
}
viewportmanager_theme_undo(screen, false);
return 1;
@@ -115,6 +118,8 @@ void sb_set_info_vp(enum screen_type screen, OFFSETTYPE(char*) label)
struct viewport *sb_skin_get_info_vp(enum screen_type screen)
{
+ if (sbs_loaded[screen] == false)
+ return NULL;
struct wps_data *data = skin_get_gwps(CUSTOM_STATUSBAR, screen)->data;
struct skin_viewport *vp = NULL;
char *label;
diff --git a/apps/main.c b/apps/main.c
index 50da787b17..5715057ee2 100644
--- a/apps/main.c
+++ b/apps/main.c
@@ -393,7 +393,6 @@ static void init(void)
tree_mem_init();
filetype_init();
playlist_init();
- theme_init_buffer();
shortcuts_init();
#if CONFIG_CODEC != SWCODEC
@@ -678,7 +677,6 @@ static void init(void)
tree_mem_init();
filetype_init();
scrobbler_init();
- theme_init_buffer();
shortcuts_init();
#if CONFIG_CODEC != SWCODEC
diff --git a/apps/settings.h b/apps/settings.h
index 34d65416dd..2524dcc909 100644
--- a/apps/settings.h
+++ b/apps/settings.h
@@ -222,7 +222,6 @@ void sound_settings_apply(void);
* skin buffer is reset properly
*/
void settings_apply_skins(void);
-void theme_init_buffer(void);
void settings_apply(bool read_disk);
void settings_apply_pm_range(void);
diff --git a/apps/settings_list.c b/apps/settings_list.c
index dbf0f41952..31721d6840 100644
--- a/apps/settings_list.c
+++ b/apps/settings_list.c
@@ -203,7 +203,7 @@ static const char graphic_numeric[] = "graphic,numeric";
/* Default theme settings */
#define DEFAULT_WPSNAME "cabbiev2"
#define DEFAULT_SBSNAME "-"
-#define DEFAULT_FMS_NAME DEFAULT_WPSNAME
+#define DEFAULT_FMS_NAME "-"
#ifdef HAVE_LCD_BITMAP