1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2010 Jonathan Gordon
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
35 #include "skin_engine.h"
36 #include "skin_buffer.h"
37 #include "statusbar-skinned.h"
39 #define FAILSAFENAME "rockbox_failsafe"
41 void skin_data_free_buflib_allocs(struct wps_data
*wps_data
);
42 char* wps_default_skin(enum screen_type screen
);
43 char* default_radio_skin(enum screen_type screen
);
44 static bool skins_initialised
= false;
46 static char* get_skin_filename(char *buf
, size_t buf_size
,
47 enum skinnable_screens skin
, enum screen_type screen
);
49 struct wps_state wps_state
= { .id3
= NULL
};
50 static struct gui_skin_helper
{
51 int (*preproccess
)(enum screen_type screen
, struct wps_data
*data
);
52 int (*postproccess
)(enum screen_type screen
, struct wps_data
*data
);
53 char* (*default_skin
)(enum screen_type screen
);
55 } skin_helpers
[SKINNABLE_SCREENS_COUNT
] = {
56 #ifdef HAVE_LCD_BITMAP
57 [CUSTOM_STATUSBAR
] = { sb_preproccess
, sb_postproccess
, sb_create_from_settings
, true },
59 [WPS
] = { NULL
, NULL
, wps_default_skin
, true },
61 [FM_SCREEN
] = { NULL
, NULL
, default_radio_skin
, false }
65 static struct gui_skin
{
66 struct gui_wps gui_wps
;
70 bool needs_full_update
;
71 } skins
[SKINNABLE_SCREENS_COUNT
][NB_SCREENS
];
74 static void gui_skin_reset(struct gui_skin
*skin
)
76 skin
->failsafe_loaded
= false;
77 skin
->needs_full_update
= true;
78 skin
->gui_wps
.data
= &skin
->data
;
79 memset(skin
->gui_wps
.data
, 0, sizeof(struct wps_data
));
80 skin
->data
.wps_loaded
= false;
81 skin
->data
.buflib_handle
= -1;
83 #ifdef HAVE_TOUCHSCREEN
84 skin
->data
.touchregions
= -1;
86 #ifdef HAVE_SKIN_VARIABLES
87 skin
->data
.skinvars
= -1;
89 #ifdef HAVE_LCD_BITMAP
90 skin
->data
.font_ids
= -1;
91 skin
->data
.images
= -1;
94 skin
->data
.albumart
= -1;
95 skin
->data
.playback_aa_slot
= -1;
97 #ifdef HAVE_BACKDROP_IMAGE
98 skin
->gui_wps
.data
->backdrop_id
= -1;
102 void gui_sync_skin_init(void)
105 for(j
=0; j
<SKINNABLE_SCREENS_COUNT
; j
++)
109 skin_data_free_buflib_allocs(&skins
[j
][i
].data
);
110 gui_skin_reset(&skins
[j
][i
]);
111 skins
[j
][i
].gui_wps
.display
= &screens
[i
];
116 void skin_unload_all(void)
118 gui_sync_skin_init();
121 void settings_apply_skins(void)
124 char filename
[MAX_PATH
];
125 static bool first_run
= true;
127 #ifdef HAVE_LCD_BITMAP
128 skin_backdrop_init();
130 skins_initialised
= true;
132 /* Make sure each skin is loaded */
133 for (i
=0; i
<SKINNABLE_SCREENS_COUNT
; i
++)
137 get_skin_filename(filename
, MAX_PATH
, i
,j
);
141 skin_data_free_buflib_allocs(&skins
[i
][j
].data
);
142 #ifdef HAVE_BACKDROP_IMAGE
143 if (skins
[i
][j
].data
.backdrop_id
>= 0)
144 skin_backdrop_unload(skins
[i
][j
].data
.backdrop_id
);
147 gui_skin_reset(&skins
[i
][j
]);
148 skins
[i
][j
].gui_wps
.display
= &screens
[j
];
149 if (skin_helpers
[i
].load_on_boot
)
154 viewportmanager_theme_changed(THEME_STATUSBAR
);
155 #ifdef HAVE_BACKDROP_IMAGE
157 skin_backdrop_show(sb_get_backdrop(i
));
161 void skin_load(enum skinnable_screens skin
, enum screen_type screen
,
162 const char *buf
, bool isfile
)
166 if (skin_helpers
[skin
].preproccess
)
167 skin_helpers
[skin
].preproccess(screen
, &skins
[skin
][screen
].data
);
170 loaded
= skin_data_load(screen
, &skins
[skin
][screen
].data
, buf
, isfile
);
172 if (!loaded
&& skin_helpers
[skin
].default_skin
)
174 loaded
= skin_data_load(screen
, &skins
[skin
][screen
].data
,
175 skin_helpers
[skin
].default_skin(screen
), false);
176 skins
[skin
][screen
].failsafe_loaded
= loaded
;
179 skins
[skin
][screen
].needs_full_update
= true;
180 if (skin_helpers
[skin
].postproccess
)
181 skin_helpers
[skin
].postproccess(screen
, &skins
[skin
][screen
].data
);
182 #ifdef HAVE_BACKDROP_IMAGE
184 skin_backdrops_preload();
188 static char* get_skin_filename(char *buf
, size_t buf_size
,
189 enum skinnable_screens skin
, enum screen_type screen
)
192 char *setting
= NULL
, *ext
= NULL
;
195 #ifdef HAVE_LCD_BITMAP
196 case CUSTOM_STATUSBAR
:
197 #if defined(HAVE_REMOTE_LCD) && NB_SCREENS > 1
198 if (screen
== SCREEN_REMOTE
)
200 setting
= global_settings
.rsbs_file
;
206 setting
= global_settings
.sbs_file
;
212 #if defined(HAVE_REMOTE_LCD) && NB_SCREENS > 1
213 if (screen
== SCREEN_REMOTE
)
215 setting
= global_settings
.rwps_file
;
221 setting
= global_settings
.wps_file
;
227 #if defined(HAVE_REMOTE_LCD) && NB_SCREENS > 1
228 if (screen
== SCREEN_REMOTE
)
230 setting
= global_settings
.rfms_file
;
236 setting
= global_settings
.fms_file
;
245 buf
[0] = '\0'; /* force it to reload the default */
246 if (strcmp(setting
, FAILSAFENAME
) && strcmp(setting
, "-"))
248 snprintf(buf
, buf_size
, WPS_DIR
"/%s.%s", setting
, ext
);
253 struct gui_wps
*skin_get_gwps(enum skinnable_screens skin
, enum screen_type screen
)
255 #ifdef HAVE_LCD_BITMAP
256 if (skin
== CUSTOM_STATUSBAR
&& !skins_initialised
)
257 return &skins
[skin
][screen
].gui_wps
;
260 if (skins
[skin
][screen
].data
.wps_loaded
== false)
262 char filename
[MAX_PATH
];
263 char *buf
= get_skin_filename(filename
, MAX_PATH
, skin
, screen
);
265 skin_load(skin
, screen
, buf
, true);
268 return &skins
[skin
][screen
].gui_wps
;
271 struct wps_state
*skin_get_global_state(void)
276 /* This is called to find out if we the screen needs a full update.
277 * if true you MUST do a full update as the next call will return false */
278 bool skin_do_full_update(enum skinnable_screens skin
,
279 enum screen_type screen
)
281 bool ret
= skins
[skin
][screen
].needs_full_update
;
282 skins
[skin
][screen
].needs_full_update
= false;
286 /* tell a skin to do a full update next time */
287 void skin_request_full_update(enum skinnable_screens skin
)
290 skins
[skin
][i
].needs_full_update
= true;