diff options
-rw-r--r-- | apps/gui/skin_engine/skin_backdrops.c | 56 | ||||
-rw-r--r-- | apps/gui/skin_engine/skin_engine.c | 245 | ||||
-rw-r--r-- | apps/gui/skin_engine/skin_parser.c | 4 | ||||
-rw-r--r-- | apps/gui/statusbar-skinned.c | 5 | ||||
-rw-r--r-- | apps/main.c | 2 | ||||
-rw-r--r-- | apps/settings.h | 1 | ||||
-rw-r--r-- | apps/settings_list.c | 2 |
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 |