From 0ca4b38b1b04e6b7d6f5ad1f3654f8f361d8933f Mon Sep 17 00:00:00 2001 From: Jonathan Gordon Date: Mon, 21 Nov 2011 10:02:23 +0000 Subject: 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 --- apps/gui/skin_engine/skin_engine.c | 245 ++++++++++++++++++++----------------- 1 file changed, 133 insertions(+), 112 deletions(-) (limited to 'apps/gui/skin_engine/skin_engine.c') 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; jfilename[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= 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; } -- cgit v1.2.3