diff --git a/apps/gui/skin_engine/skin_buffer.c b/apps/gui/skin_engine/skin_buffer.c index a15ad10..d24b6f8 100644 --- a/apps/gui/skin_engine/skin_buffer.c +++ b/apps/gui/skin_engine/skin_buffer.c @@ -31,6 +31,7 @@ #include "wps_internals.h" #include "skin_tokens.h" #include "skin_buffer.h" +#include "dir.h" /* skin buffer management. * This module is used to allocate space in a single global skin buffer for @@ -75,23 +76,27 @@ (WPS_MAX_TOKENS * sizeof(struct wps_token)) #endif -static unsigned char buffer[SKIN_BUFFER_SIZE]; +static unsigned char *buffer; static unsigned char *buffer_front = NULL; /* start of the free space, increases with allocation*/ static unsigned char *buffer_back = NULL; /* end of the free space decreases with allocation */ -static size_t buf_size = SKIN_BUFFER_SIZE; +static uint32_t buf_size; void skin_buffer_init(void) { -#if 0 /* this will go in again later probably */ +#if 1 /* this will go in again later probably */ if (buffer == NULL) { - buf_size = SKIN_BUFFER_SIZE;/* global_settings.skin_buf_size */ + /* get size from nvram.bin */ + if (global_status.skin_buffer_size > 0) + buf_size = global_status.skin_buffer_size; + else + buf_size = SKIN_BUFFER_SIZE; buffer = buffer_alloc(buf_size); buffer_front = buffer; - buffer_back = bufer + buf_size; + buffer_back = buffer + buf_size; } else #endif @@ -102,6 +107,17 @@ void skin_buffer_init(void) } } + +void skin_buffer_dump_size(ssize_t size) +{ + if (size < 0) + size = skin_buffer_usage(); + + /* add a 20k backup buffer */ + global_status.skin_buffer_size = (uint32_t)(size + (20<<10)); + status_save(); +} + /* get the number of bytes currently being used */ size_t skin_buffer_usage(void) { diff --git a/apps/gui/skin_engine/skin_buffer.h b/apps/gui/skin_engine/skin_buffer.h index 521631f..21c9267 100644 --- a/apps/gui/skin_engine/skin_buffer.h +++ b/apps/gui/skin_engine/skin_buffer.h @@ -61,4 +61,8 @@ void skin_buffer_increment(size_t used, bool align); * back 'used' bytes so make sure you actually want to do this */ void skin_buffer_free_from_front(size_t used); +/* write a file containing the skin buffer size, + * real skin_buffer size if size < 0 + * passed size if size >= 0 */ +void skin_buffer_dump_size(ssize_t size); #endif /* _SKIN_BUFFER_H_ */ diff --git a/apps/gui/skin_engine/skin_engine.h b/apps/gui/skin_engine/skin_engine.h index 90f38c9..33c072e 100644 --- a/apps/gui/skin_engine/skin_engine.h +++ b/apps/gui/skin_engine/skin_engine.h @@ -47,8 +47,9 @@ bool skin_update(struct gui_wps *gwps, unsigned int update_type); * setup up the skin-data from a format-buffer (isfile = false) * or from a skinfile (isfile = true) */ -bool skin_data_load(enum screen_type screen, struct wps_data *wps_data, - const char *buf, bool isfile); +int skin_data_load(enum screen_type screen, struct wps_data *wps_data, + const char *buf, bool isfile, bool single_pass); +void skin_data_load_finalize(struct wps_data* data, const char* buf); /* call this in statusbar toggle handlers if needed */ void skin_statusbar_changed(struct gui_wps*); diff --git a/apps/gui/skin_engine/skin_fonts.c b/apps/gui/skin_engine/skin_fonts.c index 9764b32..850803e 100644 --- a/apps/gui/skin_engine/skin_fonts.c +++ b/apps/gui/skin_engine/skin_fonts.c @@ -29,7 +29,6 @@ #include "font.h" #include "skin_buffer.h" #include "skin_fonts.h" -#define FONT_SIZE 10000 static struct skin_font_info { @@ -90,7 +89,7 @@ int skin_font_load(char* font_name) pf = &font->font; if (!font->buffer) { - pf->buffer_start = skin_buffer_alloc(FONT_SIZE); + pf->buffer_start = skin_buffer_alloc(SKIN_FONT_SIZE); if (!pf->buffer_start) return -1; font->buffer = pf->buffer_start; @@ -99,7 +98,7 @@ int skin_font_load(char* font_name) { pf->buffer_start = font->buffer; } - pf->buffer_size = FONT_SIZE; + pf->buffer_size = SKIN_FONT_SIZE; snprintf(filename, MAX_PATH, FONT_DIR "/%s.fnt", font_name); strcpy(font->name, font_name); diff --git a/apps/gui/skin_engine/skin_fonts.h b/apps/gui/skin_engine/skin_fonts.h index 0a847ee..423fc44 100644 --- a/apps/gui/skin_engine/skin_fonts.h +++ b/apps/gui/skin_engine/skin_fonts.h @@ -33,6 +33,7 @@ #define _SKINFONTS_H_ #define MAXUSERFONTS (MAXFONTS - SYSTEMFONTCOUNT) +#define SKIN_FONT_SIZE 10000 void skin_font_init(void); @@ -42,5 +43,5 @@ int skin_font_load(char* font_name); /* unload a skin font. If a font has been loaded more than once it wont actually * be unloaded untill all references have been unloaded */ void skin_font_unload(int font_id); - + #endif diff --git a/apps/gui/skin_engine/skin_parser.c b/apps/gui/skin_engine/skin_parser.c index 3122878..c57d317 100644 --- a/apps/gui/skin_engine/skin_parser.c +++ b/apps/gui/skin_engine/skin_parser.c @@ -92,6 +92,9 @@ static struct skin_viewport *curr_vp; /* the current line, linked to the above viewport */ static struct skin_line *curr_line; +static size_t curr_size; +static bool single_pass; + static int follow_lang_direction = 0; #if defined(DEBUG) || defined(SIMULATOR) @@ -573,20 +576,10 @@ static int get_image_id(int c) char *get_image_filename(const char *start, const char* bmpdir, char *buf, int buf_size) { - const char *end = strchr(start, '|'); - int bmpdirlen = strlen(bmpdir); - - if ( !end || (end - start) >= (buf_size - bmpdirlen - 2) ) - { - buf[0] = '\0'; - return NULL; - } - - strcpy(buf, bmpdir); - buf[bmpdirlen] = '/'; - memcpy( &buf[bmpdirlen + 1], start, end - start); - buf[bmpdirlen + 1 + end - start] = 0; - + size_t len = strlcpy(buf, bmpdir, buf_size); + buf[len] = '/'; + buf[len+1] = '\0'; + strlcat(buf, start, buf_size-(len-1)); return buf; } @@ -659,7 +652,14 @@ static int parse_image_load(const char *wps_bufptr, if (!img) return WPS_ERROR_INVALID_PARAM; /* save a pointer to the filename */ - img->bm.data = (char*)filename; + size_t len = strchr(filename, '|') - filename + 1; + img->bm.data = skin_buffer_alloc(len+1); + if (!img->bm.data) + return WPS_ERROR_INVALID_PARAM; + strlcpy(img->bm.data, filename, len); +/* + printf("filename: %s\n", img->bm.data); +*/ img->label = *id; img->x = x; img->y = y; @@ -731,8 +731,7 @@ static int parse_font_load(const char *wps_bufptr, return skip_end_of_line(wps_bufptr); } - - + static int parse_viewport_display(const char *wps_bufptr, struct wps_token *token, struct wps_data *wps_data) @@ -979,7 +978,13 @@ static int parse_image_special(const char *wps_bufptr, return skip_end_of_line(wps_bufptr); } else if (!error) - wps_data->backdrop = (char*)wps_bufptr + 1; + { + const char* buf = wps_bufptr + 1; + size_t len = strchr(buf, '|') - buf + 1; + char *fn = skin_buffer_alloc(len+1); + strlcpy(fn, buf, len); + wps_data->backdrop = fn; + } } #endif if (error) @@ -1168,7 +1173,13 @@ static int parse_progressbar(const char *wps_bufptr, return WPS_ERROR_INVALID_PARAM; if (LIST_VALUE_PARSED(set, PB_FILENAME)) /* filename */ - pb->bm.data = (char*)filename; + { + size_t len = strchr(filename, '|') - filename + 1; + pb->bm.data = skin_buffer_alloc(len+1); + if (!pb->bm.data) + return WPS_ERROR_INVALID_PARAM; + strlcpy(pb->bm.data, filename, len); + } if (LIST_VALUE_PARSED(set, PB_X)) /* x */ pb->x = x; @@ -1706,7 +1717,8 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr, bool debug) #if LCD_DEPTH > 1 /* Backdrop defaults to the setting unless %X is used, so set it now */ - if (global_settings.backdrop_file[0]) + if (global_settings.backdrop_file[0] + && (global_settings.backdrop_file[0] != '-')) { data->backdrop = "-"; } @@ -2008,14 +2020,29 @@ static bool load_skin_bmp(struct wps_data *wps_data, struct bitmap *bitmap, char #endif format = FORMAT_ANY|FORMAT_TRANSPARENT; + if (!single_pass) /* we only want to know the size in the first pass */ + format |= FORMAT_RETURN_SIZE; + size_t max_buf; char* imgbuf = (char*)skin_buffer_grab(&max_buf); + unsigned char* old = bitmap->data; bitmap->data = imgbuf; int ret = read_bmp_file(img_path, bitmap, max_buf, format, NULL); if (ret > 0) { - skin_buffer_increment(ret, true); + if (single_pass) + { + skin_buffer_increment(ret, true); + } + else + { + bitmap->data = old; +/* + printf("%s: %p:%s\n", __func__, bitmap->data, bitmap->data); +*/ + curr_size += ret; + } return true; } else @@ -2050,6 +2077,9 @@ static bool load_skin_bitmaps(struct wps_data *wps_data, char *bmpdir) struct gui_img *img = (struct gui_img*)list->token->value.data; if (img->bm.data) { +/* + printf("%s: %p - %p\n", __func__, list, img->bm.data); +*/ img->loaded = load_skin_bmp(wps_data, &img->bm, bmpdir); if (img->loaded) img->subimage_height = img->bm.height / img->num_subimages; @@ -2059,6 +2089,7 @@ static bool load_skin_bitmaps(struct wps_data *wps_data, char *bmpdir) list = list->next; } + #if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)) /* Backdrop load scheme: * 1) %X|filename| @@ -2067,6 +2098,22 @@ static bool load_skin_bitmaps(struct wps_data *wps_data, char *bmpdir) if (wps_data->backdrop) { bool needed = wps_data->backdrop[0] != '-'; + + /* fixme: this calculation currently doesn't take into consideration + * that multiple skins can share a backdrop */ + if (!single_pass) + { +#ifdef HAVE_REMOTE_LCD + if (curr_screen != SCREEN_MAIN) + curr_size += REMOTE_LCD_BACKDROP_BYTES; + else +#endif + curr_size += LCD_BACKDROP_BYTES; + return retval; + } +/* + printf("%s: %p\n", __func__, wps_data->backdrop); +*/ wps_data->backdrop = skin_backdrop_load(wps_data->backdrop, bmpdir, curr_screen); if (!wps_data->backdrop && needed) @@ -2136,12 +2183,38 @@ static bool skin_load_fonts(struct wps_data *data) /* to setup up the wps-data from a format-buffer (isfile = false) from a (wps-)file (isfile = true)*/ -bool skin_data_load(enum screen_type screen, struct wps_data *wps_data, - const char *buf, bool isfile) + +void skin_data_load_finalize(struct wps_data *data, const char* buf) { + single_pass = true; + /* get the bitmap dir */ + char bmpdir[MAX_PATH]; + char *dot = strrchr(buf, '.'); + + strlcpy(bmpdir, buf, dot - buf + 1); + /* load the bitmaps that were found by the parsing */ + if (!load_skin_bitmaps(data, bmpdir) || !skin_load_fonts(data)) { + skin_data_reset(data); + data->wps_loaded = false; + } + +#if defined(DEBUG) || defined(SIMULATOR) + debug_skin_usage(); +#endif +} + +int skin_data_load(enum screen_type screen, struct wps_data *wps_data, + const char *buf, bool isfile, bool _single_pass) +{ if (!wps_data || !buf) return false; + single_pass = _single_pass; + curr_size = 0; + size_t old_buf_usage = skin_buffer_usage(); +/* + printf("single pass: %d\n", single_pass); +*/ #ifdef HAVE_ALBUMART int status; struct mp3entry *curtrack; @@ -2161,10 +2234,10 @@ bool skin_data_load(enum screen_type screen, struct wps_data *wps_data, /* alloc default viewport, will be fixed up later */ curr_vp = skin_buffer_alloc(sizeof(struct skin_viewport)); if (!curr_vp) - return false; + return 0; struct skin_token_list *list = new_skin_token_list_item(NULL, curr_vp); if (!list) - return false; + return 0; add_to_ll_chain(&wps_data->viewports, list); @@ -2178,7 +2251,7 @@ bool skin_data_load(enum screen_type screen, struct wps_data *wps_data, curr_line = NULL; if (!skin_start_new_line(curr_vp, 0)) - return false; + return 0; if (!isfile) { @@ -2188,26 +2261,26 @@ bool skin_data_load(enum screen_type screen, struct wps_data *wps_data, /* load the backdrop */ if (!load_skin_bitmaps(wps_data, BACKDROP_DIR)) { skin_data_reset(wps_data); - return false; + return 0; } #endif - return true; + goto end; } - return false; + return 0; } else { int fd = open_utf8(buf, O_RDONLY); if (fd < 0) - return false; + return 0; /* get buffer space from the plugin buffer */ size_t buffersize = 0; char *wps_buffer = (char *)plugin_get_buffer(&buffersize); if (!wps_buffer) - return false; + return 0; /* copy the file's content to the buffer for parsing, ensuring that every line ends with a newline char. */ @@ -2225,12 +2298,12 @@ bool skin_data_load(enum screen_type screen, struct wps_data *wps_data, close(fd); if (start <= 0) - return false; + return 0; /* parse the WPS source */ if (!wps_parse(wps_data, wps_buffer, true)) { skin_data_reset(wps_data); - return false; + return 0; } wps_data->wps_loaded = true; @@ -2245,9 +2318,9 @@ bool skin_data_load(enum screen_type screen, struct wps_data *wps_data, if (!load_skin_bitmaps(wps_data, bmpdir)) { skin_data_reset(wps_data); wps_data->wps_loaded = false; - return false; + return 0; } - if (!skin_load_fonts(wps_data)) + if (single_pass && !skin_load_fonts(wps_data)) { skin_data_reset(wps_data); wps_data->wps_loaded = false; @@ -2275,6 +2348,8 @@ bool skin_data_load(enum screen_type screen, struct wps_data *wps_data, #if defined(DEBUG) || defined(SIMULATOR) debug_skin_usage(); #endif - return true; +end: + //printf("buf %s\n, curr_size %d\n", buf, curr_size); + return skin_buffer_usage() - old_buf_usage + curr_size; } } diff --git a/apps/gui/statusbar-skinned.c b/apps/gui/statusbar-skinned.c index 2ebdcca..9a2dec8 100644 --- a/apps/gui/statusbar-skinned.c +++ b/apps/gui/statusbar-skinned.c @@ -65,12 +65,62 @@ bool sb_set_title_text(char* title, enum themable_icons icon, enum screen_type s } -void sb_skin_data_load(enum screen_type screen, const char *buf, bool isfile) +/* This creates and loads a ".sbs" based on the user settings for: + * - regular statusbar + * - colours + * - ui viewport + * - backdrop + */ +static int sb_create_from_settings(enum screen_type screen, bool load_at_boot) +{ + char buf[128], *ptr, *ptr2; + int len, remaining = sizeof(buf); + + ptr = buf; + ptr[0] = '\0'; + + /* %Vi viewport, colours handled by the parser */ +#if NB_SCREENS > 1 + if (screen == SCREEN_REMOTE) + ptr2 = global_settings.remote_ui_vp_config; + else +#endif + ptr2 = global_settings.ui_vp_config; + + if (ptr2[0] && ptr2[0] != '-') /* from ui viewport setting */ + { + len = snprintf(ptr, remaining, "%%ax%%Vi|%s|\n", ptr2); + while ((ptr2 = strchr(ptr, ','))) + *ptr2 = '|'; + } + else + { + int y = 0, height; + switch (statusbar_position(screen)) + { + case STATUSBAR_TOP: + y = STATUSBAR_HEIGHT; + case STATUSBAR_BOTTOM: + height = screens[screen].lcdheight - STATUSBAR_HEIGHT; + break; + default: + height = screens[screen].lcdheight; + } + len = snprintf(ptr, remaining, "%%ax%%Vi|0|%d|-|%d|1|-|-|\n", + y, height); + } + return sb_skin_data_load(screen, buf, false, load_at_boot); +} + + +int sb_skin_data_load(enum screen_type screen, const char *buf, + bool isfile, bool load_at_boot) { struct wps_data *data = sb_skin[screen].data; int success; - success = buf && skin_data_load(screen, data, buf, isfile); + int ret = skin_data_load(screen, data, buf, isfile, load_at_boot); + success = buf && ret; if (success) { /* hide the sb's default viewport because it has nasty effect with stuff @@ -88,7 +138,13 @@ void sb_skin_data_load(enum screen_type screen, const char *buf, bool isfile) } if (!success && isfile) - sb_create_from_settings(screen); + ret = sb_create_from_settings(screen, load_at_boot); + return ret; +} + +void sbs_data_load_finalize(enum screen_type screen, const char* buf) +{ + skin_data_load_finalize(&sb_skin_data[screen], buf); } struct viewport *sb_skin_get_info_vp(enum screen_type screen) @@ -163,53 +219,6 @@ void sb_skin_set_update_delay(int delay) update_delay = delay; } -/* This creates and loads a ".sbs" based on the user settings for: - * - regular statusbar - * - colours - * - ui viewport - * - backdrop - */ -void sb_create_from_settings(enum screen_type screen) -{ - char buf[128], *ptr, *ptr2; - int len, remaining = sizeof(buf); - - ptr = buf; - ptr[0] = '\0'; - - /* %Vi viewport, colours handled by the parser */ -#if NB_SCREENS > 1 - if (screen == SCREEN_REMOTE) - ptr2 = global_settings.remote_ui_vp_config; - else -#endif - ptr2 = global_settings.ui_vp_config; - - if (ptr2[0] && ptr2[0] != '-') /* from ui viewport setting */ - { - len = snprintf(ptr, remaining, "%%ax%%Vi|%s|\n", ptr2); - while ((ptr2 = strchr(ptr, ','))) - *ptr2 = '|'; - } - else - { - int y = 0, height; - switch (statusbar_position(screen)) - { - case STATUSBAR_TOP: - y = STATUSBAR_HEIGHT; - case STATUSBAR_BOTTOM: - height = screens[screen].lcdheight - STATUSBAR_HEIGHT; - break; - default: - height = screens[screen].lcdheight; - } - len = snprintf(ptr, remaining, "%%ax%%Vi|0|%d|-|%d|1|-|-|\n", - y, height); - } - sb_skin_data_load(screen, buf, false); -} - void sb_skin_init(void) { int i; diff --git a/apps/gui/statusbar-skinned.h b/apps/gui/statusbar-skinned.h index 35bde0b..b71d2ea 100644 --- a/apps/gui/statusbar-skinned.h +++ b/apps/gui/statusbar-skinned.h @@ -32,9 +32,10 @@ #include "icon.h" -void sb_skin_data_load(enum screen_type screen, const char *buf, bool isfile); +int sb_skin_data_load(enum screen_type screen, const char *buf, + bool isfile, bool load_at_boot); +void sbs_data_load_finalize(enum screen_type screen, const char* buf); -void sb_create_from_settings(enum screen_type screen); void sb_skin_init(void); struct viewport *sb_skin_get_info_vp(enum screen_type screen); void sb_skin_update(enum screen_type screen, bool force); @@ -49,10 +50,9 @@ bool sb_set_backdrop(enum screen_type screen, char* filename); #else /* CHARCELL */ #define sb_skin_init() -#define sb_skin_data_load(a,b,c) +#define sb_skin_data_load(a,b,c,d) 0 #define sb_skin_set_update_delay(a) #define sb_skin_set_state(a,b) -#define sb_create_from_settings(a) #endif void do_sbs_update_callback(void *param); #endif /* __STATUSBAR_SKINNED_H__ */ diff --git a/apps/gui/theme_settings.c b/apps/gui/theme_settings.c index 9a75186..dc9522a 100644 --- a/apps/gui/theme_settings.c +++ b/apps/gui/theme_settings.c @@ -33,7 +33,8 @@ #include "skin_engine/skin_engine.h" #include "skin_engine/skin_fonts.h" #include "statusbar-skinned.h" - +#include "splash.h" +#include "lang.h" /* call this after loading a .wps/.rwps or other skin files, so that the * skin buffer is reset properly @@ -41,36 +42,45 @@ struct skin_load_setting { char* setting; char* suffix; - void (*loadfunc)(enum screen_type screen, const char *buf, bool isfile); + int (*loadfunc)(enum screen_type screen, const char *buf, + bool isfile, bool load_at_boot); + void (*finalize_func)(enum screen_type screen, const char* buf); }; static const struct skin_load_setting skins[] = { /* This determins the load order. *sbs must be loaded before any other * skin on that screen */ #ifdef HAVE_LCD_BITMAP - { global_settings.sbs_file, "sbs", sb_skin_data_load}, + { global_settings.sbs_file, "sbs", sb_skin_data_load, sbs_data_load_finalize}, #endif - { global_settings.wps_file, "wps", wps_data_load}, + { global_settings.wps_file, "wps", wps_data_load, wps_data_load_finalize}, #ifdef HAVE_REMOTE_LCD - { global_settings.rsbs_file, "rsbs", sb_skin_data_load}, - { global_settings.rwps_file, "rwps", wps_data_load}, + { global_settings.rsbs_file, "rsbs", sb_skin_data_load, sbs_data_load_finalize}, + { global_settings.rwps_file, "rwps", wps_data_load, wps_data_load_finalize}, #endif }; + + void settings_apply_skins(void) { char buf[MAX_PATH]; + int i, num_skins = ARRAYLEN(skins); + enum screen_type screen = SCREEN_MAIN; + size_t max_size = 0; + ssize_t old_size = -1; + static bool at_boot = true; + if (!at_boot) + old_size = skin_buffer_usage() + skin_buffer_freespace(); /* re-initialize the skin buffer before we start reloading skins */ skin_buffer_init(); - enum screen_type screen = SCREEN_MAIN; - unsigned int i; #ifdef HAVE_LCD_BITMAP skin_backdrop_init(); skin_font_init(); sb_skin_init(); #endif gui_sync_wps_init(); - for (i=0; i 0 && max_size > (size_t)old_size) + goto reboot; + + for(i=0; i < num_skins; i++) + { +#ifdef HAVE_REMOTE_LCD + screen = skins[i].suffix[0] == 'r' ? SCREEN_REMOTE : SCREEN_MAIN; +#endif + snprintf(buf, sizeof buf, WPS_DIR "/%s.%s", + skins[i].setting, skins[i].suffix); + skins[i].finalize_func(screen, buf); + } + } + else + at_boot = false; + viewportmanager_theme_changed(THEME_STATUSBAR); + #if LCD_DEPTH > 1 || defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1 FOR_NB_SCREENS(i) screens[i].backdrop_show(sb_get_backdrop(i)); #endif + skin_buffer_dump_size(at_boot ? -1 : (ssize_t)max_size); + return; + +reboot: + splash(HZ, ID2P(LANG_PLEASE_REBOOT)); + skin_buffer_dump_size(max_size); } diff --git a/apps/gui/wps.c b/apps/gui/wps.c index c58181e..72b7c14 100644 --- a/apps/gui/wps.c +++ b/apps/gui/wps.c @@ -99,9 +99,11 @@ static void wps_disarm_touchregions(struct wps_data *data); #define DEFAULT_WPS(screen) (WPS_DEFAULTCFG) #endif -void wps_data_load(enum screen_type screen, const char *buf, bool isfile) +int wps_data_load(enum screen_type screen, const char *buf, bool isfile, + bool load_at_boot) { bool loaded_ok; + int size; #ifndef __PCTOOL__ /* @@ -123,7 +125,9 @@ void wps_data_load(enum screen_type screen, const char *buf, bool isfile) #endif /* __PCTOOL__ */ - loaded_ok = buf && skin_data_load(screen, gui_wps[screen].data, buf, isfile); + size = skin_data_load(screen, gui_wps[screen].data, buf, isfile, + load_at_boot); + loaded_ok = buf && size; if (!loaded_ok) /* load the hardcoded default */ { @@ -153,8 +157,15 @@ void wps_data_load(enum screen_type screen, const char *buf, bool isfile) "%pb\n", #endif }; - skin_data_load(screen, gui_wps[screen].data, skin_buf[screen], false); + size = skin_data_load(screen, gui_wps[screen].data, + skin_buf[screen], false, true); } + return size; +} + +void wps_data_load_finalize(enum screen_type screen, const char* buf) +{ + skin_data_load_finalize(&wps_datas[screen], buf); } void fade(bool fade_in, bool updatewps) diff --git a/apps/gui/wps.h b/apps/gui/wps.h index 0aa4967..f47feda 100644 --- a/apps/gui/wps.h +++ b/apps/gui/wps.h @@ -26,7 +26,8 @@ long gui_wps_show(void); /* wrapper for the wps to load the skin (.wps/.rwps) files */ -void wps_data_load(enum screen_type, const char *, bool); +int wps_data_load(enum screen_type, const char *, bool, bool); +void wps_data_load_finalize(enum screen_type screen, const char* buf); void gui_sync_wps_init(void); diff --git a/apps/settings.h b/apps/settings.h index bba3336..8d3221b 100644 --- a/apps/settings.h +++ b/apps/settings.h @@ -312,6 +312,9 @@ struct system_status signed char last_screen; int viewer_icon_count; int last_volume_change; /* tick the last volume change happened. skins use this */ + /* the skin buffer size that skins can use, saved to disk so it can + * be resized on boot */ + uint32_t skin_buffer_size; }; struct user_settings diff --git a/apps/settings_list.c b/apps/settings_list.c index ade159b..a34283b 100644 --- a/apps/settings_list.c +++ b/apps/settings_list.c @@ -1649,6 +1649,7 @@ const struct settings_list settings[] = { #ifdef HAVE_MORSE_INPUT OFFON_SETTING(0, morse_input, LANG_MORSE_INPUT, false, "morse input", NULL), #endif + SYSTEM_SETTING(NVRAM(sizeof(uint32_t)), skin_buffer_size, 0), }; const int nb_settings = sizeof(settings)/sizeof(*settings);