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
This commit is contained in:
parent
814ffffdbe
commit
0ca4b38b1b
7 changed files with 188 additions and 153 deletions
|
@ -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)
|
||||
{
|
||||
free = i;
|
||||
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)
|
||||
|
|
|
@ -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,17 +59,49 @@ 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_skin_reset(struct gui_skin *skin)
|
||||
{
|
||||
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
|
||||
skin->data.touchregions = -1;
|
||||
#endif
|
||||
#ifdef HAVE_SKIN_VARIABLES
|
||||
skin->data.skinvars = -1;
|
||||
#endif
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
skin->data.font_ids = -1;
|
||||
skin->data.images = -1;
|
||||
#endif
|
||||
#ifdef HAVE_ALBUMART
|
||||
skin->data.albumart = -1;
|
||||
skin->data.playback_aa_slot = -1;
|
||||
#endif
|
||||
#ifdef HAVE_BACKDROP_IMAGE
|
||||
skin->gui_wps.data->backdrop_id = -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
void gui_sync_skin_init(void)
|
||||
{
|
||||
int j;
|
||||
|
@ -80,64 +109,60 @@ void gui_sync_skin_init(void)
|
|||
{
|
||||
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;
|
||||
skin_data_free_buflib_allocs(&skins[j][i].data);
|
||||
gui_skin_reset(&skins[j][i]);
|
||||
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;
|
||||
#ifdef HAVE_TOUCHSCREEN
|
||||
skins[j][i].data.touchregions = -1;
|
||||
#endif
|
||||
#ifdef HAVE_SKIN_VARIABLES
|
||||
skins[j][i].data.skinvars = -1;
|
||||
#endif
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
skins[j][i].data.font_ids = -1;
|
||||
skins[j][i].data.images = -1;
|
||||
#endif
|
||||
#ifdef HAVE_ALBUMART
|
||||
skins[j][i].data.albumart = -1;
|
||||
skins[j][i].data.playback_aa_slot = -1;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void skin_unload_all(void)
|
||||
{
|
||||
int j;
|
||||
|
||||
for(j=0; j<SKINNABLE_SCREENS_COUNT; j++)
|
||||
{
|
||||
FOR_NB_SCREENS(i)
|
||||
skin_data_free_buflib_allocs(&skins[j][i].data);
|
||||
}
|
||||
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
skin_backdrop_init();
|
||||
#endif
|
||||
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;
|
||||
static char* get_skin_filename(char *buf, size_t buf_size,
|
||||
enum skinnable_screens skin, enum screen_type screen)
|
||||
{
|
||||
(void)screen;
|
||||
char *setting = NULL, *ext = NULL;
|
||||
switch (skin)
|
||||
{
|
||||
case CUSTOM_STATUSBAR:
|
||||
#if defined(HAVE_REMOTE_LCD) && NB_SCREENS > 1
|
||||
if (screen == SCREEN_REMOTE)
|
||||
{
|
||||
setting = global_settings.rsbs_file;
|
||||
ext = "rsbs";
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
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
|
||||
#endif
|
||||
{
|
||||
setting = global_settings.wps_file;
|
||||
ext = "wps";
|
||||
}
|
||||
break;
|
||||
#if CONFIG_TUNER
|
||||
case FM_SCREEN:
|
||||
#if defined(HAVE_REMOTE_LCD) && NB_SCREENS > 1
|
||||
if (screen == SCREEN_REMOTE)
|
||||
{
|
||||
setting = global_settings.rfms_file;
|
||||
ext = "rfms";
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
setting = global_settings.fms_file;
|
||||
ext = "fms";
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
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 (!loading_a_sbs && skins[skin][screen].data.wps_loaded == false)
|
||||
if (skins[skin][screen].data.wps_loaded == false)
|
||||
{
|
||||
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;
|
||||
#if defined(HAVE_REMOTE_LCD) && NB_SCREENS > 1
|
||||
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:
|
||||
#if defined(HAVE_REMOTE_LCD) && NB_SCREENS > 1
|
||||
if (screen == SCREEN_REMOTE)
|
||||
{
|
||||
setting = global_settings.rwps_file;
|
||||
ext = "rwps";
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
setting = global_settings.wps_file;
|
||||
ext = "wps";
|
||||
}
|
||||
break;
|
||||
#if CONFIG_TUNER
|
||||
case FM_SCREEN:
|
||||
#if defined(HAVE_REMOTE_LCD) && NB_SCREENS > 1
|
||||
if (screen == SCREEN_REMOTE)
|
||||
{
|
||||
setting = global_settings.rfms_file;
|
||||
ext = "rfms";
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
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);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in a new issue