summaryrefslogtreecommitdiffstats
path: root/apps/gui/skin_engine/skin_engine.c
diff options
context:
space:
mode:
authorJonathan Gordon <rockbox@jdgordon.info>2011-11-21 10:02:23 +0000
committerJonathan Gordon <rockbox@jdgordon.info>2011-11-21 10:02:23 +0000
commit0ca4b38b1b04e6b7d6f5ad1f3654f8f361d8933f (patch)
treec17fc93ca3814537e12521c4bebfb560739c8ea9 /apps/gui/skin_engine/skin_engine.c
parent814ffffdbe5a5ea420ddc6475512a75cba7a8583 (diff)
downloadrockbox-0ca4b38b1b04e6b7d6f5ad1f3654f8f361d8933f.tar.gz
rockbox-0ca4b38b1b04e6b7d6f5ad1f3654f8f361d8933f.zip
skinengine: Rework skin loading so skins can be un/loaded individually. This also means that loading a .cfg which doesnt change themes shouldnt have them reloaded
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@31037 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/gui/skin_engine/skin_engine.c')
-rw-r--r--apps/gui/skin_engine/skin_engine.c245
1 files changed, 133 insertions, 112 deletions
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;
}