1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
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 ****************************************************************************/
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
);
56 } skin_helpers
[SKINNABLE_SCREENS_COUNT
] = {
57 #ifdef HAVE_LCD_BITMAP
58 [CUSTOM_STATUSBAR
] = { sb_preproccess
, sb_postproccess
, sb_create_from_settings
, true },
60 [WPS
] = { NULL
, NULL
, wps_default_skin
, true },
62 [FM_SCREEN
] = { NULL
, NULL
, default_radio_skin
, false }
66 static struct gui_skin
{
67 char filename
[MAX_PATH
];
68 struct gui_wps gui_wps
;
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;
89 #ifdef HAVE_TOUCHSCREEN
90 skin
->data
.touchregions
= -1;
92 #ifdef HAVE_SKIN_VARIABLES
93 skin
->data
.skinvars
= -1;
95 #ifdef HAVE_LCD_BITMAP
96 skin
->data
.font_ids
= -1;
97 skin
->data
.images
= -1;
100 skin
->data
.albumart
= -1;
101 skin
->data
.playback_aa_slot
= -1;
103 #ifdef HAVE_BACKDROP_IMAGE
104 skin
->gui_wps
.data
->backdrop_id
= -1;
108 void gui_sync_skin_init(void)
111 for(j
=0; j
<SKINNABLE_SCREENS_COUNT
; j
++)
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)
130 char filename
[MAX_PATH
];
131 static bool first_run
= true;
133 #ifdef HAVE_LCD_BITMAP
134 skin_backdrop_init();
136 skins_initialised
= true;
138 /* Make sure each skin is loaded */
139 for (i
=0; i
<SKINNABLE_SCREENS_COUNT
; i
++)
143 get_skin_filename(filename
, MAX_PATH
, i
,j
);
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
);
153 gui_skin_reset(&skins
[i
][j
]);
154 skins
[i
][j
].gui_wps
.display
= &screens
[j
];
155 if (skin_helpers
[i
].load_on_boot
)
160 viewportmanager_theme_changed(THEME_STATUSBAR
);
161 #ifdef HAVE_BACKDROP_IMAGE
163 skin_backdrop_show(sb_get_backdrop(i
));
167 void skin_load(enum skinnable_screens skin
, enum screen_type screen
,
168 const char *buf
, bool isfile
)
172 if (skin_helpers
[skin
].preproccess
)
173 skin_helpers
[skin
].preproccess(screen
, &skins
[skin
][screen
].data
);
176 loaded
= skin_data_load(screen
, &skins
[skin
][screen
].data
, buf
, isfile
);
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
192 skin_backdrops_preload();
196 static char* get_skin_filename(char *buf
, size_t buf_size
,
197 enum skinnable_screens skin
, enum screen_type screen
)
200 char *setting
= NULL
, *ext
= NULL
;
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
;
214 setting
= global_settings
.sbs_file
;
220 #if defined(HAVE_REMOTE_LCD) && NB_SCREENS > 1
221 if (screen
== SCREEN_REMOTE
)
223 setting
= global_settings
.rwps_file
;
229 setting
= global_settings
.wps_file
;
235 #if defined(HAVE_REMOTE_LCD) && NB_SCREENS > 1
236 if (screen
== SCREEN_REMOTE
)
238 setting
= global_settings
.rfms_file
;
244 setting
= global_settings
.fms_file
;
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
);
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
;
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
);
273 skins
[skin
][screen
].filename
[0] = '\0';
274 skin_load(skin
, screen
, buf
, true);
277 return &skins
[skin
][screen
].gui_wps
;
280 struct wps_state
*skin_get_global_state(void)
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;
295 /* tell a skin to do a full update next time */
296 void skin_request_full_update(enum skinnable_screens skin
)
299 skins
[skin
][i
].needs_full_update
= true;