Fix (c) notice which was apparently copy/pasted from a completly unrelated file
[maemo-rb.git] / apps / gui / skin_engine / skin_engine.c
blob3c3f3221b467dd1bb00a998353567f75ccf9e868
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
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 ****************************************************************************/
21 #include <stdio.h>
22 #include <stddef.h>
23 #include <stdlib.h>
24 #include <limits.h>
25 #include "inttypes.h"
26 #include "config.h"
27 #include "action.h"
28 #include "crc32.h"
29 #include "settings.h"
30 #include "wps.h"
31 #include "file.h"
32 #if CONFIG_TUNER
33 #include "radio.h"
34 #endif
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);
54 bool load_on_boot;
55 } skin_helpers[SKINNABLE_SCREENS_COUNT] = {
56 #ifdef HAVE_LCD_BITMAP
57 [CUSTOM_STATUSBAR] = { sb_preproccess, sb_postproccess, sb_create_from_settings, true },
58 #endif
59 [WPS] = { NULL, NULL, wps_default_skin, true },
60 #if CONFIG_TUNER
61 [FM_SCREEN] = { NULL, NULL, default_radio_skin, false }
62 #endif
65 static struct gui_skin {
66 struct gui_wps gui_wps;
67 struct wps_data data;
68 bool failsafe_loaded;
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;
82 skin->data.tree = -1;
83 #ifdef HAVE_TOUCHSCREEN
84 skin->data.touchregions = -1;
85 #endif
86 #ifdef HAVE_SKIN_VARIABLES
87 skin->data.skinvars = -1;
88 #endif
89 #ifdef HAVE_LCD_BITMAP
90 skin->data.font_ids = -1;
91 skin->data.images = -1;
92 #endif
93 #ifdef HAVE_ALBUMART
94 skin->data.albumart = -1;
95 skin->data.playback_aa_slot = -1;
96 #endif
97 #ifdef HAVE_BACKDROP_IMAGE
98 skin->gui_wps.data->backdrop_id = -1;
99 #endif
102 void gui_sync_skin_init(void)
104 int j;
105 for(j=0; j<SKINNABLE_SCREENS_COUNT; j++)
107 FOR_NB_SCREENS(i)
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)
123 int i;
124 char filename[MAX_PATH];
125 static bool first_run = true;
127 #ifdef HAVE_LCD_BITMAP
128 skin_backdrop_init();
129 #endif
130 skins_initialised = true;
132 /* Make sure each skin is loaded */
133 for (i=0; i<SKINNABLE_SCREENS_COUNT; i++)
135 FOR_NB_SCREENS(j)
137 get_skin_filename(filename, MAX_PATH, i,j);
139 if (!first_run)
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);
145 #endif
147 gui_skin_reset(&skins[i][j]);
148 skins[i][j].gui_wps.display = &screens[j];
149 if (skin_helpers[i].load_on_boot)
150 skin_get_gwps(i, j);
153 first_run = false;
154 viewportmanager_theme_changed(THEME_STATUSBAR);
155 #ifdef HAVE_BACKDROP_IMAGE
156 FOR_NB_SCREENS(i)
157 skin_backdrop_show(sb_get_backdrop(i));
158 #endif
161 void skin_load(enum skinnable_screens skin, enum screen_type screen,
162 const char *buf, bool isfile)
164 bool loaded = false;
166 if (skin_helpers[skin].preproccess)
167 skin_helpers[skin].preproccess(screen, &skins[skin][screen].data);
169 if (buf && *buf)
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
183 if (loaded)
184 skin_backdrops_preload();
185 #endif
188 static char* get_skin_filename(char *buf, size_t buf_size,
189 enum skinnable_screens skin, enum screen_type screen)
191 (void)screen;
192 char *setting = NULL, *ext = NULL;
193 switch (skin)
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;
201 ext = "rsbs";
203 else
204 #endif
206 setting = global_settings.sbs_file;
207 ext = "sbs";
209 break;
210 #endif
211 case WPS:
212 #if defined(HAVE_REMOTE_LCD) && NB_SCREENS > 1
213 if (screen == SCREEN_REMOTE)
215 setting = global_settings.rwps_file;
216 ext = "rwps";
218 else
219 #endif
221 setting = global_settings.wps_file;
222 ext = "wps";
224 break;
225 #if CONFIG_TUNER
226 case FM_SCREEN:
227 #if defined(HAVE_REMOTE_LCD) && NB_SCREENS > 1
228 if (screen == SCREEN_REMOTE)
230 setting = global_settings.rfms_file;
231 ext = "rfms";
233 else
234 #endif
236 setting = global_settings.fms_file;
237 ext = "fms";
239 break;
240 #endif
241 default:
242 return NULL;
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);
250 return buf;
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;
258 #endif
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);
264 cpu_boost(true);
265 skin_load(skin, screen, buf, true);
266 cpu_boost(false);
268 return &skins[skin][screen].gui_wps;
271 struct wps_state *skin_get_global_state(void)
273 return &wps_state;
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;
283 return ret;
286 /* tell a skin to do a full update next time */
287 void skin_request_full_update(enum skinnable_screens skin)
289 FOR_NB_SCREENS(i)
290 skins[skin][i].needs_full_update = true;