FS#12756 by Marek Salaba - update Czech translation
[maemo-rb.git] / apps / gui / skin_engine / skin_engine.c
blobe91320b742d15986a38e728071eb3b34f40b03fc
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2002 by Stuart Martin
11 * RTC config saving code (C) 2002 by hessu@hes.iki.fi
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 ****************************************************************************/
22 #include <stdio.h>
23 #include <stddef.h>
24 #include <stdlib.h>
25 #include <limits.h>
26 #include "inttypes.h"
27 #include "config.h"
28 #include "action.h"
29 #include "crc32.h"
30 #include "settings.h"
31 #include "wps.h"
32 #include "file.h"
33 #if CONFIG_TUNER
34 #include "radio.h"
35 #endif
36 #include "skin_engine.h"
37 #include "skin_buffer.h"
38 #include "statusbar-skinned.h"
40 #define FAILSAFENAME "rockbox_failsafe"
42 void skin_data_free_buflib_allocs(struct wps_data *wps_data);
43 char* wps_default_skin(enum screen_type screen);
44 char* default_radio_skin(enum screen_type screen);
45 static bool skins_initialised = false;
47 static char* get_skin_filename(char *buf, size_t buf_size,
48 enum skinnable_screens skin, enum screen_type screen);
50 struct wps_state wps_state = { .id3 = NULL };
51 static struct gui_skin_helper {
52 int (*preproccess)(enum screen_type screen, struct wps_data *data);
53 int (*postproccess)(enum screen_type screen, struct wps_data *data);
54 char* (*default_skin)(enum screen_type screen);
55 bool load_on_boot;
56 } skin_helpers[SKINNABLE_SCREENS_COUNT] = {
57 #ifdef HAVE_LCD_BITMAP
58 [CUSTOM_STATUSBAR] = { sb_preproccess, sb_postproccess, sb_create_from_settings, true },
59 #endif
60 [WPS] = { NULL, NULL, wps_default_skin, true },
61 #if CONFIG_TUNER
62 [FM_SCREEN] = { NULL, NULL, default_radio_skin, false }
63 #endif
66 static struct gui_skin {
67 char filename[MAX_PATH];
68 struct gui_wps gui_wps;
69 struct wps_data data;
70 char *buffer_start;
71 size_t buffer_usage;
72 bool failsafe_loaded;
74 bool needs_full_update;
75 } skins[SKINNABLE_SCREENS_COUNT][NB_SCREENS];
78 static void gui_skin_reset(struct gui_skin *skin)
80 skin->filename[0] = '\0';
81 skin->buffer_start = NULL;
82 skin->failsafe_loaded = false;
83 skin->needs_full_update = true;
84 skin->gui_wps.data = &skin->data;
85 memset(skin->gui_wps.data, 0, sizeof(struct wps_data));
86 skin->data.wps_loaded = false;
87 skin->data.buflib_handle = -1;
88 skin->data.tree = -1;
89 #ifdef HAVE_TOUCHSCREEN
90 skin->data.touchregions = -1;
91 #endif
92 #ifdef HAVE_SKIN_VARIABLES
93 skin->data.skinvars = -1;
94 #endif
95 #ifdef HAVE_LCD_BITMAP
96 skin->data.font_ids = -1;
97 skin->data.images = -1;
98 #endif
99 #ifdef HAVE_ALBUMART
100 skin->data.albumart = -1;
101 skin->data.playback_aa_slot = -1;
102 #endif
103 #ifdef HAVE_BACKDROP_IMAGE
104 skin->gui_wps.data->backdrop_id = -1;
105 #endif
108 void gui_sync_skin_init(void)
110 int j;
111 for(j=0; j<SKINNABLE_SCREENS_COUNT; j++)
113 FOR_NB_SCREENS(i)
115 skin_data_free_buflib_allocs(&skins[j][i].data);
116 gui_skin_reset(&skins[j][i]);
117 skins[j][i].gui_wps.display = &screens[i];
122 void skin_unload_all(void)
124 gui_sync_skin_init();
127 void settings_apply_skins(void)
129 int i;
130 char filename[MAX_PATH];
131 static bool first_run = true;
133 #ifdef HAVE_LCD_BITMAP
134 skin_backdrop_init();
135 #endif
136 skins_initialised = true;
138 /* Make sure each skin is loaded */
139 for (i=0; i<SKINNABLE_SCREENS_COUNT; i++)
141 FOR_NB_SCREENS(j)
143 get_skin_filename(filename, MAX_PATH, i,j);
145 if (!first_run)
147 skin_data_free_buflib_allocs(&skins[i][j].data);
148 #ifdef HAVE_BACKDROP_IMAGE
149 if (skins[i][j].data.backdrop_id >= 0)
150 skin_backdrop_unload(skins[i][j].data.backdrop_id);
151 #endif
153 gui_skin_reset(&skins[i][j]);
154 skins[i][j].gui_wps.display = &screens[j];
155 if (skin_helpers[i].load_on_boot)
156 skin_get_gwps(i, j);
159 first_run = false;
160 viewportmanager_theme_changed(THEME_STATUSBAR);
161 #ifdef HAVE_BACKDROP_IMAGE
162 FOR_NB_SCREENS(i)
163 skin_backdrop_show(sb_get_backdrop(i));
164 #endif
167 void skin_load(enum skinnable_screens skin, enum screen_type screen,
168 const char *buf, bool isfile)
170 bool loaded = false;
172 if (skin_helpers[skin].preproccess)
173 skin_helpers[skin].preproccess(screen, &skins[skin][screen].data);
175 if (buf && *buf)
176 loaded = skin_data_load(screen, &skins[skin][screen].data, buf, isfile);
177 if (loaded)
178 strcpy(skins[skin][screen].filename, buf);
180 if (!loaded && skin_helpers[skin].default_skin)
182 loaded = skin_data_load(screen, &skins[skin][screen].data,
183 skin_helpers[skin].default_skin(screen), false);
184 skins[skin][screen].failsafe_loaded = loaded;
187 skins[skin][screen].needs_full_update = true;
188 if (skin_helpers[skin].postproccess)
189 skin_helpers[skin].postproccess(screen, &skins[skin][screen].data);
190 #ifdef HAVE_BACKDROP_IMAGE
191 if (loaded)
192 skin_backdrops_preload();
193 #endif
196 static char* get_skin_filename(char *buf, size_t buf_size,
197 enum skinnable_screens skin, enum screen_type screen)
199 (void)screen;
200 char *setting = NULL, *ext = NULL;
201 switch (skin)
203 #ifdef HAVE_LCD_BITMAP
204 case CUSTOM_STATUSBAR:
205 #if defined(HAVE_REMOTE_LCD) && NB_SCREENS > 1
206 if (screen == SCREEN_REMOTE)
208 setting = global_settings.rsbs_file;
209 ext = "rsbs";
211 else
212 #endif
214 setting = global_settings.sbs_file;
215 ext = "sbs";
217 break;
218 #endif
219 case WPS:
220 #if defined(HAVE_REMOTE_LCD) && NB_SCREENS > 1
221 if (screen == SCREEN_REMOTE)
223 setting = global_settings.rwps_file;
224 ext = "rwps";
226 else
227 #endif
229 setting = global_settings.wps_file;
230 ext = "wps";
232 break;
233 #if CONFIG_TUNER
234 case FM_SCREEN:
235 #if defined(HAVE_REMOTE_LCD) && NB_SCREENS > 1
236 if (screen == SCREEN_REMOTE)
238 setting = global_settings.rfms_file;
239 ext = "rfms";
241 else
242 #endif
244 setting = global_settings.fms_file;
245 ext = "fms";
247 break;
248 #endif
249 default:
250 return NULL;
253 buf[0] = '\0'; /* force it to reload the default */
254 if (strcmp(setting, FAILSAFENAME) && strcmp(setting, "-"))
256 snprintf(buf, buf_size, WPS_DIR "/%s.%s", setting, ext);
258 return buf;
261 struct gui_wps *skin_get_gwps(enum skinnable_screens skin, enum screen_type screen)
263 #ifdef HAVE_LCD_BITMAP
264 if (skin == CUSTOM_STATUSBAR && !skins_initialised)
265 return &skins[skin][screen].gui_wps;
266 #endif
268 if (skins[skin][screen].data.wps_loaded == false)
270 char filename[MAX_PATH];
271 char *buf = get_skin_filename(filename, MAX_PATH, skin, screen);
272 cpu_boost(true);
273 skins[skin][screen].filename[0] = '\0';
274 skin_load(skin, screen, buf, true);
275 cpu_boost(false);
277 return &skins[skin][screen].gui_wps;
280 struct wps_state *skin_get_global_state(void)
282 return &wps_state;
285 /* This is called to find out if we the screen needs a full update.
286 * if true you MUST do a full update as the next call will return false */
287 bool skin_do_full_update(enum skinnable_screens skin,
288 enum screen_type screen)
290 bool ret = skins[skin][screen].needs_full_update;
291 skins[skin][screen].needs_full_update = false;
292 return ret;
295 /* tell a skin to do a full update next time */
296 void skin_request_full_update(enum skinnable_screens skin)
298 FOR_NB_SCREENS(i)
299 skins[skin][i].needs_full_update = true;