diff --git a/apps/gui/bitmap/list-skinned.c b/apps/gui/bitmap/list-skinned.c index 208b2df681..444d49148f 100644 --- a/apps/gui/bitmap/list-skinned.c +++ b/apps/gui/bitmap/list-skinned.c @@ -175,22 +175,23 @@ bool skinlist_draw(struct screen *display, struct gui_synclist *list) for (cur_line = 0; cur_line < display_lines; cur_line++) { struct skin_element* viewport; - struct skin_viewport* skin_viewport; + struct skin_viewport* skin_viewport = NULL; if (list_start_item+cur_line+1 > list->nb_items) break; current_drawing_line = list_start_item+cur_line; is_selected = list->show_selection_marker && list_start_item+cur_line == list->selected_item; - for (viewport = listcfg[screen]->data->tree; + for (viewport = SKINOFFSETTOPTR(get_skin_buffer(wps.data), listcfg[screen]->data->tree); viewport; - viewport = viewport->next) + viewport = SKINOFFSETTOPTR(get_skin_buffer(wps.data), viewport->next)) { int origional_x, origional_y; int origional_w, origional_h; + char *viewport_label = SKINOFFSETTOPTR(get_skin_buffer(wps.data), skin_viewport->label); skin_viewport = (struct skin_viewport*)viewport->data; - if (viewport->children == 0 || !skin_viewport->label || - (skin_viewport->label && strcmp(label, skin_viewport->label)) + if (viewport->children == 0 || !viewport_label || + (skin_viewport->label && strcmp(label, viewport_label)) ) continue; if (is_selected) @@ -220,15 +221,17 @@ bool skinlist_draw(struct screen *display, struct gui_synclist *list) display->set_viewport(&skin_viewport->vp); #ifdef HAVE_LCD_BITMAP /* Set images to not to be displayed */ - struct skin_token_list *imglist = wps.data->images; + struct skin_token_list *imglist = SKINOFFSETTOPTR(get_skin_buffer(wps.data), wps.data->images); while (imglist) { - struct gui_img *img = (struct gui_img *)imglist->token->value.data; + struct wps_token *token = SKINOFFSETTOPTR(get_skin_buffer(wps.data), imglist->token); + struct gui_img *img = SKINOFFSETTOPTR(get_skin_buffer(wps.data), token->value.data); img->display = -1; - imglist = imglist->next; + imglist = SKINOFFSETTOPTR(get_skin_buffer(wps.data), imglist->next); } #endif - skin_render_viewport(viewport->children[0], + struct skin_element** children = SKINOFFSETTOPTR(get_skin_buffer(wps.data), viewport->children); + skin_render_viewport(children[0], &wps, skin_viewport, SKIN_REFRESH_ALL); #ifdef HAVE_LCD_BITMAP wps_display_images(&wps, &skin_viewport->vp); diff --git a/apps/gui/skin_engine/skin_display.c b/apps/gui/skin_engine/skin_display.c index d2dbb56f64..1114c09a72 100644 --- a/apps/gui/skin_engine/skin_display.c +++ b/apps/gui/skin_engine/skin_display.c @@ -102,7 +102,7 @@ void skin_statusbar_changed(struct gui_wps *skin) struct wps_data *data = skin->data; const struct screen *display = skin->display; const int screen = display->screen_type; - struct skin_viewport *svp = skin_find_item(VP_DEFAULT_LABEL, SKIN_FIND_VP, data); + struct skin_viewport *svp = skin_find_item(VP_DEFAULT_LABEL_STRING, SKIN_FIND_VP, data); struct viewport *vp = &svp->vp; viewport_set_defaults(vp, screen); @@ -131,7 +131,7 @@ void skin_statusbar_changed(struct gui_wps *skin) void draw_progressbar(struct gui_wps *gwps, int line, struct progressbar *pb) { struct screen *display = gwps->display; - struct viewport *vp = pb->vp; + struct viewport *vp = SKINOFFSETTOPTR(get_skin_buffer(gwps->data), pb->vp); struct wps_state *state = skin_get_global_state(); struct mp3entry *id3 = state->id3; int x = pb->x, y = pb->y, width = pb->width, height = pb->height; @@ -226,9 +226,9 @@ void draw_progressbar(struct gui_wps *gwps, int line, struct progressbar *pb) flags |= INNER_NOFILL; } - if (pb->slider) + if (SKINOFFSETTOPTR(get_skin_buffer(gwps->data), pb->slider)) { - struct gui_img *img = pb->slider; + struct gui_img *img = SKINOFFSETTOPTR(get_skin_buffer(gwps->data), pb->slider); /* clear the slider */ screen_clear_area(display, x, y, width, height); @@ -245,9 +245,9 @@ void draw_progressbar(struct gui_wps *gwps, int line, struct progressbar *pb) } } - if (pb->backdrop) + if (SKINOFFSETTOPTR(get_skin_buffer(gwps->data), pb->backdrop)) { - struct gui_img *img = pb->backdrop; + struct gui_img *img = SKINOFFSETTOPTR(get_skin_buffer(gwps->data), pb->backdrop); img->bm.data = core_get_data(img->buflib_handle); display->bmp_part(&img->bm, 0, 0, x, y, width, height); flags |= DONT_CLEAR_EXCESS; @@ -255,11 +255,12 @@ void draw_progressbar(struct gui_wps *gwps, int line, struct progressbar *pb) if (!pb->nobar) { - if (pb->image) + struct gui_img *img = SKINOFFSETTOPTR(get_skin_buffer(gwps->data), pb->image); + if (img) { - char *img_data = core_get_data(pb->image->buflib_handle); - pb->image->bm.data = img_data; - gui_bitmap_scrollbar_draw(display, &pb->image->bm, + char *img_data = core_get_data(img->buflib_handle); + img->bm.data = img_data; + gui_bitmap_scrollbar_draw(display, &img->bm, x, y, width, height, length, 0, end, flags); } @@ -268,11 +269,11 @@ void draw_progressbar(struct gui_wps *gwps, int line, struct progressbar *pb) length, 0, end, flags); } - if (pb->slider) + if (SKINOFFSETTOPTR(get_skin_buffer(gwps->data), pb->slider)) { int xoff = 0, yoff = 0; int w = width, h = height; - struct gui_img *img = pb->slider; + struct gui_img *img = SKINOFFSETTOPTR(get_skin_buffer(gwps->data), pb->slider); img->bm.data = core_get_data(img->buflib_handle); if (flags&HORIZONTAL) @@ -347,11 +348,12 @@ void wps_display_images(struct gui_wps *gwps, struct viewport* vp) struct wps_data *data = gwps->data; struct screen *display = gwps->display; - struct skin_token_list *list = data->images; + struct skin_token_list *list = SKINOFFSETTOPTR(get_skin_buffer(data), data->images); while (list) { - struct gui_img *img = (struct gui_img*)list->token->value.data; + struct wps_token *token = SKINOFFSETTOPTR(get_skin_buffer(data), list->token); + struct gui_img *img = (struct gui_img*)SKINOFFSETTOPTR(get_skin_buffer(data), token->value.data); if (img->using_preloaded_icons && img->display >= 0) { screen_put_icon(display, img->x, img->y, img->display); @@ -362,20 +364,21 @@ void wps_display_images(struct gui_wps *gwps, struct viewport* vp) { wps_draw_image(gwps, img, img->display); } - else if (img->always_display && img->vp == vp) + else if (img->always_display && SKINOFFSETTOPTR(get_skin_buffer(data), img->vp) == vp) { wps_draw_image(gwps, img, 0); } } - list = list->next; + list = SKINOFFSETTOPTR(get_skin_buffer(data), list->next); } #ifdef HAVE_ALBUMART /* now draw the AA */ - if (data->albumart && data->albumart->vp == vp - && data->albumart->draw_handle >= 0) + struct skin_albumart *aa = SKINOFFSETTOPTR(get_skin_buffer(data), data->albumart); + if (aa && SKINOFFSETTOPTR(get_skin_buffer(data), aa->vp) == vp + && aa->draw_handle >= 0) { - draw_album_art(gwps, data->albumart->draw_handle, false); - data->albumart->draw_handle = -1; + draw_album_art(gwps, aa->draw_handle, false); + aa->draw_handle = -1; } #endif @@ -398,8 +401,8 @@ int evaluate_conditional(struct gui_wps *gwps, int offset, int intval = num_options < 2 ? 2 : num_options; /* get_token_value needs to know the number of options in the enum */ - value = get_token_value(gwps, conditional->token, offset, - result, sizeof(result), &intval); + value = get_token_value(gwps, SKINOFFSETTOPTR(get_skin_buffer(gwps->data), conditional->token), + offset, result, sizeof(result), &intval); /* intval is now the number of the enum option we want to read, starting from 1. If intval is -1, we check if value is empty. */ diff --git a/apps/gui/skin_engine/skin_engine.c b/apps/gui/skin_engine/skin_engine.c index bd875fe9e4..75862faab0 100644 --- a/apps/gui/skin_engine/skin_engine.c +++ b/apps/gui/skin_engine/skin_engine.c @@ -41,19 +41,10 @@ static bool skins_initialising = true; /* App uses the host malloc to manage the buffer */ -#ifdef APPLICATION -#define skin_buffer NULL void theme_init_buffer(void) { skins_initialising = false; } -#else -static char skin_buffer[SKIN_BUFFER_SIZE]; -void theme_init_buffer(void) -{ - skins_initialising = false; -} -#endif void skin_data_free_buflib_allocs(struct wps_data *wps_data); char* wps_default_skin(enum screen_type screen); @@ -95,8 +86,20 @@ void gui_sync_skin_init(void) skins[j][i].gui_wps.display = &screens[i]; memset(skins[j][i].gui_wps.data, 0, sizeof(struct wps_data)); skins[j][i].data.wps_loaded = false; + skins[j][i].data.buflib_handle = -1; + skins[j][i].data.tree = -1; +#ifdef HAVE_TOUCHSCREEN + skins[j][i].data.touchregions = -1; +#endif +#ifdef HAVE_SKIN_VARIABLES + skins[j][i].data.skinvars = -1; +#endif +#ifdef HAVE_LCD_BITMAP + skins[j][i].data.font_ids = -1; + skins[j][i].data.images = -1; +#endif #ifdef HAVE_ALBUMART - skins[j][i].data.albumart = NULL; + skins[j][i].data.albumart = -1; skins[j][i].data.playback_aa_slot = -1; #endif } @@ -113,8 +116,6 @@ void skin_unload_all(void) skin_data_free_buflib_allocs(&skins[j][i].data); } - skin_buffer_init(skin_buffer, SKIN_BUFFER_SIZE); - #ifdef HAVE_LCD_BITMAP skin_backdrop_init(); #endif @@ -245,7 +246,6 @@ struct gui_wps *skin_get_gwps(enum skinnable_screens skin, enum screen_type scre cpu_boost(false); loading_a_sbs = false; } - return &skins[skin][screen].gui_wps; } diff --git a/apps/gui/skin_engine/skin_parser.c b/apps/gui/skin_engine/skin_parser.c index 8eef1dedee..ef0f3623e8 100644 --- a/apps/gui/skin_engine/skin_parser.c +++ b/apps/gui/skin_engine/skin_parser.c @@ -24,7 +24,9 @@ #include #include #include "config.h" +#ifndef __PCTOOL__ #include "core_alloc.h" +#endif #include "file.h" #include "misc.h" #include "plugin.h" @@ -77,12 +79,41 @@ #define WPS_ERROR_INVALID_PARAM -1 #define GLYPHS_TO_CACHE 256 +static char* skin_buffer = NULL; +void skinparser_set_buffer(char* pointer) +{ + skin_buffer = pointer; +} + +#if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)) +static char *backdrop_filename; +#endif static bool isdefault(struct skin_tag_parameter *param) { return param->type == DEFAULT; } +static inline char* +get_param_text(struct skin_element *element, int param_number) +{ + struct skin_tag_parameter* params = SKINOFFSETTOPTR(skin_buffer, element->params); + return SKINOFFSETTOPTR(skin_buffer, params[param_number].data.text); +} + +static inline struct skin_element* +get_param_code(struct skin_element *element, int param_number) +{ + struct skin_tag_parameter* params = SKINOFFSETTOPTR(skin_buffer, element->params); + return SKINOFFSETTOPTR(skin_buffer, params[param_number].data.code); +} + +static inline struct skin_tag_parameter* +get_param(struct skin_element *element, int param_number) +{ + struct skin_tag_parameter* params = SKINOFFSETTOPTR(skin_buffer, element->params); + return ¶ms[param_number]; +} /* which screen are we parsing for? */ static enum screen_type curr_screen; @@ -90,6 +121,7 @@ static enum screen_type curr_screen; /* the current viewport */ static struct skin_element *curr_viewport_element; static struct skin_viewport *curr_vp; +static struct skin_element *first_viewport; static struct line *curr_line; @@ -103,16 +135,19 @@ typedef int (*parse_function)(struct skin_element *element, /* add a skin_token_list item to the list chain. ALWAYS appended because some of the * chains require the order to be kept. */ -static void add_to_ll_chain(struct skin_token_list **list, struct skin_token_list *item) +static void add_to_ll_chain(OFFSETTYPE(struct skin_token_list *) *listoffset, + struct skin_token_list *item) { - if (*list == NULL) - *list = item; + struct skin_token_list *list = SKINOFFSETTOPTR(skin_buffer, *listoffset); + if (list == NULL) + { + *listoffset = PTRTOSKINOFFSET(skin_buffer, item); + } else { - struct skin_token_list *t = *list; - while (t->next) - t = t->next; - t->next = item; + while (SKINOFFSETTOPTR(skin_buffer, list->next)) + list = SKINOFFSETTOPTR(skin_buffer, list->next); + list->next = PTRTOSKINOFFSET(skin_buffer, item); } } @@ -123,32 +158,36 @@ void *skin_find_item(const char *label, enum skin_find_what what, struct wps_data *data) { const char *itemlabel = NULL; + char *old_skin_buffer = skin_buffer; + char *databuf = get_skin_buffer(data); union { struct skin_token_list *linkedlist; struct skin_element *vplist; } list = {NULL}; bool isvplist = false; void *ret = NULL; + if (databuf && databuf != skin_buffer) + skin_buffer = get_skin_buffer(data); switch (what) { case SKIN_FIND_UIVP: case SKIN_FIND_VP: - list.vplist = data->tree; + list.vplist = SKINOFFSETTOPTR(skin_buffer, data->tree); isvplist = true; break; #ifdef HAVE_LCD_BITMAP case SKIN_FIND_IMAGE: - list.linkedlist = data->images; + list.linkedlist = SKINOFFSETTOPTR(skin_buffer, data->images); break; #endif #ifdef HAVE_TOUCHSCREEN case SKIN_FIND_TOUCHREGION: - list.linkedlist = data->touchregions; + list.linkedlist = SKINOFFSETTOPTR(skin_buffer, data->touchregions); break; #endif #ifdef HAVE_SKIN_VARIABLES case SKIN_VARIABLE: - list.linkedlist = data->skinvars; + list.linkedlist = SKINOFFSETTOPTR(skin_buffer, data->skinvars); break; #endif } @@ -156,43 +195,55 @@ void *skin_find_item(const char *label, enum skin_find_what what, while (list.linkedlist) { bool skip = false; + struct wps_token *token = NULL; + if (!isvplist) + token = SKINOFFSETTOPTR(skin_buffer, list.linkedlist->token); switch (what) { case SKIN_FIND_UIVP: case SKIN_FIND_VP: - ret = list.vplist->data; - itemlabel = ((struct skin_viewport *)ret)->label; + ret = SKINOFFSETTOPTR(skin_buffer, list.vplist->data); + if (((struct skin_viewport *)ret)->label == VP_DEFAULT_LABEL) + itemlabel = VP_DEFAULT_LABEL_STRING; + else + itemlabel = SKINOFFSETTOPTR(skin_buffer, ((struct skin_viewport *)ret)->label); skip = !(((struct skin_viewport *)ret)->is_infovp == (what==SKIN_FIND_UIVP)); break; #ifdef HAVE_LCD_BITMAP case SKIN_FIND_IMAGE: - ret = list.linkedlist->token->value.data; - itemlabel = ((struct gui_img *)ret)->label; + ret = SKINOFFSETTOPTR(skin_buffer, token->value.data); + itemlabel = SKINOFFSETTOPTR(skin_buffer, ((struct gui_img *)ret)->label); break; #endif #ifdef HAVE_TOUCHSCREEN case SKIN_FIND_TOUCHREGION: - ret = list.linkedlist->token->value.data; - itemlabel = ((struct touchregion *)ret)->label; + ret = SKINOFFSETTOPTR(skin_buffer, token->value.data); + itemlabel = SKINOFFSETTOPTR(skin_buffer, ((struct touchregion *)ret)->label); break; #endif #ifdef HAVE_SKIN_VARIABLES case SKIN_VARIABLE: - ret = list.linkedlist->token->value.data; - itemlabel = ((struct skin_var *)ret)->label; + ret = SKINOFFSETTOPTR(skin_buffer, token->value.data); + itemlabel = SKINOFFSETTOPTR(skin_buffer, ((struct skin_var *)ret)->label); break; #endif } if (!skip && itemlabel && !strcmp(itemlabel, label)) + { + if (old_skin_buffer != skin_buffer) + skin_buffer = old_skin_buffer; return ret; + } if (isvplist) - list.vplist = list.vplist->next; + list.vplist = SKINOFFSETTOPTR(skin_buffer, list.vplist->next); else - list.linkedlist = list.linkedlist->next; + list.linkedlist = SKINOFFSETTOPTR(skin_buffer, list.linkedlist->next); } + if (old_skin_buffer != skin_buffer) + skin_buffer = old_skin_buffer; return NULL; } @@ -212,10 +263,10 @@ static struct skin_token_list *new_skin_token_list_item(struct wps_token *token, token = (struct wps_token*)skin_buffer_alloc(sizeof(struct wps_token)); if (!llitem || !token) return NULL; - llitem->next = NULL; - llitem->token = token; + llitem->next = PTRTOSKINOFFSET(skin_buffer, NULL); + llitem->token = PTRTOSKINOFFSET(skin_buffer, token); if (token_data) - llitem->token->value.data = token_data; + token->value.data = PTRTOSKINOFFSET(skin_buffer, token_data); return llitem; } @@ -226,13 +277,12 @@ static int parse_statusbar_tags(struct skin_element* element, (void)element; if (token->type == SKIN_TOKEN_DRAW_INBUILTBAR) { - token->value.data = (void*)&curr_vp->vp; + token->value.data = PTRTOSKINOFFSET(skin_buffer, (void*)&curr_vp->vp); } else { - struct skin_element *def_vp = wps_data->tree; - struct skin_viewport *default_vp = def_vp->data; - if (def_vp->params_count == 0) + struct skin_viewport *default_vp = SKINOFFSETTOPTR(skin_buffer, first_viewport->data); + if (first_viewport->params_count == 0) { wps_data->wps_sb_tag = true; wps_data->show_sb_on_wps = (token->type == SKIN_TOKEN_ENABLE_THEME); @@ -279,7 +329,7 @@ static int parse_image_display(struct skin_element *element, struct wps_token *token, struct wps_data *wps_data) { - char *label = element->params[0].data.text; + char *label = get_param_text(element, 0); char sublabel = '\0'; int subimage; struct gui_img *img; @@ -297,9 +347,9 @@ static int parse_image_display(struct skin_element *element, { return WPS_ERROR_INVALID_PARAM; } - id->label = label; + id->label = img->label; id->offset = 0; - id->token = NULL; + id->token = PTRTOSKINOFFSET(skin_buffer, NULL); if (img->using_preloaded_icons) { token->type = SKIN_TOKEN_IMAGE_DISPLAY_LISTICON; @@ -307,13 +357,13 @@ static int parse_image_display(struct skin_element *element, if (element->params_count > 1) { - if (element->params[1].type == CODE) - id->token = element->params[1].data.code->data; + if (get_param(element, 1)->type == CODE) + id->token = get_param_code(element, 1)->data; /* specify a number. 1 being the first subimage (i.e top) NOT 0 */ - else if (element->params[1].type == INTEGER) - id->subimage = element->params[1].data.number - 1; + else if (get_param(element, 1)->type == INTEGER) + id->subimage = get_param(element, 1)->data.number - 1; if (element->params_count > 2) - id->offset = element->params[2].data.number; + id->offset = get_param(element, 2)->data.number; } else { @@ -326,7 +376,7 @@ static int parse_image_display(struct skin_element *element, id->subimage = 0; } } - token->value.data = id; + token->value.data = PTRTOSKINOFFSET(skin_buffer, id); return 0; } @@ -344,10 +394,10 @@ static int parse_image_load(struct skin_element *element, or %xl(n,filename.bmp,x,y,num_subimages) */ - id = element->params[0].data.text; - filename = element->params[1].data.text; - x = element->params[2].data.number; - y = element->params[3].data.number; + id = get_param_text(element, 0); + filename = get_param_text(element, 1); + x = get_param(element, 2)->data.number; + y = get_param(element, 3)->data.number; /* check the image number and load state */ if(skin_find_item(id, SKIN_FIND_IMAGE, wps_data)) @@ -360,7 +410,7 @@ static int parse_image_load(struct skin_element *element, return WPS_ERROR_INVALID_PARAM; /* save a pointer to the filename */ img->bm.data = (char*)filename; - img->label = id; + img->label = PTRTOSKINOFFSET(skin_buffer, (void*)id); img->x = x; img->y = y; img->num_subimages = 1; @@ -370,7 +420,7 @@ static int parse_image_load(struct skin_element *element, img->buflib_handle = -1; /* save current viewport */ - img->vp = &curr_vp->vp; + img->vp = PTRTOSKINOFFSET(skin_buffer, &curr_vp->vp); if (token->type == SKIN_TOKEN_IMAGE_DISPLAY) { @@ -378,7 +428,7 @@ static int parse_image_load(struct skin_element *element, } else if (element->params_count == 5) { - img->num_subimages = element->params[4].data.number; + img->num_subimages = get_param(element, 4)->data.number; if (img->num_subimages <= 0) return WPS_ERROR_INVALID_PARAM; } @@ -408,13 +458,13 @@ static int parse_font_load(struct skin_element *element, struct wps_data *wps_data) { (void)wps_data; (void)token; - int id = element->params[0].data.number; - char *filename = element->params[1].data.text; + int id = get_param(element, 0)->data.number; + char *filename = get_param_text(element, 1); int glyphs; char *ptr; if(element->params_count > 2) - glyphs = element->params[2].data.number; + glyphs = get_param(element, 2)->data.number; else glyphs = GLYPHS_TO_CACHE; if (id < 2) @@ -452,12 +502,12 @@ static int parse_playlistview(struct skin_element *element, (struct playlistviewer *)skin_buffer_alloc(sizeof(struct playlistviewer)); if (!viewer) return WPS_ERROR_INVALID_PARAM; - viewer->vp = &curr_vp->vp; + viewer->vp = PTRTOSKINOFFSET(skin_buffer, &curr_vp->vp); viewer->show_icons = true; - viewer->start_offset = element->params[0].data.number; - viewer->line = element->params[1].data.code; + viewer->start_offset = get_param(element, 0)->data.number; + viewer->line = PTRTOSKINOFFSET(skin_buffer, get_param_code(element, 1)); - token->value.data = (void*)viewer; + token->value.data = PTRTOSKINOFFSET(skin_buffer, (void*)viewer); return 0; } @@ -474,12 +524,12 @@ static int parse_viewport_gradient_setup(struct skin_element *element, cfg = (struct gradient_config *)skin_buffer_alloc(sizeof(struct gradient_config)); if (!cfg) return 1; - if (!parse_color(curr_screen, element->params[0].data.text, &cfg->start) || - !parse_color(curr_screen, element->params[1].data.text, &cfg->end)) + if (!parse_color(curr_screen, get_param_text(element, 0), &cfg->start) || + !parse_color(curr_screen, get_param_text(element, 1), &cfg->end)) return 1; if (element->params_count > 2) { - if (!parse_color(curr_screen, element->params[2].data.text, &cfg->text)) + if (!parse_color(curr_screen, get_param_text(element, 2), &cfg->text)) return 1; } else @@ -487,7 +537,7 @@ static int parse_viewport_gradient_setup(struct skin_element *element, cfg->text = curr_vp->vp.fg_pattern; } - token->value.data = cfg; + token->value.data = PTRTOSKINOFFSET(skin_buffer, cfg); return 0; } #endif @@ -500,14 +550,14 @@ static int parse_listitem(struct skin_element *element, struct listitem *li = (struct listitem *)skin_buffer_alloc(sizeof(struct listitem)); if (!li) return 1; - token->value.data = li; + token->value.data = PTRTOSKINOFFSET(skin_buffer, li); if (element->params_count == 0) li->offset = 0; else { - li->offset = element->params[0].data.number; + li->offset = get_param(element, 0)->data.number; if (element->params_count > 1) - li->wrap = strcasecmp(element->params[1].data.text, "nowrap") != 0; + li->wrap = strcasecmp(get_param_text(element, 1), "nowrap") != 0; else li->wrap = true; } @@ -526,17 +576,17 @@ static int parse_listitemviewport(struct skin_element *element, return -1; cfg->data = wps_data; cfg->tile = false; - cfg->label = element->params[0].data.text; + cfg->label = get_param_text(element, 0); cfg->width = -1; cfg->height = -1; - if (!isdefault(&element->params[1])) - cfg->width = element->params[1].data.number; - if (!isdefault(&element->params[2])) - cfg->height = element->params[2].data.number; + if (!isdefault(get_param(element, 1))) + cfg->width = get_param(element, 1)->data.number; + if (!isdefault(get_param(element, 2))) + cfg->height = get_param(element, 2)->data.number; if (element->params_count > 3 && - !strcmp(element->params[3].data.text, "tile")) + !strcmp(get_param_text(element, 3), "tile")) cfg->tile = true; - token->value.data = (void*)cfg; + token->value.data = PTRTOSKINOFFSET(skin_buffer, (void*)cfg); #endif return 0; } @@ -548,7 +598,7 @@ static int parse_viewporttextstyle(struct skin_element *element, { (void)wps_data; int style; - char *mode = element->params[0].data.text; + char *mode = get_param_text(element, 0); unsigned colour; if (!strcmp(mode, "invert")) @@ -558,7 +608,7 @@ static int parse_viewporttextstyle(struct skin_element *element, else if (!strcmp(mode, "colour") || !strcmp(mode, "color")) { if (element->params_count < 2 || - !parse_color(curr_screen, element->params[1].data.text, &colour)) + !parse_color(curr_screen, get_param_text(element, 1), &colour)) return 1; style = STYLE_COLORED|(STYLE_COLOR_MASK&colour); } @@ -571,7 +621,7 @@ static int parse_viewporttextstyle(struct skin_element *element, else /* atoi() instead of using a number in the parser is because [si] * will select the number for something which looks like a colour * making the "colour" case (above) harder to parse */ - num_lines = atoi(element->params[1].data.text); + num_lines = atoi(get_param_text(element, 1)); style = STYLE_GRADIENT|NUMLN_PACK(num_lines)|CURLN_PACK(0); } #endif @@ -590,7 +640,7 @@ static int parse_viewportcolour(struct skin_element *element, struct wps_data *wps_data) { (void)wps_data; - struct skin_tag_parameter *param = element->params; + struct skin_tag_parameter *param = get_param(element, 0); struct viewport_colour *colour = (struct viewport_colour *)skin_buffer_alloc(sizeof(struct viewport_colour)); if (!colour) @@ -602,11 +652,12 @@ static int parse_viewportcolour(struct skin_element *element, } else { - if (!parse_color(curr_screen, param->data.text, &colour->colour)) + if (!parse_color(curr_screen, SKINOFFSETTOPTR(skin_buffer, param->data.text), + &colour->colour)) return -1; } - colour->vp = &curr_vp->vp; - token->value.data = colour; + colour->vp = PTRTOSKINOFFSET(skin_buffer, &curr_vp->vp); + token->value.data = PTRTOSKINOFFSET(skin_buffer, colour); if (element->line == curr_viewport_element->line) { if (token->type == SKIN_TOKEN_VIEWPORT_FGCOLOUR) @@ -634,18 +685,18 @@ static int parse_image_special(struct skin_element *element, char *filename; if (token->type == SKIN_TOKEN_IMAGE_BACKDROP) { - if (isdefault(&element->params[0])) + if (isdefault(get_param(element, 0))) { filename = "-"; } else { - filename = element->params[0].data.text; + filename = get_param_text(element, 0); /* format: %X(filename.bmp) or %X(d) */ if (!strcmp(filename, "d")) filename = NULL; } - wps_data->backdrop = filename; + backdrop_filename = filename; } #endif @@ -665,7 +716,7 @@ static int parse_setting_and_lang(struct skin_element *element, * If that ever changes remove the #ifndef __PCTOOL__'s here */ (void)wps_data; - char *temp = element->params[0].data.text; + char *temp = get_param_text(element, 0); int i; if (token->type == SKIN_TOKEN_TRANSLATEDSTRING) @@ -692,12 +743,12 @@ static int parse_logical_if(struct skin_element *element, struct wps_data *wps_data) { (void)wps_data; - char *op = element->params[1].data.text; + char *op = get_param_text(element, 1); struct logical_if *lif = skin_buffer_alloc(sizeof(struct logical_if)); if (!lif) return -1; - token->value.data = lif; - lif->token = element->params[0].data.code->data; + token->value.data = PTRTOSKINOFFSET(skin_buffer, lif); + lif->token = get_param_code(element, 0)->data; if (!strncmp(op, "=", 1)) lif->op = IF_EQUALS; @@ -712,9 +763,9 @@ static int parse_logical_if(struct skin_element *element, else if (!strncmp(op, "<", 1)) lif->op = IF_LESSTHAN; - memcpy(&lif->operand, &element->params[2], sizeof(lif->operand)); + memcpy(&lif->operand, get_param(element, 2), sizeof(lif->operand)); if (element->params_count > 3) - lif->num_options = element->params[3].data.number; + lif->num_options = get_param(element, 3)->data.number; else lif->num_options = TOKEN_VALUE_ONLY; return 0; @@ -743,7 +794,7 @@ static int parse_timeout_tag(struct skin_element *element, } } else - val = element->params[0].data.number; + val = get_param(element, 0)->data.number; token->value.i = val * TIMEOUT_UNIT; return 0; } @@ -756,13 +807,13 @@ static int parse_substring_tag(struct skin_element* element, struct substring *ss = (struct substring*)skin_buffer_alloc(sizeof(struct substring)); if (!ss) return 1; - ss->start = element->params[0].data.number; - if (element->params[1].type == DEFAULT) + ss->start = get_param(element, 0)->data.number; + if (get_param(element, 1)->type == DEFAULT) ss->length = -1; else - ss->length = element->params[1].data.number; - ss->token = element->params[2].data.code->data; - token->value.data = ss; + ss->length = get_param(element, 1)->data.number; + ss->token = get_param_code(element, 2)->data; + token->value.data = PTRTOSKINOFFSET(skin_buffer, ss); return 0; } @@ -773,7 +824,7 @@ static int parse_progressbar_tag(struct skin_element* element, #ifdef HAVE_LCD_BITMAP struct progressbar *pb; struct viewport *vp = &curr_vp->vp; - struct skin_tag_parameter *param = element->params; + struct skin_tag_parameter *param = get_param(element, 0); int curr_param = 0; char *image_filename = NULL; @@ -782,17 +833,17 @@ static int parse_progressbar_tag(struct skin_element* element, return 0; /* nothing to do */ pb = (struct progressbar*)skin_buffer_alloc(sizeof(struct progressbar)); - token->value.data = pb; + token->value.data = PTRTOSKINOFFSET(skin_buffer, pb); if (!pb) return WPS_ERROR_INVALID_PARAM; - pb->vp = vp; + pb->vp = PTRTOSKINOFFSET(skin_buffer, vp); pb->follow_lang_direction = follow_lang_direction > 0; pb->nofill = false; pb->nobar = false; - pb->image = NULL; - pb->slider = NULL; - pb->backdrop = NULL; + pb->image = PTRTOSKINOFFSET(skin_buffer, NULL); + pb->slider = PTRTOSKINOFFSET(skin_buffer, NULL); + pb->backdrop = PTRTOSKINOFFSET(skin_buffer, NULL); pb->invert_fill_direction = false; pb->horizontal = true; @@ -849,7 +900,7 @@ static int parse_progressbar_tag(struct skin_element* element, /* optional params, first is the image filename if it isnt recognised as a keyword */ curr_param = 4; - if (isdefault(&element->params[curr_param])) + if (isdefault(get_param(element, curr_param))) { param++; curr_param++; @@ -858,75 +909,79 @@ static int parse_progressbar_tag(struct skin_element* element, pb->horizontal = pb->width > pb->height; while (curr_param < element->params_count) { + char* text; param++; - if (!strcmp(param->data.text, "invert")) + text = SKINOFFSETTOPTR(skin_buffer, param->data.text); + if (!strcmp(text, "invert")) pb->invert_fill_direction = true; - else if (!strcmp(param->data.text, "nofill")) + else if (!strcmp(text, "nofill")) pb->nofill = true; - else if (!strcmp(param->data.text, "nobar")) + else if (!strcmp(text, "nobar")) pb->nobar = true; - else if (!strcmp(param->data.text, "slider")) + else if (!strcmp(text, "slider")) { if (curr_param+1 < element->params_count) { curr_param++; param++; - pb->slider = skin_find_item(param->data.text, - SKIN_FIND_IMAGE, wps_data); + text = SKINOFFSETTOPTR(skin_buffer, param->data.text); + pb->slider = PTRTOSKINOFFSET(skin_buffer, + skin_find_item(text, SKIN_FIND_IMAGE, wps_data)); } else /* option needs the next param */ return -1; } - else if (!strcmp(param->data.text, "image")) + else if (!strcmp(text, "image")) { if (curr_param+1 < element->params_count) { curr_param++; param++; - image_filename = param->data.text; + image_filename = SKINOFFSETTOPTR(skin_buffer, param->data.text); + } + else /* option needs the next param */ + return -1; + } + else if (!strcmp(text, "backdrop")) + { + if (curr_param+1 < element->params_count) + { + curr_param++; + param++; + text = SKINOFFSETTOPTR(skin_buffer, param->data.text); + pb->backdrop = PTRTOSKINOFFSET(skin_buffer, + skin_find_item(text, SKIN_FIND_IMAGE, wps_data)); } else /* option needs the next param */ return -1; } - else if (!strcmp(param->data.text, "backdrop")) - { - if (curr_param+1 < element->params_count) - { - curr_param++; - param++; - pb->backdrop = skin_find_item(param->data.text, - SKIN_FIND_IMAGE, wps_data); - - } - else /* option needs the next param */ - return -1; - } - else if (!strcmp(param->data.text, "vertical")) + else if (!strcmp(text, "vertical")) { pb->horizontal = false; - if (isdefault(&element->params[3])) + if (isdefault(get_param(element, 3))) pb->height = vp->height - pb->y; } - else if (!strcmp(param->data.text, "horizontal")) + else if (!strcmp(text, "horizontal")) pb->horizontal = true; else if (curr_param == 4) - image_filename = param->data.text; + image_filename = text; curr_param++; } if (image_filename) { - pb->image = skin_find_item(image_filename, SKIN_FIND_IMAGE, wps_data); - if (!pb->image) /* load later */ + pb->image = PTRTOSKINOFFSET(skin_buffer, + skin_find_item(image_filename, SKIN_FIND_IMAGE, wps_data)); + if (!SKINOFFSETTOPTR(skin_buffer, pb->image)) /* load later */ { struct gui_img* img = (struct gui_img*)skin_buffer_alloc(sizeof(struct gui_img)); if (!img) return WPS_ERROR_INVALID_PARAM; /* save a pointer to the filename */ img->bm.data = (char*)image_filename; - img->label = image_filename; + img->label = PTRTOSKINOFFSET(skin_buffer, image_filename); img->x = 0; img->y = 0; img->num_subimages = 1; @@ -934,13 +989,13 @@ static int parse_progressbar_tag(struct skin_element* element, img->display = -1; img->using_preloaded_icons = false; img->buflib_handle = -1; - img->vp = &curr_vp->vp; + img->vp = PTRTOSKINOFFSET(skin_buffer, &curr_vp->vp); struct skin_token_list *item = (struct skin_token_list *)new_skin_token_list_item(NULL, img); if (!item) return WPS_ERROR_INVALID_PARAM; add_to_ll_chain(&wps_data->images, item); - pb->image = img; + pb->image = PTRTOSKINOFFSET(skin_buffer, img); } } @@ -993,12 +1048,12 @@ static int parse_albumart_load(struct skin_element* element, aa->xalign = WPS_ALBUMART_ALIGN_CENTER; /* default */ aa->yalign = WPS_ALBUMART_ALIGN_CENTER; /* default */ - aa->x = element->params[0].data.number; - aa->y = element->params[1].data.number; - aa->width = element->params[2].data.number; - aa->height = element->params[3].data.number; + aa->x = get_param(element, 0)->data.number; + aa->y = get_param(element, 1)->data.number; + aa->width = get_param(element, 2)->data.number; + aa->height = get_param(element, 3)->data.number; - aa->vp = &curr_vp->vp; + aa->vp = PTRTOSKINOFFSET(skin_buffer, &curr_vp->vp); aa->draw_handle = -1; /* if we got here, we parsed everything ok .. ! */ @@ -1016,7 +1071,7 @@ static int parse_albumart_load(struct skin_element* element, aa->x = LCD_WIDTH - (aa->x + aa->width); aa->state = WPS_ALBUMART_LOAD; - wps_data->albumart = aa; + wps_data->albumart = PTRTOSKINOFFSET(skin_buffer, aa); dimensions.width = aa->width; dimensions.height = aa->height; @@ -1026,9 +1081,9 @@ static int parse_albumart_load(struct skin_element* element, if (0 <= albumart_slot) wps_data->playback_aa_slot = albumart_slot; - if (element->params_count > 4 && !isdefault(&element->params[4])) + if (element->params_count > 4 && !isdefault(get_param(element, 4))) { - switch (*element->params[4].data.text) + switch (*get_param_text(element, 4)) { case 'l': case 'L': @@ -1050,9 +1105,9 @@ static int parse_albumart_load(struct skin_element* element, break; } } - if (element->params_count > 5 && !isdefault(&element->params[5])) + if (element->params_count > 5 && !isdefault(get_param(element, 5))) { - switch (*element->params[5].data.text) + switch (*get_param_text(element, 5)) { case 't': case 'T': @@ -1082,7 +1137,7 @@ static struct skin_var* find_or_add_var(const char* label, ret = (struct skin_var*)skin_buffer_alloc(sizeof(struct skin_var)); if (!ret) return NULL; - ret->label = label; + ret->label = PTRTOSKINOFFSET(skin_buffer, label); ret->value = 1; ret->last_changed = 0xffff; struct skin_token_list *item = new_skin_token_list_item(NULL, ret); @@ -1096,14 +1151,14 @@ static int parse_skinvar( struct skin_element *element, struct wps_token *token, struct wps_data *wps_data) { - const char* label = element->params[0].data.text; + const char* label = get_param_text(element, 0); struct skin_var* var = find_or_add_var(label, wps_data); if (!var) return WPS_ERROR_INVALID_PARAM; switch (token->type) { case SKIN_TOKEN_VAR_GETVAL: - token->value.data = var; + token->value.data = PTRTOSKINOFFSET(skin_buffer, var); break; case SKIN_TOKEN_VAR_SET: { @@ -1112,23 +1167,23 @@ static int parse_skinvar( struct skin_element *element, sizeof(struct skin_var_changer)); if (!data) return WPS_ERROR_INVALID_PARAM; - data->var = var; - data->newval = element->params[2].data.number; + data->var = PTRTOSKINOFFSET(skin_buffer, var); + data->newval = get_param(element, 2)->data.number; data->max = 0; - if (!strcmp(element->params[1].data.text, "set")) + if (!strcmp(get_param_text(element, 1), "set")) data->direct = true; - else if (!strcmp(element->params[1].data.text, "inc")) + else if (!strcmp(get_param_text(element, 1), "inc")) { data->direct = false; } - else if (!strcmp(element->params[1].data.text, "dec")) + else if (!strcmp(get_param_text(element, 1), "dec")) { data->direct = false; data->newval *= -1; } if (element->params_count > 3) - data->max = element->params[3].data.number; - token->value.data = data; + data->max = get_param(element, 3)->data.number; + token->value.data = PTRTOSKINOFFSET(skin_buffer, data); } break; case SKIN_TOKEN_VAR_TIMEOUT: @@ -1138,12 +1193,12 @@ static int parse_skinvar( struct skin_element *element, sizeof(struct skin_var_lastchange)); if (!data) return WPS_ERROR_INVALID_PARAM; - data->var = var; + data->var = PTRTOSKINOFFSET(skin_buffer, var); data->timeout = 10; if (element->params_count > 1) - data->timeout = element->params[1].data.number; + data->timeout = get_param(element, 1)->data.number; data->timeout *= TIMEOUT_UNIT; - token->value.data = data; + token->value.data = PTRTOSKINOFFSET(skin_buffer, data); } break; default: /* kill the warning */ @@ -1161,23 +1216,25 @@ static int parse_lasttouch(struct skin_element *element, (struct touchregion_lastpress*)skin_buffer_alloc( sizeof(struct touchregion_lastpress)); int i; + struct touchregion *region = NULL; if (!data) return WPS_ERROR_INVALID_PARAM; - data->region = NULL; + data->timeout = 10; for (i=0; iparams_count; i++) { - if (element->params[i].type == STRING) - data->region = skin_find_item(element->params[i].data.text, + if (get_param(element, i)->type == STRING) + region = skin_find_item(get_param_text(element, i), SKIN_FIND_TOUCHREGION, wps_data); - else if (element->params[i].type == INTEGER || - element->params[i].type == DECIMAL) - data->timeout = element->params[i].data.number; + else if (get_param(element, i)->type == INTEGER || + get_param(element, i)->type == DECIMAL) + data->timeout = get_param(element, i)->data.number; } + data->region = PTRTOSKINOFFSET(skin_buffer, region); data->timeout *= TIMEOUT_UNIT; - token->value.data = data; + token->value.data = PTRTOSKINOFFSET(skin_buffer, data); return 0; } @@ -1221,7 +1278,7 @@ static int touchregion_setup_setting(struct skin_element *element, int param_no, { #ifndef __PCTOOL__ int p = param_no; - char *name = element->params[p++].data.text; + char *name = get_param_text(element, p++); int j; region->setting_data.setting = find_setting_by_cfgname(name, &j); @@ -1237,11 +1294,11 @@ static int touchregion_setup_setting(struct skin_element *element, int param_no, if (element->params_count < p+1) return -1; - text = element->params[p++].data.text; + text = get_param_text(element, p++); switch (settings[j].flags&F_T_MASK) { case F_T_CUSTOM: - setting->value.text = text; + setting->value.text = PTRTOSKINOFFSET(skin_buffer, text); break; case F_T_INT: case F_T_UINT: @@ -1301,34 +1358,34 @@ static int parse_touchregion(struct skin_element *element, /* should probably do some bounds checking here with the viewport... but later */ region->action = ACTION_NONE; - if (element->params[0].type == STRING) + if (get_param(element, 0)->type == STRING) { - region->label = element->params[0].data.text; + region->label = PTRTOSKINOFFSET(skin_buffer, get_param_text(element, 0)); p = 1; /* "[SI]III[SI]|SS" is the param list. There MUST be 4 numbers * followed by at least one string. Verify that here */ if (element->params_count < 6 || - element->params[4].type != INTEGER) + get_param(element, 4)->type != INTEGER) return WPS_ERROR_INVALID_PARAM; } else { - region->label = NULL; + region->label = PTRTOSKINOFFSET(skin_buffer, NULL); p = 0; } - region->x = element->params[p++].data.number; - region->y = element->params[p++].data.number; - region->width = element->params[p++].data.number; - region->height = element->params[p++].data.number; - region->wvp = curr_vp; + region->x = get_param(element, p++)->data.number; + region->y = get_param(element, p++)->data.number; + region->width = get_param(element, p++)->data.number; + region->height = get_param(element, p++)->data.number; + region->wvp = PTRTOSKINOFFSET(skin_buffer, curr_vp); region->armed = false; region->reverse_bar = false; region->value = 0; region->last_press = 0xffff; region->press_length = PRESS; region->allow_while_locked = false; - action = element->params[p++].data.text; + action = get_param_text(element, p++); /* figure out the action */ if(!strcmp(pb_string, action)) @@ -1364,7 +1421,7 @@ static int parse_touchregion(struct skin_element *element, } while (p < element->params_count) { - char* param = element->params[p++].data.text; + char* param = get_param_text(element, p++); if (!strcmp(param, "allow_while_locked")) region->allow_while_locked = true; else if (!strcmp(param, "reverse_bar")) @@ -1438,24 +1495,30 @@ static bool check_feature_tag(const int type) */ void skin_data_free_buflib_allocs(struct wps_data *wps_data) { - (void)wps_data; + if (wps_data->wps_loaded) + skin_buffer = get_skin_buffer(wps_data); #ifdef HAVE_LCD_BITMAP #ifndef __PCTOOL__ - struct skin_token_list *list = wps_data->images; + struct skin_token_list *list = SKINOFFSETTOPTR(skin_buffer, wps_data->images); + int *font_ids = SKINOFFSETTOPTR(skin_buffer, wps_data->font_ids); while (list) { - struct gui_img *img = (struct gui_img*)list->token->value.data; + struct wps_token *token = SKINOFFSETTOPTR(skin_buffer, list->token); + struct gui_img *img = (struct gui_img*)SKINOFFSETTOPTR(skin_buffer, token->value.data); if (img->buflib_handle > 0) core_free(img->buflib_handle); - list = list->next; + list = SKINOFFSETTOPTR(skin_buffer, list->next); } - wps_data->images = NULL; - if (wps_data->font_ids != NULL) + wps_data->images = PTRTOSKINOFFSET(skin_buffer, NULL); + if (font_ids != NULL) { while (wps_data->font_count > 0) - font_unload(wps_data->font_ids[--wps_data->font_count]); + font_unload(font_ids[--wps_data->font_count]); } - wps_data->font_ids = NULL; + wps_data->font_ids = PTRTOSKINOFFSET(skin_buffer, NULL); + if (wps_data->buflib_handle > 0) + core_free(wps_data->buflib_handle); + wps_data->buflib_handle = -1; #endif #endif } @@ -1469,22 +1532,22 @@ static void skin_data_reset(struct wps_data *wps_data) { skin_data_free_buflib_allocs(wps_data); #ifdef HAVE_LCD_BITMAP - wps_data->images = NULL; + wps_data->images = INVALID_OFFSET; #endif - wps_data->tree = NULL; + wps_data->tree = INVALID_OFFSET; #if LCD_DEPTH > 1 || defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1 if (wps_data->backdrop_id >= 0) skin_backdrop_unload(wps_data->backdrop_id); - wps_data->backdrop = NULL; + backdrop_filename = NULL; #endif #ifdef HAVE_TOUCHSCREEN - wps_data->touchregions = NULL; + wps_data->touchregions = INVALID_OFFSET; #endif #ifdef HAVE_SKIN_VARIABLES - wps_data->skinvars = NULL; + wps_data->skinvars = INVALID_OFFSET; #endif #ifdef HAVE_ALBUMART - wps_data->albumart = NULL; + wps_data->albumart = INVALID_OFFSET; if (wps_data->playback_aa_slot >= 0) { playback_release_aa_slot(wps_data->playback_aa_slot); @@ -1560,10 +1623,8 @@ static int load_skin_bmp(struct wps_data *wps_data, struct bitmap *bitmap, char* handle = core_alloc_ex(bitmap->data, buf_size, &buflib_ops); if (handle < 0) { -#ifndef APPLICATION DEBUGF("Not enough skin buffer: need %zd more.\n", buf_size - skin_buffer_freespace()); -#endif close(fd); return handle; } @@ -1600,16 +1661,17 @@ static bool load_skin_bitmaps(struct wps_data *wps_data, char *bmpdir) bool retval = true; /* return false if a single image failed to load */ /* regular images */ - list = wps_data->images; + list = SKINOFFSETTOPTR(skin_buffer, wps_data->images); while (list) { - struct gui_img *img = (struct gui_img*)list->token->value.data; + struct wps_token *token = SKINOFFSETTOPTR(skin_buffer, list->token); + struct gui_img *img = (struct gui_img*)SKINOFFSETTOPTR(skin_buffer, token->value.data); if (img->bm.data) { if (img->using_preloaded_icons) { img->loaded = true; - list->token->type = SKIN_TOKEN_IMAGE_DISPLAY_LISTICON; + token->type = SKIN_TOKEN_IMAGE_DISPLAY_LISTICON; } else { @@ -1621,11 +1683,11 @@ static bool load_skin_bitmaps(struct wps_data *wps_data, char *bmpdir) retval = false; } } - list = list->next; + list = SKINOFFSETTOPTR(skin_buffer, list->next); } #if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)) - wps_data->backdrop_id = skin_backdrop_assign(wps_data->backdrop, bmpdir, curr_screen); + wps_data->backdrop_id = skin_backdrop_assign(backdrop_filename, bmpdir, curr_screen); #endif /* has backdrop support */ return retval; } @@ -1639,11 +1701,12 @@ static bool skin_load_fonts(struct wps_data *data) struct skin_element *vp_list; int font_id; /* walk though each viewport and assign its font */ - for(vp_list = data->tree; vp_list; vp_list = vp_list->next) + for(vp_list = SKINOFFSETTOPTR(skin_buffer, data->tree); + vp_list; vp_list = SKINOFFSETTOPTR(skin_buffer, vp_list->next)) { /* first, find the viewports that have a non-sys/ui-font font */ struct skin_viewport *skin_vp = - (struct skin_viewport*)vp_list->data; + SKINOFFSETTOPTR(skin_buffer, vp_list->data); struct viewport *vp = &skin_vp->vp; font_id = skin_vp->parsed_fontid; @@ -1699,19 +1762,28 @@ static bool skin_load_fonts(struct wps_data *data) /* finally, assign the font_id to the viewport */ vp->font = font->id; } - data->font_ids = skin_buffer_alloc(font_count * sizeof(int)); - if (!success || data->font_ids == NULL) + if (font_count) { - while (font_count > 0) + int *font_ids = skin_buffer_alloc(font_count * sizeof(int)); + if (!success || font_ids == NULL) { - if(id_array[--font_count] != -1) - font_unload(id_array[font_count]); + while (font_count > 0) + { + if(id_array[--font_count] != -1) + font_unload(id_array[font_count]); + } + data->font_ids = PTRTOSKINOFFSET(skin_buffer, NULL); + return false; } - data->font_ids = NULL; - return false; + memcpy(font_ids, id_array, sizeof(int)*font_count); + data->font_count = font_count; + data->font_ids = PTRTOSKINOFFSET(skin_buffer, font_ids); + } + else + { + data->font_count = 0; + data->font_ids = PTRTOSKINOFFSET(skin_buffer, NULL); } - memcpy(data->font_ids, id_array, sizeof(int)*font_count); - data->font_count = font_count; return success; } @@ -1726,13 +1798,15 @@ static int convert_viewport(struct wps_data *data, struct skin_element* element) return CALLBACK_ERROR; skin_vp->hidden_flags = 0; - skin_vp->label = NULL; + skin_vp->label = PTRTOSKINOFFSET(skin_buffer, NULL); skin_vp->is_infovp = false; skin_vp->parsed_fontid = 1; - element->data = skin_vp; + element->data = PTRTOSKINOFFSET(skin_buffer, skin_vp); curr_vp = skin_vp; curr_viewport_element = element; - + if (!first_viewport) + first_viewport = element; + viewport_set_defaults(&skin_vp->vp, curr_screen); #if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)) @@ -1746,11 +1820,11 @@ static int convert_viewport(struct wps_data *data, struct skin_element* element) #endif - struct skin_tag_parameter *param = element->params; + struct skin_tag_parameter *param = get_param(element, 0); if (element->params_count == 0) /* default viewport */ { - if (!data->tree) /* first viewport in the skin */ - data->tree = element; + if (data->tree < 0) /* first viewport in the skin */ + data->tree = PTRTOSKINOFFSET(skin_buffer, element); skin_vp->label = VP_DEFAULT_LABEL; return CALLBACK_OK; } @@ -1848,6 +1922,7 @@ static int skin_element_callback(struct skin_element* element, void* data) token = (struct wps_token*)skin_buffer_alloc(sizeof(struct wps_token)); memset(token, 0, sizeof(*token)); token->type = element->tag->type; + token->value.data = INVALID_OFFSET; if (element->tag->flags&SKIN_RTC_REFRESH) { @@ -1860,7 +1935,7 @@ static int skin_element_callback(struct skin_element* element, void* data) else curr_line->update_mode |= element->tag->flags&SKIN_REFRESH_ALL; - element->data = token; + element->data = PTRTOSKINOFFSET(skin_buffer, token); /* Some tags need special handling for the tag, so add them here */ switch (token->type) @@ -1909,7 +1984,7 @@ static int skin_element_callback(struct skin_element* element, void* data) break; #endif case SKIN_TOKEN_FILE_DIRECTORY: - token->value.i = element->params[0].data.number; + token->value.i = get_param(element, 0)->data.number; break; #if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)) case SKIN_TOKEN_VIEWPORT_FGCOLOUR: @@ -1941,7 +2016,7 @@ static int skin_element_callback(struct skin_element* element, void* data) break; case SKIN_TOKEN_VIEWPORT_ENABLE: case SKIN_TOKEN_UIVIEWPORT_ENABLE: - token->value.data = element->params[0].data.text; + token->value.data = get_param(element, 0)->data.text; break; case SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY: function = parse_image_display; @@ -1964,8 +2039,11 @@ static int skin_element_callback(struct skin_element* element, void* data) #endif #ifdef HAVE_ALBUMART case SKIN_TOKEN_ALBUMART_DISPLAY: - if (wps_data->albumart) - wps_data->albumart->vp = &curr_vp->vp; + if (SKINOFFSETTOPTR(skin_buffer, wps_data->albumart)) + { + struct skin_albumart *aa = SKINOFFSETTOPTR(skin_buffer, wps_data->albumart); + aa->vp = PTRTOSKINOFFSET(skin_buffer, &curr_vp->vp); + } break; case SKIN_TOKEN_ALBUMART_LOAD: function = parse_albumart_load; @@ -2002,7 +2080,7 @@ static int skin_element_callback(struct skin_element* element, void* data) (struct line *)skin_buffer_alloc(sizeof(struct line)); line->update_mode = SKIN_REFRESH_STATIC; curr_line = line; - element->data = line; + element->data = PTRTOSKINOFFSET(skin_buffer, line); } break; case LINE_ALTERNATOR: @@ -2013,7 +2091,7 @@ static int skin_element_callback(struct skin_element* element, void* data) #ifndef __PCTOOL__ alternator->next_change_tick = current_tick; #endif - element->data = alternator; + element->data = PTRTOSKINOFFSET(skin_buffer, alternator); } break; case CONDITIONAL: @@ -2022,7 +2100,7 @@ static int skin_element_callback(struct skin_element* element, void* data) (struct conditional *)skin_buffer_alloc(sizeof(struct conditional)); conditional->last_value = -1; conditional->token = element->data; - element->data = conditional; + element->data = PTRTOSKINOFFSET(skin_buffer, conditional); if (!check_feature_tag(element->tag->type)) { return FEATURE_NOT_AVAILABLE; @@ -2051,11 +2129,12 @@ bool skin_data_load(enum screen_type screen, struct wps_data *wps_data, struct mp3entry *curtrack; long offset; struct skin_albumart old_aa = {.state = WPS_ALBUMART_NONE}; - if (wps_data->albumart) + struct skin_albumart *aa = SKINOFFSETTOPTR(skin_buffer, wps_data->albumart); + if (aa) { - old_aa.state = wps_data->albumart->state; - old_aa.height = wps_data->albumart->height; - old_aa.width = wps_data->albumart->width; + old_aa.state = aa->state; + old_aa.height = aa->height; + old_aa.width = aa->width; } #endif #ifdef HAVE_LCD_BITMAP @@ -2074,12 +2153,20 @@ bool skin_data_load(enum screen_type screen, struct wps_data *wps_data, #endif + /* get buffer space from the plugin buffer */ + size_t buffersize = 0; + wps_buffer = (char *)plugin_get_buffer(&buffersize); + + if (!wps_buffer) + return false; + skin_data_reset(wps_data); wps_data->wps_loaded = false; curr_screen = screen; curr_line = NULL; curr_vp = NULL; curr_viewport_element = NULL; + first_viewport = NULL; if (isfile) { @@ -2087,14 +2174,6 @@ bool skin_data_load(enum screen_type screen, struct wps_data *wps_data, if (fd < 0) return false; - - /* get buffer space from the plugin buffer */ - size_t buffersize = 0; - wps_buffer = (char *)plugin_get_buffer(&buffersize); - - if (!wps_buffer) - return false; - /* copy the file's content to the buffer for parsing, ensuring that every line ends with a newline char. */ unsigned int start = 0; @@ -2110,25 +2189,26 @@ bool skin_data_load(enum screen_type screen, struct wps_data *wps_data, close(fd); if (start <= 0) return false; + skin_buffer = &wps_buffer[start]; + buffersize -= start; } else { + skin_buffer = wps_buffer; wps_buffer = (char*)buf; } + skin_buffer = (void *)(((unsigned long)skin_buffer + 3) & ~3); + buffersize -= 3; #if LCD_DEPTH > 1 || defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1 - wps_data->backdrop = "-"; + backdrop_filename = "-"; wps_data->backdrop_id = -1; #endif /* parse the skin source */ -#ifndef APPLICATION - skin_buffer_save_position(); -#endif - wps_data->tree = skin_parse(wps_buffer, skin_element_callback, wps_data); - if (!wps_data->tree) { + skin_buffer_init(skin_buffer, buffersize); + struct skin_element *tree = skin_parse(wps_buffer, skin_element_callback, wps_data); + wps_data->tree = PTRTOSKINOFFSET(skin_buffer, tree); + if (!SKINOFFSETTOPTR(skin_buffer, wps_data->tree)) { skin_data_reset(wps_data); -#ifndef APPLICATION - skin_buffer_restore_position(); -#endif return false; } @@ -2149,9 +2229,6 @@ bool skin_data_load(enum screen_type screen, struct wps_data *wps_data, !skin_load_fonts(wps_data)) { skin_data_reset(wps_data); -#ifndef APPLICATION - skin_buffer_restore_position(); -#endif return false; } #endif @@ -2159,7 +2236,7 @@ bool skin_data_load(enum screen_type screen, struct wps_data *wps_data, status = audio_status(); if (status & AUDIO_STATUS_PLAY) { - struct skin_albumart *aa = wps_data->albumart; + struct skin_albumart *aa = SKINOFFSETTOPTR(skin_buffer, wps_data->albumart); if (aa && ((aa->state && !old_aa.state) || (aa->state && (((old_aa.height != aa->height) || @@ -2173,7 +2250,18 @@ bool skin_data_load(enum screen_type screen, struct wps_data *wps_data, } } #endif - wps_data->wps_loaded = true; +#ifndef __PCTOOL__ + wps_data->buflib_handle = core_alloc(isfile ? buf : "failsafe skin", + skin_buffer_usage()); + if (wps_data->buflib_handle >= 0) + { + wps_data->wps_loaded = true; + memcpy(core_get_data(wps_data->buflib_handle), skin_buffer, + skin_buffer_usage()); + } +#else + wps_data->wps_loaded = wps_data->tree >= 0; +#endif #ifdef DEBUG_SKIN_ENGINE // if (isfile && debug_wps) // debug_skin_usage(); diff --git a/apps/gui/skin_engine/skin_render.c b/apps/gui/skin_engine/skin_render.c index 4d41a6f9b7..e408caaa1e 100644 --- a/apps/gui/skin_engine/skin_render.c +++ b/apps/gui/skin_engine/skin_render.c @@ -27,6 +27,7 @@ #include "strlcat.h" #include "config.h" +#include "core_alloc.h" #include "kernel.h" #ifdef HAVE_ALBUMART #include "albumart.h" @@ -81,6 +82,18 @@ static void skin_render_playlistviewer(struct playlistviewer* viewer, unsigned long refresh_type); #endif +static char* skin_buffer; +/* hack alert: fix skin_parser.c's skin_buffer pointer */ +void skinparser_set_buffer(char* pointer); + +static inline struct skin_element* +get_child(OFFSETTYPE(struct skin_element**) children, int child) +{ + OFFSETTYPE(struct skin_element*) *kids = SKINOFFSETTOPTR(skin_buffer, children); + return SKINOFFSETTOPTR(skin_buffer, kids[child]); +} + + static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info, struct skin_element *element, struct viewport* vp) { @@ -88,7 +101,7 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info, (void)vp; /* silence warnings */ (void)info; #endif - struct wps_token *token = (struct wps_token *)element->data; + struct wps_token *token = (struct wps_token *)SKINOFFSETTOPTR(skin_buffer, element->data); #ifdef HAVE_LCD_BITMAP struct wps_data *data = gwps->data; @@ -99,14 +112,16 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info, #if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)) case SKIN_TOKEN_VIEWPORT_FGCOLOUR: { - struct viewport_colour *col = token->value.data; - col->vp->fg_pattern = col->colour; + struct viewport_colour *col = SKINOFFSETTOPTR(skin_buffer, token->value.data); + struct viewport *vp = SKINOFFSETTOPTR(skin_buffer, col->vp); + vp->fg_pattern = col->colour; } break; case SKIN_TOKEN_VIEWPORT_BGCOLOUR: { - struct viewport_colour *col = token->value.data; - col->vp->bg_pattern = col->colour; + struct viewport_colour *col = SKINOFFSETTOPTR(skin_buffer, token->value.data); + struct viewport *vp = SKINOFFSETTOPTR(skin_buffer, col->vp); + vp->bg_pattern = col->colour; } break; case SKIN_TOKEN_VIEWPORT_TEXTSTYLE: @@ -116,7 +131,7 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info, #ifdef HAVE_LCD_COLOR case SKIN_TOKEN_VIEWPORT_GRADIENT_SETUP: { - struct gradient_config *cfg = token->value.data; + struct gradient_config *cfg = SKINOFFSETTOPTR(skin_buffer, token->value.data); vp->lss_pattern = cfg->start; vp->lse_pattern = cfg->end; vp->lst_pattern = cfg->text; @@ -125,14 +140,18 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info, #endif case SKIN_TOKEN_VIEWPORT_ENABLE: { - char *label = token->value.data; + char *label = SKINOFFSETTOPTR(skin_buffer, token->value.data); char temp = VP_DRAW_HIDEABLE; - struct skin_element *viewport = gwps->data->tree; + struct skin_element *viewport = SKINOFFSETTOPTR(skin_buffer, gwps->data->tree); while (viewport) { - struct skin_viewport *skinvp = (struct skin_viewport*)viewport->data; - if (skinvp->label && !skinvp->is_infovp && - !strcmp(skinvp->label, label)) + struct skin_viewport *skinvp = SKINOFFSETTOPTR(skin_buffer, viewport->data); + + char *vplabel = SKINOFFSETTOPTR(skin_buffer, skinvp->label); + if (skinvp->label == VP_DEFAULT_LABEL) + vplabel = VP_DEFAULT_LABEL_STRING; + if (vplabel && !skinvp->is_infovp && + !strcmp(vplabel, label)) { if (skinvp->hidden_flags&VP_DRAW_HIDDEN) { @@ -140,7 +159,7 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info, } skinvp->hidden_flags = temp; } - viewport = viewport->next; + viewport = SKINOFFSETTOPTR(skin_buffer, viewport->next); } } break; @@ -148,11 +167,10 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info, case SKIN_TOKEN_LIST_ITEM_CFG: if (do_refresh) skinlist_set_cfg(gwps->display->screen_type, - token->value.data); + SKINOFFSETTOPTR(skin_buffer, token->value.data)); break; case SKIN_TOKEN_UIVIEWPORT_ENABLE: - sb_set_info_vp(gwps->display->screen_type, - token->value.data); + sb_set_info_vp(gwps->display->screen_type, token->value.data); break; case SKIN_TOKEN_PEAKMETER: data->peak_meter_enabled = true; @@ -173,7 +191,7 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info, case SKIN_TOKEN_TUNER_RSSI_BAR: case SKIN_TOKEN_LIST_SCROLLBAR: { - struct progressbar *bar = (struct progressbar*)token->value.data; + struct progressbar *bar = (struct progressbar*)SKINOFFSETTOPTR(skin_buffer, token->value.data); if (do_refresh) draw_progressbar(gwps, info->line_number, bar); } @@ -183,12 +201,12 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info, case SKIN_TOKEN_IMAGE_DISPLAY_LISTICON: case SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY: { - struct image_display *id = token->value.data; - const char* label = id->label; + struct image_display *id = SKINOFFSETTOPTR(skin_buffer, token->value.data); + const char* label = SKINOFFSETTOPTR(skin_buffer, id->label); struct gui_img *img = skin_find_item(label,SKIN_FIND_IMAGE, data); if (img && img->loaded) { - if (id->token == NULL) + if (SKINOFFSETTOPTR(skin_buffer, id->token) == NULL) { img->display = id->subimage; } @@ -197,8 +215,8 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info, char buf[16]; const char *out; int a = img->num_subimages; - out = get_token_value(gwps, id->token, info->offset, - buf, sizeof(buf), &a); + out = get_token_value(gwps, SKINOFFSETTOPTR(skin_buffer, id->token), + info->offset, buf, sizeof(buf), &a); /* NOTE: get_token_value() returns values starting at 1! */ if (a == -1) @@ -224,29 +242,32 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info, } #ifdef HAVE_ALBUMART case SKIN_TOKEN_ALBUMART_DISPLAY: + { + struct skin_albumart *aa = SKINOFFSETTOPTR(skin_buffer, data->albumart); /* now draw the AA */ - if (do_refresh && data->albumart) + if (do_refresh && aa) { int handle = playback_current_aa_hid(data->playback_aa_slot); #if CONFIG_TUNER if (in_radio_screen() || (get_radio_status() != FMRADIO_OFF)) { - struct dim dim = {data->albumart->width, data->albumart->height}; + struct dim dim = {aa->width, aa->height}; handle = radio_get_art_hid(&dim); } #endif - data->albumart->draw_handle = handle; + aa->draw_handle = handle; } break; + } #endif case SKIN_TOKEN_DRAW_INBUILTBAR: gui_statusbar_draw(&(statusbars.statusbars[gwps->display->screen_type]), info->refresh_type == SKIN_REFRESH_ALL, - token->value.data); + SKINOFFSETTOPTR(skin_buffer, token->value.data)); break; case SKIN_TOKEN_VIEWPORT_CUSTOMLIST: if (do_refresh) - skin_render_playlistviewer(token->value.data, gwps, + skin_render_playlistviewer(SKINOFFSETTOPTR(skin_buffer, token->value.data), gwps, info->skin_vp, info->refresh_type); break; @@ -255,23 +276,24 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info, case SKIN_TOKEN_VAR_SET: if (do_refresh) { - struct skin_var_changer *data = token->value.data; + struct skin_var_changer *data = SKINOFFSETTOPTR(skin_buffer, token->value.data); + struct skin_var *var = SKINOFFSETTOPTR(skin_buffer, data->var); if (data->direct) - data->var->value = data->newval; + var->value = data->newval; else { - data->var->value += data->newval; + var->value += data->newval; if (data->max) { - if (data->var->value > data->max) - data->var->value = 1; - else if (data->var->value < 1) - data->var->value = data->max; + if (var->value > data->max) + var->value = 1; + else if (var->value < 1) + var->value = data->max; } } - if (data->var->value < 1) - data->var->value = 1; - data->var->last_changed = current_tick; + if (var->value < 1) + var->value = 1; + var->last_changed = current_tick; } break; #endif @@ -289,7 +311,7 @@ static void do_tags_in_hidden_conditional(struct skin_element* branch, #ifdef HAVE_LCD_BITMAP struct gui_wps *gwps = info->gwps; struct wps_data *data = gwps->data; -#endif +#endif /* Tags here are ones which need to be "turned off" or cleared * if they are in a conditional branch which isnt being used */ if (branch->type == LINE_ALTERNATOR) @@ -297,12 +319,12 @@ static void do_tags_in_hidden_conditional(struct skin_element* branch, int i; for (i=0; ichildren_count; i++) { - do_tags_in_hidden_conditional(branch->children[i], info); + do_tags_in_hidden_conditional(get_child(branch->children, i), info); } } else if (branch->type == LINE && branch->children_count) { - struct skin_element *child = branch->children[0]; + struct skin_element *child = get_child(branch->children, 0); #if defined(HAVE_LCD_BITMAP) || defined(HAVE_ALBUMART) struct wps_token *token; #endif @@ -313,25 +335,25 @@ static void do_tags_in_hidden_conditional(struct skin_element* branch, int i; for (i=0; ichildren_count; i++) { - do_tags_in_hidden_conditional(child->children[i], info); + do_tags_in_hidden_conditional(get_child(child->children, i), info); } - child = child->next; + child = SKINOFFSETTOPTR(skin_buffer, child->next); continue; } - else if (child->type != TAG || !child->data) + else if (child->type != TAG || !SKINOFFSETTOPTR(skin_buffer, child->data)) { - child = child->next; + child = SKINOFFSETTOPTR(skin_buffer, child->next); continue; } #if defined(HAVE_LCD_BITMAP) || defined(HAVE_ALBUMART) - token = (struct wps_token *)child->data; + token = (struct wps_token *)SKINOFFSETTOPTR(skin_buffer, child->data); #endif #ifdef HAVE_LCD_BITMAP /* clear all pictures in the conditional and nested ones */ if (token->type == SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY) { - struct image_display *id = token->value.data; - struct gui_img *img = skin_find_item(id->label, + struct image_display *id = SKINOFFSETTOPTR(skin_buffer, token->value.data); + struct gui_img *img = skin_find_item(SKINOFFSETTOPTR(skin_buffer, id->label), SKIN_FIND_IMAGE, data); clear_image_pos(gwps, img); } @@ -341,14 +363,18 @@ static void do_tags_in_hidden_conditional(struct skin_element* branch, } else if (token->type == SKIN_TOKEN_VIEWPORT_ENABLE) { - char *label = token->value.data; + char *label = SKINOFFSETTOPTR(skin_buffer, token->value.data); struct skin_element *viewport; - for (viewport = data->tree; + for (viewport = SKINOFFSETTOPTR(skin_buffer, data->tree); viewport; - viewport = viewport->next) + viewport = SKINOFFSETTOPTR(skin_buffer, viewport->next)) { - struct skin_viewport *skin_viewport = (struct skin_viewport*)viewport->data; - if (skin_viewport->label && strcmp(skin_viewport->label, label)) + struct skin_viewport *skin_viewport = SKINOFFSETTOPTR(skin_buffer, viewport->data); + + char *vplabel = SKINOFFSETTOPTR(skin_buffer, skin_viewport->label); + if (skin_viewport->label == VP_DEFAULT_LABEL) + vplabel = VP_DEFAULT_LABEL_STRING; + if (vplabel && strcmp(vplabel, label)) continue; if (skin_viewport->hidden_flags&VP_NEVER_VISIBLE) { @@ -377,7 +403,7 @@ static void do_tags_in_hidden_conditional(struct skin_element* branch, playback_current_aa_hid(data->playback_aa_slot), true); } #endif - child = child->next; + child = SKINOFFSETTOPTR(skin_buffer, child->next); } } } @@ -433,7 +459,7 @@ static bool skin_render_line(struct skin_element* line, struct skin_draw_info *i if (line->children_count == 0) return false; /* empty line, do nothing */ - struct skin_element *child = line->children[0]; + struct skin_element *child = get_child(line->children, 0); struct conditional *conditional; skin_render_func func = skin_render_line; int old_refresh_mode = info->refresh_type; @@ -442,7 +468,7 @@ static bool skin_render_line(struct skin_element* line, struct skin_draw_info *i switch (child->type) { case CONDITIONAL: - conditional = (struct conditional*)child->data; + conditional = SKINOFFSETTOPTR(skin_buffer, child->data); last_value = conditional->last_value; value = evaluate_conditional(info->gwps, info->offset, conditional, child->children_count); @@ -456,20 +482,20 @@ static bool skin_render_line(struct skin_element* line, struct skin_draw_info *i { /* we are in a false branch of a %?aa conditional */ if (last_value == 0) - do_tags_in_hidden_conditional(child->children[0], info); + do_tags_in_hidden_conditional(get_child(child->children, 0), info); break; } } else { if (last_value >= 0 && value != last_value && last_value < child->children_count) - do_tags_in_hidden_conditional(child->children[last_value], info); + do_tags_in_hidden_conditional(get_child(child->children, last_value), info); } - if (child->children[value]->type == LINE_ALTERNATOR) + if (get_child(child->children, value)->type == LINE_ALTERNATOR) { func = skin_render_alternator; } - else if (child->children[value]->type == LINE) + else if (get_child(child->children, value)->type == LINE) func = skin_render_line; if (value != last_value) @@ -478,7 +504,7 @@ static bool skin_render_line(struct skin_element* line, struct skin_draw_info *i info->force_redraw = true; } - if (func(child->children[value], info)) + if (func(get_child(child->children, value), info)) needs_update = true; else needs_update = needs_update || (last_value != value); @@ -493,14 +519,14 @@ static bool skin_render_line(struct skin_element* line, struct skin_draw_info *i fix_line_alignment(info, child); - if (!child->data) + if (!SKINOFFSETTOPTR(skin_buffer, child->data)) { break; } if (!do_non_text_tags(info->gwps, info, child, &info->skin_vp->vp)) { static char tempbuf[128]; - const char *valuestr = get_token_value(info->gwps, child->data, + const char *valuestr = get_token_value(info->gwps, SKINOFFSETTOPTR(skin_buffer, child->data), info->offset, tempbuf, sizeof(tempbuf), NULL); if (valuestr) @@ -517,7 +543,7 @@ static bool skin_render_line(struct skin_element* line, struct skin_draw_info *i } break; case TEXT: - strlcat(info->cur_align_start, child->data, + strlcat(info->cur_align_start, SKINOFFSETTOPTR(skin_buffer, child->data), info->buf_size - (info->cur_align_start-info->buf)); needs_update = needs_update || (info->refresh_type&SKIN_REFRESH_STATIC) != 0; @@ -527,7 +553,7 @@ static bool skin_render_line(struct skin_element* line, struct skin_draw_info *i break; } - child = child->next; + child = SKINOFFSETTOPTR(skin_buffer, child->next); } return needs_update; } @@ -541,29 +567,29 @@ static int get_subline_timeout(struct gui_wps *gwps, struct skin_element* line) { if (element->children_count == 0) return retval; /* empty line, so force redraw */ - element = element->children[0]; + element = get_child(element->children, 0); } while (element) { if (element->type == TAG && element->tag->type == SKIN_TOKEN_SUBLINE_TIMEOUT ) { - token = element->data; + token = SKINOFFSETTOPTR(skin_buffer, element->data); return token->value.i; } else if (element->type == CONDITIONAL) { - struct conditional *conditional = element->data; + struct conditional *conditional = SKINOFFSETTOPTR(skin_buffer, element->data); int val = evaluate_conditional(gwps, 0, conditional, element->children_count); if (val >= 0) { - retval = get_subline_timeout(gwps, element->children[val]); + retval = get_subline_timeout(gwps, get_child(element->children, val)); if (retval >= 0) return retval; } } - element = element->next; + element = SKINOFFSETTOPTR(skin_buffer, element->next); } return retval; } @@ -571,7 +597,7 @@ static int get_subline_timeout(struct gui_wps *gwps, struct skin_element* line) bool skin_render_alternator(struct skin_element* element, struct skin_draw_info *info) { bool changed_lines = false; - struct line_alternator *alternator = (struct line_alternator*)element->data; + struct line_alternator *alternator = SKINOFFSETTOPTR(skin_buffer, element->data); unsigned old_refresh = info->refresh_type; if (info->refresh_type == SKIN_REFRESH_ALL) { @@ -597,11 +623,11 @@ bool skin_render_alternator(struct skin_element* element, struct skin_draw_info try_line++; if (try_line >= element->children_count) try_line = 0; - if (element->children[try_line]->children_count != 0) + if (get_child(element->children, try_line)->children_count != 0) { - current_line = element->children[try_line]; + current_line = get_child(element->children, try_line); rettimeout = get_subline_timeout(info->gwps, - current_line->children[0]); + get_child(current_line->children, 0)); if (rettimeout > 0) { suitable = true; @@ -619,7 +645,7 @@ bool skin_render_alternator(struct skin_element* element, struct skin_draw_info info->refresh_type = SKIN_REFRESH_ALL; info->force_redraw = true; } - bool ret = skin_render_line(element->children[alternator->current_line], info); + bool ret = skin_render_line(get_child(element->children, alternator->current_line), info); info->refresh_type = old_refresh; return changed_lines || ret; } @@ -646,14 +672,17 @@ void skin_render_viewport(struct skin_element* viewport, struct gui_wps *gwps, struct align_pos * align = &info.align; bool needs_update; + skin_buffer = get_skin_buffer(gwps->data); + skinparser_set_buffer(skin_buffer); #ifdef HAVE_LCD_BITMAP /* Set images to not to be displayed */ - struct skin_token_list *imglist = gwps->data->images; + struct skin_token_list *imglist = SKINOFFSETTOPTR(skin_buffer, gwps->data->images); while (imglist) { - struct gui_img *img = (struct gui_img *)imglist->token->value.data; + struct wps_token *token = SKINOFFSETTOPTR(skin_buffer, imglist->token); + struct gui_img *img = (struct gui_img *)SKINOFFSETTOPTR(skin_buffer, token->value.data); img->display = -1; - imglist = imglist->next; + imglist = SKINOFFSETTOPTR(skin_buffer, imglist->next); } /* fix font ID's */ @@ -716,7 +745,7 @@ void skin_render_viewport(struct skin_element* viewport, struct gui_wps *gwps, } if (!info.no_line_break) info.line_number++; - line = line->next; + line = SKINOFFSETTOPTR(skin_buffer, line->next); } #ifdef HAVE_LCD_BITMAP wps_display_images(gwps, &skin_viewport->vp); @@ -730,8 +759,11 @@ void skin_render(struct gui_wps *gwps, unsigned refresh_mode) struct skin_element* viewport; struct skin_viewport* skin_viewport; + char *label; int old_refresh_mode = refresh_mode; + skin_buffer = get_skin_buffer(gwps->data); + skinparser_set_buffer(skin_buffer); #ifdef HAVE_LCD_CHARCELLS int i; @@ -741,18 +773,21 @@ void skin_render(struct gui_wps *gwps, unsigned refresh_mode) data->wps_progress_pat[i] = display->get_locked_pattern(); } #endif - viewport = data->tree; - skin_viewport = (struct skin_viewport *)viewport->data; - if (skin_viewport->label && viewport->next && - !strcmp(skin_viewport->label,VP_DEFAULT_LABEL)) + viewport = SKINOFFSETTOPTR(skin_buffer, data->tree); + skin_viewport = SKINOFFSETTOPTR(skin_buffer, viewport->data); + label = SKINOFFSETTOPTR(skin_buffer, skin_viewport->label); + if (skin_viewport->label == VP_DEFAULT_LABEL) + label = VP_DEFAULT_LABEL_STRING; + if (label && SKINOFFSETTOPTR(skin_buffer, viewport->next) && + !strcmp(label,VP_DEFAULT_LABEL_STRING)) refresh_mode = 0; - for (viewport = data->tree; + for (viewport = SKINOFFSETTOPTR(skin_buffer, data->tree); viewport; - viewport = viewport->next) + viewport = SKINOFFSETTOPTR(skin_buffer, viewport->next)) { /* SETUP */ - skin_viewport = (struct skin_viewport*)viewport->data; + skin_viewport = SKINOFFSETTOPTR(skin_buffer, viewport->data); unsigned vp_refresh_mode = refresh_mode; #if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1) skin_viewport->vp.fg_pattern = skin_viewport->start_fgcolour; @@ -789,7 +824,7 @@ void skin_render(struct gui_wps *gwps, unsigned refresh_mode) } /* render */ if (viewport->children_count) - skin_render_viewport(viewport->children[0], gwps, + skin_render_viewport(get_child(viewport->children, 0), gwps, skin_viewport, vp_refresh_mode); refresh_mode = old_refresh_mode; } @@ -826,7 +861,7 @@ void skin_render_playlistviewer(struct playlistviewer* viewer, struct align_pos * align = &info.align; bool needs_update; int cur_pos, start_item, max; - int nb_lines = viewport_get_nb_lines(viewer->vp); + int nb_lines = viewport_get_nb_lines(SKINOFFSETTOPTR(skin_buffer, viewer->vp)); #if CONFIG_TUNER if (get_current_activity() == ACTIVITY_FM) { @@ -848,7 +883,7 @@ void skin_render_playlistviewer(struct playlistviewer* viewer, if (max-start_item > nb_lines) max = start_item + nb_lines; - line = viewer->line; + line = SKINOFFSETTOPTR(skin_buffer, viewer->line); while (start_item < max) { linebuf[0] = '\0'; diff --git a/apps/gui/skin_engine/skin_tokens.c b/apps/gui/skin_engine/skin_tokens.c index 6f154a4d53..bb9466c134 100644 --- a/apps/gui/skin_engine/skin_tokens.c +++ b/apps/gui/skin_engine/skin_tokens.c @@ -36,6 +36,7 @@ #include "debug.h" #include "cuesheet.h" #include "replaygain.h" +#include "core_alloc.h" #ifdef HAVE_LCD_CHARCELLS #include "hwcompat.h" #endif @@ -732,18 +733,21 @@ static const char* NOINLINE get_lif_token_value(struct gui_wps *gwps, { int a = lif->num_options; int b; - const char* out_text = get_token_value(gwps, lif->token, offset, - buf, buf_size, &a); - if (a == -1 && lif->token->type != SKIN_TOKEN_VOLUME) + struct wps_token *liftoken = SKINOFFSETTOPTR(get_skin_buffer(gwps->data), lif->token); + const char* out_text = get_token_value(gwps, liftoken, offset, buf, buf_size, &a); + if (a == -1 && liftoken->type != SKIN_TOKEN_VOLUME) a = (out_text && *out_text) ? 1 : 0; switch (lif->operand.type) { case STRING: + { + char *cmp = SKINOFFSETTOPTR(get_skin_buffer(gwps->data), lif->operand.data.text); if (out_text == NULL) return NULL; - a = strcmp(out_text, lif->operand.data.text); + a = strcmp(out_text, cmp); b = 0; break; + } case INTEGER: case DECIMAL: b = lif->operand.data.number; @@ -752,11 +756,12 @@ static const char* NOINLINE get_lif_token_value(struct gui_wps *gwps, { char temp_buf[MAX_PATH]; const char *outb; - struct wps_token *token = lif->operand.data.code->data; + struct skin_element *element = SKINOFFSETTOPTR(get_skin_buffer(gwps->data), lif->operand.data.code); + struct wps_token *token = SKINOFFSETTOPTR(get_skin_buffer(gwps->data), element->data); b = lif->num_options; outb = get_token_value(gwps, token, offset, temp_buf, sizeof(temp_buf), &b); - if (b == -1 && lif->token->type != SKIN_TOKEN_VOLUME) + if (b == -1 && liftoken->type != SKIN_TOKEN_VOLUME) { if (!out_text || !outb) return (lif->op == IF_EQUALS) ? NULL : "neq"; @@ -865,14 +870,15 @@ const char *get_token_value(struct gui_wps *gwps, { case SKIN_TOKEN_LOGICAL_IF: { - struct logical_if *lif = token->value.data; + struct logical_if *lif = SKINOFFSETTOPTR(get_skin_buffer(data), token->value.data); return get_lif_token_value(gwps, lif, offset, buf, buf_size); } break; case SKIN_TOKEN_SUBSTRING: { - struct substring *ss = token->value.data; - const char *token_val = get_token_value(gwps, ss->token, offset, + struct substring *ss = SKINOFFSETTOPTR(get_skin_buffer(data), token->value.data); + const char *token_val = get_token_value(gwps, + SKINOFFSETTOPTR(get_skin_buffer(data), ss->token), offset, buf, buf_size, intval); if (token_val) { @@ -909,7 +915,7 @@ const char *get_token_value(struct gui_wps *gwps, return &(token->value.c); case SKIN_TOKEN_STRING: - return (char*)token->value.data; + return (char*)SKINOFFSETTOPTR(get_skin_buffer(data), token->value.data); case SKIN_TOKEN_TRANSLATEDSTRING: return (char*)P2STR(ID2P(token->value.i)); @@ -929,7 +935,7 @@ const char *get_token_value(struct gui_wps *gwps, return buf; case SKIN_TOKEN_LIST_ITEM_TEXT: { - struct listitem *li = (struct listitem *)token->value.data; + struct listitem *li = (struct listitem *)SKINOFFSETTOPTR(get_skin_buffer(data), token->value.data); return skinlist_get_item_text(li->offset, li->wrap, buf, buf_size); } case SKIN_TOKEN_LIST_ITEM_NUMBER: @@ -941,7 +947,7 @@ const char *get_token_value(struct gui_wps *gwps, return skinlist_is_selected_item()?"s":""; case SKIN_TOKEN_LIST_ITEM_ICON: { - struct listitem *li = (struct listitem *)token->value.data; + struct listitem *li = (struct listitem *)SKINOFFSETTOPTR(get_skin_buffer(data), token->value.data); int icon = skinlist_get_item_icon(li->offset, li->wrap); if (intval) *intval = icon; @@ -997,14 +1003,15 @@ const char *get_token_value(struct gui_wps *gwps, return buf; #ifdef HAVE_ALBUMART case SKIN_TOKEN_ALBUMART_FOUND: - if (data->albumart) + if (SKINOFFSETTOPTR(get_skin_buffer(data), data->albumart)) { int handle = -1; handle = playback_current_aa_hid(data->playback_aa_slot); #if CONFIG_TUNER if (in_radio_screen() || (get_radio_status() != FMRADIO_OFF)) { - struct dim dim = {data->albumart->width, data->albumart->height}; + struct skin_albumart *aa = SKINOFFSETTOPTR(get_skin_buffer(data), data->albumart); + struct dim dim = {aa->width, aa->height}; handle = radio_get_art_hid(&dim); } #endif @@ -1473,9 +1480,11 @@ const char *get_token_value(struct gui_wps *gwps, { #ifdef HAVE_TOUCHSCREEN unsigned int last_touch = touchscreen_last_touch(); - struct touchregion_lastpress *data = token->value.data; - if (data->region) - last_touch = data->region->last_press; + char *skin_base = get_skin_buffer(data); + struct touchregion_lastpress *data = SKINOFFSETTOPTR(skin_base, token->value.data); + struct touchregion *region = SKINOFFSETTOPTR(skin_base, data->region); + if (region) + last_touch = region->last_press; if (last_touch != 0xffff && TIME_BEFORE(current_tick, data->timeout + last_touch)) @@ -1805,7 +1814,8 @@ const char *get_token_value(struct gui_wps *gwps, #ifdef HAVE_SKIN_VARIABLES case SKIN_TOKEN_VAR_GETVAL: { - struct skin_var* var = token->value.data; + char *skin_base = get_skin_buffer(data); + struct skin_var* var = SKINOFFSETTOPTR(skin_base, token->value.data); if (intval) *intval = var->value; snprintf(buf, buf_size, "%d", var->value); @@ -1814,8 +1824,10 @@ const char *get_token_value(struct gui_wps *gwps, break; case SKIN_TOKEN_VAR_TIMEOUT: { - struct skin_var_lastchange *data = token->value.data; - unsigned int last_change = data->var->last_changed; + char *skin_base = get_skin_buffer(data); + struct skin_var_lastchange *data = SKINOFFSETTOPTR(skin_base, token->value.data); + struct skin_var* var = SKINOFFSETTOPTR(skin_base, data->var); + unsigned int last_change = var->last_changed; if (last_change != 0xffff && TIME_BEFORE(current_tick, data->timeout + last_change)) diff --git a/apps/gui/skin_engine/skin_tokens.h b/apps/gui/skin_engine/skin_tokens.h deleted file mode 100644 index bfca7b7f8d..0000000000 --- a/apps/gui/skin_engine/skin_tokens.h +++ /dev/null @@ -1,49 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2007 Nicolas Pennequin - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -#ifndef _SKIN_TOKENS_H_ -#define _SKIN_TOKENS_H_ - -#include -#include "tag_table.h" - -struct wps_token { - union { - char c; - unsigned short i; - long l; - void* data; - } value; - - enum skin_token_type type; /* enough to store the token type */ - /* Whether the tag (e.g. track name or the album) refers the - current or the next song (false=current, true=next) */ - bool next; -}; - -struct skin_token_list { - struct wps_token *token; - struct skin_token_list *next; -}; - -char* get_dir(char* buf, int buf_size, const char* path, int level); - -#endif diff --git a/apps/gui/skin_engine/skin_touchsupport.c b/apps/gui/skin_engine/skin_touchsupport.c index 64c797942c..59687bd99b 100644 --- a/apps/gui/skin_engine/skin_touchsupport.c +++ b/apps/gui/skin_engine/skin_touchsupport.c @@ -37,11 +37,14 @@ /** Disarms all touchregions. */ void skin_disarm_touchregions(struct wps_data *data) { - struct skin_token_list *regions = data->touchregions; + char* skin_buffer = get_skin_buffer(data); + struct skin_token_list *regions = SKINOFFSETTOPTR(skin_buffer, data->touchregions); while (regions) { - ((struct touchregion *)regions->token->value.data)->armed = false; - regions = regions->next; + struct wps_token *token = SKINOFFSETTOPTR(skin_buffer, regions->token); + struct touchregion *region = SKINOFFSETTOPTR(skin_buffer, token->value.data); + region->armed = false; + regions = SKINOFFSETTOPTR(skin_buffer, regions->next); } } @@ -56,35 +59,39 @@ int skin_get_touchaction(struct wps_data *data, int* edge_offset, short x,y; short vx, vy; int type = action_get_touchscreen_press(&x, &y); + struct skin_viewport *wvp; struct touchregion *r, *temp = NULL; + char* skin_buffer = get_skin_buffer(data); bool repeated = (type == BUTTON_REPEAT); bool released = (type == BUTTON_REL); bool pressed = (type == BUTTON_TOUCHSCREEN); - struct skin_token_list *regions = data->touchregions; + struct skin_token_list *regions = SKINOFFSETTOPTR(skin_buffer, data->touchregions); bool needs_repeat; while (regions) { - r = (struct touchregion *)regions->token->value.data; + struct wps_token *token = SKINOFFSETTOPTR(skin_buffer, regions->token); + r = SKINOFFSETTOPTR(skin_buffer, token->value.data); + wvp = SKINOFFSETTOPTR(skin_buffer, r->wvp); /* make sure this region's viewport is visible */ - if (r->wvp->hidden_flags&VP_DRAW_HIDDEN) + if (wvp->hidden_flags&VP_DRAW_HIDDEN) { - regions = regions->next; + regions = SKINOFFSETTOPTR(skin_buffer, regions->next); continue; } if (data->touchscreen_locked && (r->action != ACTION_TOUCH_SOFTLOCK && !r->allow_while_locked)) { - regions = regions->next; + regions = SKINOFFSETTOPTR(skin_buffer, regions->next); continue; } needs_repeat = r->press_length != PRESS; /* check if it's inside this viewport */ - if (viewport_point_within_vp(&(r->wvp->vp), x, y)) + if (viewport_point_within_vp(&(wvp->vp), x, y)) { /* reposition the touch inside the viewport since touchregions * are relative to a preceding viewport */ - vx = x - r->wvp->vp.x; - vy = y - r->wvp->vp.y; + vx = x - wvp->vp.x; + vy = y - wvp->vp.y; /* now see if the point is inside this region */ if (vx >= r->x && vx < r->x+r->width && vy >= r->y && vy < r->y+r->height) @@ -127,7 +134,7 @@ int skin_get_touchaction(struct wps_data *data, int* edge_offset, } } } - regions = regions->next; + regions = SKINOFFSETTOPTR(skin_buffer, regions->next); } /* On release, all regions are disarmed. */ @@ -214,7 +221,7 @@ int skin_get_touchaction(struct wps_data *data, int* edge_offset, { case F_T_CUSTOM: s->custom_setting - ->load_from_cfg(s->setting, data->value.text); + ->load_from_cfg(s->setting, SKINOFFSETTOPTR(skin_buffer, data->value.text)); break; case F_T_INT: case F_T_UINT: diff --git a/apps/gui/skin_engine/wps_internals.h b/apps/gui/skin_engine/wps_internals.h index ed09ad0938..65a063592f 100644 --- a/apps/gui/skin_engine/wps_internals.h +++ b/apps/gui/skin_engine/wps_internals.h @@ -25,6 +25,11 @@ #ifndef _WPS_ENGINE_INTERNALS_ #define _WPS_ENGINE_INTERNALS_ +#include "tag_table.h" +#include "skin_parser.h" +#ifndef __PCTOOL__ +#include "core_alloc.h" +#endif /* Timeout unit expressed in HZ. In WPS, all timeouts are given in seconds (possibly with a decimal fraction) but stored as integer values. @@ -33,52 +38,48 @@ #define TIMEOUT_UNIT (HZ/10) /* I.e. 0.1 sec */ #define DEFAULT_SUBLINE_TIME_MULTIPLIER 20 /* In TIMEOUT_UNIT's */ -#include "skin_tokens.h" -#include "tag_table.h" -#include "skin_parser.h" - - /* TODO: sort this mess out */ #include "screen_access.h" #include "statusbar.h" #include "metadata.h" -/* alignments */ -#define WPS_ALIGN_RIGHT 32 -#define WPS_ALIGN_CENTER 64 -#define WPS_ALIGN_LEFT 128 - #define TOKEN_VALUE_ONLY 0x0DEADC0D -#ifdef HAVE_ALBUMART - -/* albumart definitions */ -#define WPS_ALBUMART_NONE 0 /* WPS does not contain AA tag */ -#define WPS_ALBUMART_CHECK 1 /* WPS contains AA conditional tag */ -#define WPS_ALBUMART_LOAD 2 /* WPS contains AA tag */ - -#define WPS_ALBUMART_ALIGN_RIGHT 1 /* x align: right */ -#define WPS_ALBUMART_ALIGN_CENTER 2 /* x/y align: center */ -#define WPS_ALBUMART_ALIGN_LEFT 4 /* x align: left */ -#define WPS_ALBUMART_ALIGN_TOP 1 /* y align: top */ -#define WPS_ALBUMART_ALIGN_BOTTOM 4 /* y align: bottom */ - -#endif /* HAVE_ALBUMART */ - /* wps_data*/ +struct wps_token { + union { + char c; + unsigned short i; + long l; + OFFSETTYPE(void*) data; + } value; + + enum skin_token_type type; /* enough to store the token type */ + /* Whether the tag (e.g. track name or the album) refers the + current or the next song (false=current, true=next) */ + bool next; +}; + +char* get_dir(char* buf, int buf_size, const char* path, int level); + + +struct skin_token_list { + OFFSETTYPE(struct wps_token *) token; + OFFSETTYPE(struct skin_token_list *) next; +}; #ifdef HAVE_LCD_BITMAP struct gui_img { - struct viewport* vp; /* The viewport to display this image in */ + OFFSETTYPE(struct viewport*) vp; /* The viewport to display this image in */ short int x; /* x-pos */ short int y; /* y-pos */ short int num_subimages; /* number of sub-images */ short int subimage_height; /* height of each sub-image */ struct bitmap bm; int buflib_handle; - const char *label; + OFFSETTYPE(char*) label; bool loaded; /* load state */ bool always_display; /* not using the preload/display mechanism */ int display; @@ -86,15 +87,15 @@ struct gui_img { }; struct image_display { - const char *label; + OFFSETTYPE(char*) label; int subimage; - struct wps_token *token; /* the token to get the subimage number from */ + OFFSETTYPE(struct wps_token*) token; /* the token to get the subimage number from */ int offset; /* offset into the bitmap strip to start */ }; struct progressbar { enum skin_token_type type; - struct viewport *vp; + OFFSETTYPE(struct viewport *) vp; /* regular pb */ short x; /* >=0: explicitly set in the tag -> y-coord within the viewport @@ -105,14 +106,14 @@ struct progressbar { short height; bool follow_lang_direction; - struct gui_img *image; + OFFSETTYPE(struct gui_img *) image; bool invert_fill_direction; bool nofill; bool nobar; - struct gui_img *slider; + OFFSETTYPE(struct gui_img *) slider; bool horizontal; - struct gui_img *backdrop; + OFFSETTYPE(struct gui_img *) backdrop; }; #endif @@ -125,35 +126,11 @@ struct align_pos { }; #ifdef HAVE_LCD_BITMAP - -#define MAX_IMAGES (26*2) /* a-z and A-Z */ -#define MAX_PROGRESSBARS 3 - -/* The image buffer is big enough to store one full-screen native bitmap, - plus two full-screen mono bitmaps. */ - -#define WPS_MAX_VIEWPORTS 24 -#define WPS_MAX_LINES ((LCD_HEIGHT/5+1) * 2) -#define WPS_MAX_SUBLINES (WPS_MAX_LINES*3) #define WPS_MAX_TOKENS 1150 -#define WPS_MAX_STRINGS 128 -#define STRING_BUFFER_SIZE 1024 -#define WPS_MAX_COND_LEVEL 10 - #else - -#define WPS_MAX_VIEWPORTS 2 -#define WPS_MAX_LINES 2 -#define WPS_MAX_SUBLINES 12 #define WPS_MAX_TOKENS 64 -#define WPS_MAX_STRINGS 32 -#define STRING_BUFFER_SIZE 64 -#define WPS_MAX_COND_LEVEL 5 - #endif -#define SUBLINE_RESET -1 - enum wps_parse_error { PARSE_OK, PARSE_FAIL_UNCLOSED_COND, @@ -176,12 +153,17 @@ struct gradient_config { #define VP_DRAW_WASHIDDEN 0x4 /* these are never drawn, nor cleared, i.e. just ignored */ #define VP_NEVER_VISIBLE 0x8 -#define VP_DEFAULT_LABEL "|" +#ifndef __PCTOOL__ +#define VP_DEFAULT_LABEL -200 +#else +#define VP_DEFAULT_LABEL NULL +#endif +#define VP_DEFAULT_LABEL_STRING "|" struct skin_viewport { struct viewport vp; /* The LCD viewport struct */ char hidden_flags; bool is_infovp; - char* label; + OFFSETTYPE(char*) label; int parsed_fontid; #if LCD_DEPTH > 1 unsigned start_fgcolour; @@ -192,14 +174,14 @@ struct skin_viewport { #endif }; struct viewport_colour { - struct viewport *vp; + OFFSETTYPE(struct viewport *) vp; unsigned colour; }; #ifdef HAVE_TOUCHSCREEN struct touchregion { - char* label; /* label to identify this region */ - struct skin_viewport* wvp;/* The viewport this region is in */ + OFFSETTYPE(char*) label; /* label to identify this region */ + OFFSETTYPE(struct skin_viewport*) wvp;/* The viewport this region is in */ short int x; /* x-pos */ short int y; /* y-pos */ short int width; /* width */ @@ -219,7 +201,7 @@ struct touchregion { const struct settings_list *setting; /* setting being controlled */ union { /* Value to set the setting to for ACTION_SETTING_SET */ int number; - char* text; + OFFSETTYPE(char*) text; } value; } setting_data; int value; @@ -230,20 +212,32 @@ struct touchregion { struct touchregion_lastpress { - struct touchregion *region; + OFFSETTYPE(struct touchregion *) region; long timeout; }; #endif struct playlistviewer { - struct viewport *vp; + OFFSETTYPE(struct viewport *) vp; bool show_icons; int start_offset; - struct skin_element *line; + OFFSETTYPE(struct skin_element *) line; }; #ifdef HAVE_ALBUMART + +/* albumart definitions */ +#define WPS_ALBUMART_NONE 0 /* WPS does not contain AA tag */ +#define WPS_ALBUMART_CHECK 1 /* WPS contains AA conditional tag */ +#define WPS_ALBUMART_LOAD 2 /* WPS contains AA tag */ + +#define WPS_ALBUMART_ALIGN_RIGHT 1 /* x align: right */ +#define WPS_ALBUMART_ALIGN_CENTER 2 /* x/y align: center */ +#define WPS_ALBUMART_ALIGN_LEFT 4 /* x align: left */ +#define WPS_ALBUMART_ALIGN_TOP 1 /* y align: top */ +#define WPS_ALBUMART_ALIGN_BOTTOM 4 /* y align: bottom */ + struct skin_albumart { /* Album art support */ int x; @@ -255,7 +249,7 @@ struct skin_albumart { unsigned char yalign; /* WPS_ALBUMART_ALIGN_TOP, _CENTER, _BOTTOM */ unsigned char state; /* WPS_ALBUMART_NONE, _CHECK, _LOAD */ - struct viewport *vp; + OFFSETTYPE(struct viewport *) vp; int draw_handle; }; #endif @@ -272,11 +266,11 @@ struct line_alternator { struct conditional { int last_value; - struct wps_token *token; + OFFSETTYPE(struct wps_token *) token; }; struct logical_if { - struct wps_token *token; + OFFSETTYPE(struct wps_token *) token; enum { IF_EQUALS, /* == */ IF_NOTEQUALS, /* != */ @@ -292,7 +286,7 @@ struct logical_if { struct substring { int start; int length; - struct wps_token *token; + OFFSETTYPE(struct wps_token *) token; }; struct listitem { @@ -302,16 +296,16 @@ struct listitem { #ifdef HAVE_SKIN_VARIABLES struct skin_var { - const char *label; + OFFSETTYPE(const char *) label; int value; long last_changed; }; struct skin_var_lastchange { - struct skin_var *var; + OFFSETTYPE(struct skin_var *) var; long timeout; }; struct skin_var_changer { - struct skin_var *var; + OFFSETTYPE(struct skin_var *) var; int newval; bool direct; /* true to make val=newval, false for val += newval */ int max; @@ -323,30 +317,29 @@ struct skin_var_changer { viewable content of a wps */ struct wps_data { - struct skin_element *tree; + int buflib_handle; + + OFFSETTYPE(struct skin_element *) tree; #ifdef HAVE_LCD_BITMAP - struct skin_token_list *images; - int *font_ids; + OFFSETTYPE(struct skin_token_list *) images; + OFFSETTYPE(int *) font_ids; int font_count; #endif #if LCD_DEPTH > 1 || defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1 - struct { - char *backdrop; - int backdrop_id; - }; + int backdrop_id; #endif #ifdef HAVE_TOUCHSCREEN - struct skin_token_list *touchregions; + OFFSETTYPE(struct skin_token_list *) touchregions; bool touchscreen_locked; #endif #ifdef HAVE_ALBUMART - struct skin_albumart *albumart; + OFFSETTYPE(struct skin_albumart *) albumart; int playback_aa_slot; #endif #ifdef HAVE_SKIN_VARIABLES - struct skin_token_list *skinvars; + OFFSETTYPE(struct skin_token_list *) skinvars; #endif #ifdef HAVE_LCD_BITMAP @@ -360,6 +353,17 @@ struct wps_data bool wps_loaded; }; +#ifndef __PCTOOL__ +static inline char* get_skin_buffer(struct wps_data* data) +{ + if (data->buflib_handle >= 0) + return core_get_data(data->buflib_handle); + return NULL; +} +#else +#define get_skin_buffer(d) skin_buffer +#endif + /* wps_data end */ /* wps_state diff --git a/apps/gui/statusbar-skinned.c b/apps/gui/statusbar-skinned.c index f79672c0d9..960cf67d4d 100644 --- a/apps/gui/statusbar-skinned.c +++ b/apps/gui/statusbar-skinned.c @@ -87,8 +87,9 @@ int sb_postproccess(enum screen_type screen, struct wps_data *data) /* hide the sb's default viewport because it has nasty effect with stuff * not part of the statusbar, * hence .sbs's without any other vps are unsupported*/ - struct skin_viewport *vp = skin_find_item(VP_DEFAULT_LABEL, SKIN_FIND_VP, data); - struct skin_element *next_vp = data->tree->next; + struct skin_viewport *vp = skin_find_item(VP_DEFAULT_LABEL_STRING, SKIN_FIND_VP, data); + struct skin_element *tree = SKINOFFSETTOPTR(get_skin_buffer(data), data->tree); + struct skin_element *next_vp = SKINOFFSETTOPTR(get_skin_buffer(data), tree->next); if (vp) { @@ -105,9 +106,9 @@ int sb_postproccess(enum screen_type screen, struct wps_data *data) return 1; } -static char *infovp_label[NB_SCREENS]; -static char *oldinfovp_label[NB_SCREENS]; -void sb_set_info_vp(enum screen_type screen, char *label) +static OFFSETTYPE(char*) infovp_label[NB_SCREENS]; +static OFFSETTYPE(char*) oldinfovp_label[NB_SCREENS]; +void sb_set_info_vp(enum screen_type screen, OFFSETTYPE(char*) label) { infovp_label[screen] = label; } @@ -116,15 +117,19 @@ struct viewport *sb_skin_get_info_vp(enum screen_type screen) { struct wps_data *data = skin_get_gwps(CUSTOM_STATUSBAR, screen)->data; struct skin_viewport *vp = NULL; + char *label; if (oldinfovp_label[screen] && - strcmp(oldinfovp_label[screen], infovp_label[screen])) + (oldinfovp_label[screen] != infovp_label[screen])) { /* UI viewport changed, so force a redraw */ oldinfovp_label[screen] = infovp_label[screen]; viewportmanager_theme_enable(screen, false, NULL); viewportmanager_theme_undo(screen, true); } - vp = skin_find_item(infovp_label[screen], SKIN_FIND_UIVP, data); + label = SKINOFFSETTOPTR(get_skin_buffer(data), infovp_label[screen]); + if (infovp_label[screen] == VP_DEFAULT_LABEL) + label = VP_DEFAULT_LABEL_STRING; + vp = skin_find_item(label, SKIN_FIND_UIVP, data); if (!vp) return NULL; if (vp->parsed_fontid == 1) @@ -270,7 +275,7 @@ void sb_skin_init(void) { FOR_NB_SCREENS(i) { - oldinfovp_label[i] = NULL; + oldinfovp_label[i] = VP_DEFAULT_LABEL; } } diff --git a/apps/gui/statusbar-skinned.h b/apps/gui/statusbar-skinned.h index bfd8193110..ac12dfa1aa 100644 --- a/apps/gui/statusbar-skinned.h +++ b/apps/gui/statusbar-skinned.h @@ -36,7 +36,7 @@ void sb_skin_data_load(enum screen_type screen, const char *buf, bool isfile); char* sb_create_from_settings(enum screen_type screen); void sb_skin_init(void) INIT_ATTR; -void sb_set_info_vp(enum screen_type screen, char *label); +void sb_set_info_vp(enum screen_type screen, OFFSETTYPE(char*) label); struct viewport *sb_skin_get_info_vp(enum screen_type screen); void sb_skin_update(enum screen_type screen, bool force); diff --git a/apps/gui/wps.c b/apps/gui/wps.c index 6486e42fbb..97c945d0e8 100644 --- a/apps/gui/wps.c +++ b/apps/gui/wps.c @@ -667,7 +667,7 @@ static void gwps_enter_wps(void) #if LCD_DEPTH > 1 if (display->depth > 1) { - struct skin_viewport *svp = skin_find_item(VP_DEFAULT_LABEL, + struct skin_viewport *svp = skin_find_item(VP_DEFAULT_LABEL_STRING, SKIN_FIND_VP, gwps->data); if (svp) { diff --git a/apps/lang/basque.lang b/apps/lang/basque.lang index f0cc1ee1c3..8a9de4b385 100644 --- a/apps/lang/basque.lang +++ b/apps/lang/basque.lang @@ -11502,16 +11502,16 @@ id: LANG_SKIN_RAM_USAGE - desc: how much RAM the skins are using + desc: deprecated user: core - *: "Skin RAM usage:" + *: "" - *: "Azalaren RAM erabilera:" + *: "" - *: "Azalaren RAM erabilera:" + *: "" diff --git a/apps/lang/bulgarian.lang b/apps/lang/bulgarian.lang index ad88cd77cc..257389c36e 100644 --- a/apps/lang/bulgarian.lang +++ b/apps/lang/bulgarian.lang @@ -12255,16 +12255,16 @@ id: LANG_SKIN_RAM_USAGE - desc: how much RAM the skins are using + desc: deprecated user: core - *: "Skin RAM usage:" + *: "" - *: "Използвана RAM от скина:" + *: "" - *: "Използвана RAM от скина" + *: "" diff --git a/apps/lang/catala.lang b/apps/lang/catala.lang index e4abf581cc..aabcb931ff 100644 --- a/apps/lang/catala.lang +++ b/apps/lang/catala.lang @@ -11494,16 +11494,16 @@ id: LANG_SKIN_RAM_USAGE - desc: how much RAM the skins are using + desc: deprecated user: core - *: "Skin RAM usage:" + *: "" - *: "Ús de RAM per part del tema:" + *: "" - *: "Ús de RAM per part del tema" + *: "" diff --git a/apps/lang/chinese-simp.lang b/apps/lang/chinese-simp.lang index fb0408d472..7319071903 100644 --- a/apps/lang/chinese-simp.lang +++ b/apps/lang/chinese-simp.lang @@ -11821,16 +11821,16 @@ id: LANG_SKIN_RAM_USAGE - desc: how much RAM the skins are using + desc: deprecated user: core - *: "Skin RAM usage:" + *: "" - *: "Skin RAM usage:" + *: "" - *: "Skin RAM usage" + *: "" diff --git a/apps/lang/czech.lang b/apps/lang/czech.lang index 3d9557d4cb..00a89b87ff 100644 --- a/apps/lang/czech.lang +++ b/apps/lang/czech.lang @@ -11504,16 +11504,16 @@ id: LANG_SKIN_RAM_USAGE - desc: how much RAM the skins are using + desc: deprecated user: core - *: "Skin RAM usage:" + *: "" - *: "Využití RAM pro skiny:" + *: "" - *: "Využití RAM pro skiny" + *: "" diff --git a/apps/lang/dansk.lang b/apps/lang/dansk.lang index 2c89ccdc4c..d99cbc9003 100644 --- a/apps/lang/dansk.lang +++ b/apps/lang/dansk.lang @@ -11446,16 +11446,16 @@ id: LANG_SKIN_RAM_USAGE - desc: how much RAM the skins are using + desc: deprecated user: core - *: "Skin RAM usage:" + *: "" - *: "Temas RAM-forbrug:" + *: "" - *: "Temas RAM-forbrug" + *: "" diff --git a/apps/lang/deutsch.lang b/apps/lang/deutsch.lang index ae7867bf20..d565effb03 100644 --- a/apps/lang/deutsch.lang +++ b/apps/lang/deutsch.lang @@ -11445,16 +11445,16 @@ id: LANG_SKIN_RAM_USAGE - desc: how much RAM the skins are using + desc: deprecated user: core - *: "Skin RAM usage:" + *: "" - *: "Themen-Speicher:" + *: "" - *: "Themen-Speicher" + *: "" diff --git a/apps/lang/english-us.lang b/apps/lang/english-us.lang index 9a7c8786e7..16af129376 100644 --- a/apps/lang/english-us.lang +++ b/apps/lang/english-us.lang @@ -11500,16 +11500,16 @@ id: LANG_SKIN_RAM_USAGE - desc: how much RAM the skins are using + desc: deprecated user: core - *: "Skin RAM usage:" + *: "" - *: "Skin RAM usage:" + *: "" - *: "Skin RAM usage" + *: "" diff --git a/apps/lang/english.lang b/apps/lang/english.lang index 741f120023..de541af1f5 100644 --- a/apps/lang/english.lang +++ b/apps/lang/english.lang @@ -11587,16 +11587,16 @@ id: LANG_SKIN_RAM_USAGE - desc: how much RAM the skins are using + desc: deprecated user: core - *: "Skin RAM usage:" + *: "" - *: "Skin RAM usage:" + *: "" - *: "Skin RAM usage" + *: "" diff --git a/apps/lang/espanol.lang b/apps/lang/espanol.lang index d1b484413f..f12fb2ec70 100644 --- a/apps/lang/espanol.lang +++ b/apps/lang/espanol.lang @@ -11816,16 +11816,16 @@ id: LANG_SKIN_RAM_USAGE - desc: how much RAM the skins are using + desc: deprecated user: core - *: "Skin RAM usage:" + *: "" - *: "Uso de RAM de la piel:" + *: "" - *: "Uso de RAM de la piel" + *: "" diff --git a/apps/lang/finnish.lang b/apps/lang/finnish.lang index a2ab55101f..0855a5f04c 100644 --- a/apps/lang/finnish.lang +++ b/apps/lang/finnish.lang @@ -11383,16 +11383,16 @@ id: LANG_SKIN_RAM_USAGE - desc: how much RAM the skins are using + desc: deprecated user: core - *: "Skin RAM usage:" + *: "" - *: "Nahan käyttämä RAM-muisti:" + *: "" - *: "Nahan käyttämä RAM-muisti" + *: "" diff --git a/apps/lang/francais.lang b/apps/lang/francais.lang index ff94abfc92..9ad6e92073 100644 --- a/apps/lang/francais.lang +++ b/apps/lang/francais.lang @@ -11528,16 +11528,16 @@ id: LANG_SKIN_RAM_USAGE - desc: how much RAM the skins are using + desc: deprecated user: core - *: "Skin RAM usage:" + *: "" - *: "Tampon du thème:" + *: "" - *: "Tampon du thème utilisé" + *: "" diff --git a/apps/lang/galego.lang b/apps/lang/galego.lang index 4d390a30e9..a137f6888f 100644 --- a/apps/lang/galego.lang +++ b/apps/lang/galego.lang @@ -10883,16 +10883,16 @@ ipod*,iaudiox5,iaudiom5,iriverh10,iriverh10_5gb,sansae200*,sansac200*,gigabeat*, id: LANG_SKIN_RAM_USAGE - desc: how much RAM the skins are using + desc: deprecated user: core - *: "Skin RAM usage:" + *: "" - *: "Uso de RAM pola skin:" + *: "" - *: "Uso de RAM pola skin" + *: "" diff --git a/apps/lang/hebrew.lang b/apps/lang/hebrew.lang index 30ce32f793..100a5f66ac 100644 --- a/apps/lang/hebrew.lang +++ b/apps/lang/hebrew.lang @@ -11509,16 +11509,16 @@ id: LANG_SKIN_RAM_USAGE - desc: how much RAM the skins are using + desc: deprecated user: core - *: "Skin RAM usage:" + *: "" - *: "Skin RAM usage:" + *: "" - *: "Skin RAM usage" + *: "" diff --git a/apps/lang/hrvatski.lang b/apps/lang/hrvatski.lang index cc45c157bf..1dbfc620c1 100644 --- a/apps/lang/hrvatski.lang +++ b/apps/lang/hrvatski.lang @@ -11503,16 +11503,16 @@ id: LANG_SKIN_RAM_USAGE - desc: how much RAM the skins are using + desc: deprecated user: core - *: "Skin RAM usage:" + *: "" - *: "Korištenje RAM-a presvlake:" + *: "" - *: "Korištenje RAM-a presvlake" + *: "" diff --git a/apps/lang/italiano.lang b/apps/lang/italiano.lang index 0450f2280d..ddb18039e1 100644 --- a/apps/lang/italiano.lang +++ b/apps/lang/italiano.lang @@ -11504,16 +11504,16 @@ desc: deprecated id: LANG_SKIN_RAM_USAGE - desc: how much RAM the skins are using + desc: deprecated user: core - *: "Skin RAM usage:" + *: "" - *: "RAM usata per Skin:" + *: "" - *: "RAM usata per Skin" + *: "" diff --git a/apps/lang/japanese.lang b/apps/lang/japanese.lang index a1d6039979..3a62826d28 100644 --- a/apps/lang/japanese.lang +++ b/apps/lang/japanese.lang @@ -11509,16 +11509,16 @@ id: LANG_SKIN_RAM_USAGE - desc: how much RAM the skins are using + desc: deprecated user: core - *: "Skin RAM usage:" + *: "" - *: "スキンのRAM使用量:" + *: "" - *: "スキンのRAM使用量" + *: "" diff --git a/apps/lang/latviesu.lang b/apps/lang/latviesu.lang index 866820d4f3..0a46088444 100644 --- a/apps/lang/latviesu.lang +++ b/apps/lang/latviesu.lang @@ -11505,16 +11505,16 @@ id: LANG_SKIN_RAM_USAGE - desc: how much RAM the skins are using + desc: deprecated user: core - *: "Skin RAM usage:" + *: "" - *: "Ādas RAM izl.:" + *: "" - *: "aadas ram izlietojums" + *: "" diff --git a/apps/lang/magyar.lang b/apps/lang/magyar.lang index e18fbe4ceb..a12de094ad 100644 --- a/apps/lang/magyar.lang +++ b/apps/lang/magyar.lang @@ -11366,16 +11366,16 @@ id: LANG_SKIN_RAM_USAGE - desc: how much RAM the skins are using + desc: deprecated user: core - *: "Skin RAM usage:" + *: "" - *: "Téma RAM használat:" + *: "" - *: "Téma RAM használat" + *: "" diff --git a/apps/lang/nederlands.lang b/apps/lang/nederlands.lang index 76cd861276..689b410a96 100644 --- a/apps/lang/nederlands.lang +++ b/apps/lang/nederlands.lang @@ -11852,16 +11852,16 @@ id: LANG_SKIN_RAM_USAGE - desc: how much RAM the skins are using + desc: deprecated user: core - *: "Skin RAM usage:" + *: "" - *: "Uitzicht RAM gebruik:" + *: "" - *: "Uitzicht RAM gebruik" + *: "" diff --git a/apps/lang/polski.lang b/apps/lang/polski.lang index c68484ffbd..8baa93d774 100644 --- a/apps/lang/polski.lang +++ b/apps/lang/polski.lang @@ -11426,16 +11426,16 @@ id: LANG_SKIN_RAM_USAGE - desc: how much RAM the skins are using + desc: deprecated user: core - *: "Skin RAM usage:" + *: "" - *: "Pamięć zajmowana przez styl:" + *: "" - *: "Pamięć zajmowana przez styl" + *: "" diff --git a/apps/lang/portugues-brasileiro.lang b/apps/lang/portugues-brasileiro.lang index e708e936d4..43bd38e283 100644 --- a/apps/lang/portugues-brasileiro.lang +++ b/apps/lang/portugues-brasileiro.lang @@ -11501,16 +11501,16 @@ id: LANG_SKIN_RAM_USAGE - desc: how much RAM the skins are using + desc: deprecated user: core - *: "Skin RAM usage:" + *: "" - *: "Uso de RAM do Skin:" + *: "" - *: "Uso de RAM do Skin" + *: "" diff --git a/apps/lang/portugues.lang b/apps/lang/portugues.lang index c9808596ae..fde14e89b4 100644 --- a/apps/lang/portugues.lang +++ b/apps/lang/portugues.lang @@ -11679,16 +11679,16 @@ id: LANG_SKIN_RAM_USAGE - desc: how much RAM the skins are using + desc: deprecated user: core - *: "Skin RAM usage:" + *: "" - *: "Uso de RAM do Visual:" + *: "" - *: "Uso de RAM do Visual" + *: "" diff --git a/apps/lang/romaneste.lang b/apps/lang/romaneste.lang index 169df41ed9..8fcb4f8b99 100644 --- a/apps/lang/romaneste.lang +++ b/apps/lang/romaneste.lang @@ -12501,16 +12501,16 @@ id: LANG_SKIN_RAM_USAGE - desc: how much RAM the skins are using + desc: deprecated user: core - *: "Skin RAM usage:" + *: "" - *: "Utilizare RAM de către skin:" + *: "" - *: "Utilizare RAM de către skin:" + *: "" diff --git a/apps/lang/russian.lang b/apps/lang/russian.lang index be67c92259..7cd280ce62 100644 --- a/apps/lang/russian.lang +++ b/apps/lang/russian.lang @@ -12219,16 +12219,16 @@ id: LANG_SKIN_RAM_USAGE - desc: how much RAM the skins are using + desc: deprecated user: core - *: "Skin RAM usage:" + *: "" - *: "RAM для темы:" + *: "" - *: "RAM для темы" + *: "" diff --git a/apps/lang/slovak.lang b/apps/lang/slovak.lang index 8b34e739d8..0bb4b46270 100644 --- a/apps/lang/slovak.lang +++ b/apps/lang/slovak.lang @@ -11500,16 +11500,16 @@ id: LANG_SKIN_RAM_USAGE - desc: how much RAM the skins are using + desc: deprecated user: core - *: "Skin RAM usage:" + *: "" - *: "Pamäť Ram využitá vzhľadom" + *: "" - *: "Pamäť RAM využitá vzhľadom" + *: "" diff --git a/apps/lang/slovenscina.lang b/apps/lang/slovenscina.lang index a40ba3a6b9..546eb86b5e 100644 --- a/apps/lang/slovenscina.lang +++ b/apps/lang/slovenscina.lang @@ -9764,16 +9764,16 @@ id: LANG_SKIN_RAM_USAGE - desc: how much RAM the skins are using + desc: deprecated user: core - *: "Skin RAM usage:" + *: "" - *: "Skin RAM usage:" + *: "" - *: "Skin RAM usage" + *: "" diff --git a/apps/lang/srpski.lang b/apps/lang/srpski.lang index 0f70707981..8d5b311c4b 100644 --- a/apps/lang/srpski.lang +++ b/apps/lang/srpski.lang @@ -11784,16 +11784,16 @@ id: LANG_SKIN_RAM_USAGE - desc: how much RAM the skins are using + desc: deprecated user: core - *: "Skin RAM usage:" + *: "" - *: "Потрошња RAM за скинове:" + *: "" - *: "Потрошња RAM за скинове" + *: "" diff --git a/apps/lang/svenska.lang b/apps/lang/svenska.lang index a154e0032d..c0b1b048cf 100644 --- a/apps/lang/svenska.lang +++ b/apps/lang/svenska.lang @@ -11506,16 +11506,16 @@ id: LANG_SKIN_RAM_USAGE - desc: how much RAM the skins are using + desc: deprecated user: core - *: "Skin RAM usage:" + *: "" - *: "Tema:" + *: "" - *: "Tema" + *: "" diff --git a/apps/lang/tagalog.lang b/apps/lang/tagalog.lang index 7547954c42..51d8e912df 100644 --- a/apps/lang/tagalog.lang +++ b/apps/lang/tagalog.lang @@ -11394,16 +11394,16 @@ id: LANG_SKIN_RAM_USAGE - desc: how much RAM the skins are using + desc: deprecated user: core - *: "Skin RAM usage:" + *: "" - *: "Skin RAM usage:" + *: "" - *: "Skin RAM usage" + *: "" diff --git a/apps/lang/thai.lang b/apps/lang/thai.lang index fd2d698844..e0079ac408 100644 --- a/apps/lang/thai.lang +++ b/apps/lang/thai.lang @@ -11342,16 +11342,16 @@ id: LANG_SKIN_RAM_USAGE - desc: how much RAM the skins are using + desc: deprecated user: core - *: "Skin RAM usage:" + *: "" - *: "หน่วยความจำหน้ากาก:" + *: "" - *: "Skin RAM usage" + *: "" diff --git a/apps/lang/walon.lang b/apps/lang/walon.lang index 0f9b508a83..ab3c8427a3 100644 --- a/apps/lang/walon.lang +++ b/apps/lang/walon.lang @@ -11505,16 +11505,16 @@ id: LANG_SKIN_RAM_USAGE - desc: how much RAM the skins are using + desc: deprecated user: core - *: "Skin RAM usage:" + *: "" - *: "Memwere eployeye pol pea:" + *: "" - *: "Memwere eployeye pol pea" + *: "" diff --git a/apps/menus/main_menu.c b/apps/menus/main_menu.c index 7f8a56e887..8053bf0cf8 100644 --- a/apps/menus/main_menu.c +++ b/apps/menus/main_menu.c @@ -147,9 +147,6 @@ enum infoscreenorder INFO_DISK1, /* capacity or internal capacity/free on hotswap */ INFO_DISK2, /* free space or external capacity/free on hotswap */ INFO_BUFFER, -#ifndef APPLICATION - INFO_SKIN_USAGE, /* ram usage of the skins */ -#endif INFO_VERSION, INFO_COUNT }; @@ -159,7 +156,7 @@ static const char* info_getname(int selected_item, void *data, { struct info_data *info = (struct info_data*)data; char s1[32]; -#if defined(HAVE_MULTIVOLUME) || !defined(APPLICATION) +#if defined(HAVE_MULTIVOLUME) char s2[32]; #endif if (info->new_data) @@ -246,14 +243,6 @@ static const char* info_getname(int selected_item, void *data, snprintf(buffer, buffer_len, SIZE_FMT, str(LANG_DISK_SIZE_INFO), s1); #endif break; -#ifndef APPLICATION - case INFO_SKIN_USAGE: - output_dyn_value(s1, sizeof s1, skin_buffer_usage(), byte_units, true); - output_dyn_value(s2, sizeof s2, skin_buffer_usage() - +skin_buffer_freespace(), byte_units, true); - snprintf(buffer, buffer_len, "%s %s / %s", str(LANG_SKIN_RAM_USAGE), s1, s2); - break; -#endif } return buffer; } @@ -334,12 +323,6 @@ static int info_speak_item(int selected_item, void * data) output_dyn_value(NULL, 0, info->size, kbyte_units, true); #endif break; -#ifndef APPLICATION - case INFO_SKIN_USAGE: - talk_id(LANG_SKIN_RAM_USAGE, false); - output_dyn_value(NULL, 0, skin_buffer_usage(), byte_units, true); - break; -#endif } return 0; diff --git a/apps/recorder/albumart.c b/apps/recorder/albumart.c index 43f18cd163..4cbabbc8ce 100644 --- a/apps/recorder/albumart.c +++ b/apps/recorder/albumart.c @@ -305,7 +305,7 @@ void draw_album_art(struct gui_wps *gwps, int handle_id, bool clear) return; struct wps_data *data = gwps->data; - struct skin_albumart *aa = data->albumart; + struct skin_albumart *aa = SKINOFFSETTOPTR(get_skin_buffer(data), data->albumart); if (!aa) return; diff --git a/lib/skin_parser/skin_buffer.c b/lib/skin_parser/skin_buffer.c index 5a9d4464b8..d18122ef20 100644 --- a/lib/skin_parser/skin_buffer.c +++ b/lib/skin_parser/skin_buffer.c @@ -47,54 +47,26 @@ #ifdef ROCKBOX #include "config.h" #include "skin_debug.h" - -#ifdef APPLICATION -# define USE_HOST_MALLOC -#else -# define USE_ROCKBOX_ALLOC -#endif - -#endif - -#ifdef USE_ROCKBOX_ALLOC static size_t buf_size; static unsigned char *buffer_start = NULL; static unsigned char *buffer_front = NULL; -#endif -#ifdef USE_HOST_MALLOC - -struct malloc_object { - struct malloc_object *next; - char buf[0]; -}; -static struct malloc_object *malloced_head = NULL, *malloced_tail = NULL; - -static void skin_free_malloced(void) +#ifndef __PCTOOL__ +long skin_buffer_to_offset(void *pointer) { - struct malloc_object *obj = malloced_head; - struct malloc_object *this; - while (obj) - { - this = obj; - obj = this->next; - free(this); - } - malloced_head = NULL; - malloced_tail = NULL; + return pointer == NULL ? -1 : (void*)pointer - (void*)buffer_start; } +void* skin_buffer_from_offset(long offset) +{ + return offset < 0 ? NULL : buffer_start + offset; +} #endif void skin_buffer_init(char* buffer, size_t size) { -#ifdef USE_ROCKBOX_ALLOC buffer_start = buffer_front = buffer; buf_size = size; -#elif defined(USE_HOST_MALLOC) - (void)buffer; (void)size; - skin_free_malloced(); -#endif } /* Allocate size bytes from the buffer */ @@ -108,8 +80,6 @@ void* skin_buffer_alloc(size_t size) { void *retval = NULL; #endif - -#ifdef USE_ROCKBOX_ALLOC /* 32-bit aligned */ size = (size + 3) & ~3; if (size > skin_buffer_freespace()) @@ -119,25 +89,9 @@ void* skin_buffer_alloc(size_t size) } retval = buffer_front; buffer_front += size; -#elif defined(USE_HOST_MALLOC) - size_t malloc_size = sizeof(struct malloc_object) + size; - struct malloc_object *obj = malloc(malloc_size); - retval = &obj->buf; - obj->next = NULL; - if (malloced_tail == NULL) - malloced_head = malloced_tail = obj; - else - malloced_tail->next = obj; - malloced_tail = obj; - -#else - retval = malloc(size); -#endif return retval; } - -#ifdef USE_ROCKBOX_ALLOC /* get the number of bytes currently being used */ size_t skin_buffer_usage(void) { @@ -147,16 +101,9 @@ size_t skin_buffer_freespace(void) { return buf_size - skin_buffer_usage(); } - -static unsigned char *saved_buffer_pos = NULL; -void skin_buffer_save_position(void) +#else +void* skin_buffer_alloc(size_t size) { - saved_buffer_pos = buffer_front; -} - -void skin_buffer_restore_position(void) -{ - if (saved_buffer_pos) - buffer_front = saved_buffer_pos; + return malloc(size); } #endif diff --git a/lib/skin_parser/skin_buffer.h b/lib/skin_parser/skin_buffer.h index b2ed34e09f..7c9bb0b9c0 100644 --- a/lib/skin_parser/skin_buffer.h +++ b/lib/skin_parser/skin_buffer.h @@ -28,6 +28,18 @@ void skin_buffer_init(char* buffer, size_t size); /* Allocate size bytes from the buffer */ +#ifndef __PCTOOL__ +#define INVALID_OFFSET (-1) +#define IS_VALID_OFFSET(o) ((o) >= 0) +long skin_buffer_to_offset(void *pointer); +void* skin_buffer_from_offset(long offset); +#else +#define INVALID_OFFSET (NULL) +#define IS_VALID_OFFSET(o) ((o) != NULL) +#define skin_buffer_to_offset(p) p +#define skin_buffer_from_offset(o) o +#endif + /* #define DEBUG_SKIN_ALLOCATIONS */ #ifdef DEBUG_SKIN_ALLOCATIONS @@ -44,7 +56,4 @@ void* skin_buffer_alloc(size_t size); size_t skin_buffer_usage(void); size_t skin_buffer_freespace(void); -/* save and restore a buffer position incase a skin fails to load */ -void skin_buffer_save_position(void); -void skin_buffer_restore_position(void); #endif diff --git a/lib/skin_parser/skin_debug.c b/lib/skin_parser/skin_debug.c index 52f9127f1f..ecf238f1b1 100644 --- a/lib/skin_parser/skin_debug.c +++ b/lib/skin_parser/skin_debug.c @@ -31,6 +31,7 @@ int debug_indent_level = 0; extern int skin_line; extern char* skin_start; +extern char* skin_buffer; /* Global error variables */ int error_line; @@ -38,6 +39,14 @@ int error_col; const char *error_line_start; char* error_message; + +static inline struct skin_element* +get_child(OFFSETTYPE(struct skin_element**) children, int child) +{ + struct skin_element **kids = SKINOFFSETTOPTR(skin_buffer, children); + return kids[child]; +} + /* Debugging functions */ void skin_error(enum skin_errorcode error, const char* cursor) { @@ -144,14 +153,14 @@ void skin_debug_tree(struct skin_element* root) printf("{ Viewport \n"); debug_indent_level++; - skin_debug_tree(current->children[0]); + skin_debug_tree(get_child(current->children, 0)); debug_indent_level--; printf("}"); break; case TEXT: - text = current->data; + text = SKINOFFSETTOPTR(skin_buffer, current->data); printf("* Plain text on line %d: \"%s\"\n", current->line, text); break; @@ -166,7 +175,7 @@ void skin_debug_tree(struct skin_element* root) current->tag->name, current->line, current->params_count); debug_indent_level++; - skin_debug_params(current->params_count, current->params); + skin_debug_params(current->params_count, SKINOFFSETTOPTR(skin_buffer, current->params)); debug_indent_level--; skin_debug_indent(); printf(")\n"); @@ -185,7 +194,7 @@ void skin_debug_tree(struct skin_element* root) debug_indent_level++; for(i = 0; i < current->children_count; i++) { - skin_debug_tree(current->children[i]); + skin_debug_tree(get_child(current->children, i)); } debug_indent_level--; @@ -203,7 +212,7 @@ void skin_debug_tree(struct skin_element* root) skin_debug_indent(); printf("[ Enumeration %d\n", i); debug_indent_level++; - skin_debug_tree(current->children[i]); + skin_debug_tree(get_child(current->children, i)); debug_indent_level--; skin_debug_indent(); printf("]\n"); @@ -221,7 +230,7 @@ void skin_debug_tree(struct skin_element* root) debug_indent_level++; if (current->children) - skin_debug_tree(current->children[0]); + skin_debug_tree(get_child(current->children, 0)); debug_indent_level--; skin_debug_indent(); @@ -229,7 +238,7 @@ void skin_debug_tree(struct skin_element* root) break; } - current = current->next; + current = SKINOFFSETTOPTR(skin_buffer, current->next); } } @@ -248,7 +257,7 @@ void skin_debug_params(int count, struct skin_tag_parameter params[]) break; case STRING: - printf("string: \"%s\"", params[i].data.text); + printf("string: \"%s\"", SKINOFFSETTOPTR(skin_buffer, params[i].data.text)); break; case INTEGER: @@ -263,7 +272,7 @@ void skin_debug_params(int count, struct skin_tag_parameter params[]) case CODE: printf("Skin Code: \n"); debug_indent_level++; - skin_debug_tree(params[i].data.code); + skin_debug_tree(SKINOFFSETTOPTR(skin_buffer, params[i].data.code)); debug_indent_level--; skin_debug_indent(); break; diff --git a/lib/skin_parser/skin_parser.c b/lib/skin_parser/skin_parser.c index 2612cc8906..c49ac12a59 100644 --- a/lib/skin_parser/skin_parser.c +++ b/lib/skin_parser/skin_parser.c @@ -37,8 +37,6 @@ int skin_line = 0; char* skin_start = 0; int viewport_line = 0; -static int tag_recursion_level = 0; - #ifdef ROCKBOX static skin_callback callback = NULL; static void* callback_data; @@ -81,8 +79,6 @@ struct skin_element* skin_parse(const char* document) struct skin_element* root = NULL; struct skin_element* last = NULL; - struct skin_element** to_write = 0; - const char* cursor = document; /*Keeps track of location in the document*/ skin_line = 1; @@ -93,14 +89,18 @@ struct skin_element* skin_parse(const char* document) while(*cursor != '\0') { + struct skin_element* tree = skin_parse_viewport(&cursor); if(!root) - to_write = &root; + { + root = tree; + last = root; + } else - to_write = &(last->next); + { + last->next = skin_buffer_to_offset(tree); + last = tree; + } - - *to_write = skin_parse_viewport(&cursor); - last = *to_write; if(!last) { skin_free_tree(root); /* Clearing any memory already used */ @@ -108,8 +108,8 @@ struct skin_element* skin_parse(const char* document) } /* Making sure last is at the end */ - while(last->next) - last = last->next; + while(IS_VALID_OFFSET(last->next)) + last = skin_buffer_from_offset(last->next); } return root; @@ -121,8 +121,6 @@ static struct skin_element* skin_parse_viewport(const char** document) struct skin_element* root = NULL; struct skin_element* last = NULL; struct skin_element* retval = NULL; - - tag_recursion_level = 0; retval = skin_alloc_element(); if (!retval) @@ -132,7 +130,7 @@ static struct skin_element* skin_parse_viewport(const char** document) retval->line = skin_line; viewport_line = skin_line; - struct skin_element** to_write = 0; + OFFSETTYPE(struct skin_element*)* children; const char* cursor = *document; /* Keeps track of location in the document */ const char* bookmark; /* Used when we need to look ahead */ @@ -165,8 +163,8 @@ static struct skin_element* skin_parse_viewport(const char** document) return retval; } retval->children_count = 1; - retval->children = skin_alloc_children(1); - if (!retval->children) + children = skin_alloc_children(1); + if (!children) return NULL; do { @@ -212,15 +210,19 @@ static struct skin_element* skin_parse_viewport(const char** document) } cursor = bookmark; - if(!root) - to_write = &root; - else - to_write = &(last->next); - if(sublines) { - *to_write = skin_parse_sublines(&cursor); - last = *to_write; + struct skin_element* out = skin_parse_sublines(&cursor); + if (!root) + { + root = out; + last = root; + } + else + { + last->next = skin_buffer_to_offset(out); + last = out; + } if(!last) return NULL; } @@ -237,15 +239,25 @@ static struct skin_element* skin_parse_viewport(const char** document) if (check_viewport(cursor)) break; #endif - *to_write = skin_parse_line(&cursor); - last = *to_write; + + struct skin_element* out = skin_parse_line(&cursor); + if (!root) + { + root = out; + last = root; + } + else + { + last->next = skin_buffer_to_offset(out); + last = out; + } if(!last) return NULL; } /* Making sure last is at the end */ - while(last->next) - last = last->next; + while(IS_VALID_OFFSET(last->next)) + last = skin_buffer_from_offset(last->next); if(*cursor == '\n') { @@ -269,7 +281,8 @@ static struct skin_element* skin_parse_viewport(const char** document) *document = cursor; - retval->children[0] = root; + children[0] = skin_buffer_to_offset(root); + retval->children = skin_buffer_to_offset(children); return retval; } @@ -293,6 +306,7 @@ static struct skin_element* skin_parse_line_optional(const char** document, struct skin_element* root = NULL; struct skin_element* current = NULL; struct skin_element* retval = NULL; + OFFSETTYPE(struct skin_element*)* children = NULL; /* A wrapper for the line */ retval = skin_alloc_element(); @@ -315,8 +329,8 @@ static struct skin_element* skin_parse_line_optional(const char** document, if(retval->children_count > 0) { - retval->children = skin_alloc_children(1); - if (!retval->children) + children = skin_alloc_children(1); + if (!children) return NULL; } @@ -344,10 +358,11 @@ static struct skin_element* skin_parse_line_optional(const char** document, /* Allocating memory if necessary */ if(root) { - current->next = skin_alloc_element(); - if (!current->next) + struct skin_element *next = skin_alloc_element(); + if (!next) return NULL; - current = current->next; + current->next = skin_buffer_to_offset(next); + current = next; } else { @@ -384,7 +399,10 @@ static struct skin_element* skin_parse_line_optional(const char** document, *document = cursor; if(root) - retval->children[0] = root; + { + children[0] = skin_buffer_to_offset(root); + retval->children = skin_buffer_to_offset(children); + } return retval; } @@ -397,6 +415,7 @@ static struct skin_element* skin_parse_sublines_optional(const char** document, int conditional) { struct skin_element* retval; + OFFSETTYPE(struct skin_element*)* children; const char* cursor = *document; int sublines = 1; int i; @@ -405,7 +424,7 @@ static struct skin_element* skin_parse_sublines_optional(const char** document, if (!retval) return NULL; retval->type = LINE_ALTERNATOR; - retval->next = NULL; + retval->next = skin_buffer_to_offset(NULL); retval->line = skin_line; /* First we count the sublines */ @@ -449,14 +468,16 @@ static struct skin_element* skin_parse_sublines_optional(const char** document, /* ...and then we parse them */ retval->children_count = sublines; - retval->children = skin_alloc_children(sublines); - if (!retval->children) + children = skin_alloc_children(sublines); + if (!children) return NULL; cursor = *document; for(i = 0; i < sublines; i++) { - retval->children[i] = skin_parse_line_optional(&cursor, conditional); + children[i] = skin_buffer_to_offset(skin_parse_line_optional(&cursor, conditional)); + if (children[i] < 0) + return NULL; skip_whitespace(&cursor); if(*cursor != MULTILINESYM && i != sublines - 1) @@ -478,6 +499,7 @@ static struct skin_element* skin_parse_sublines_optional(const char** document, } #endif *document = cursor; + retval->children = skin_buffer_to_offset(children); return retval; } @@ -490,13 +512,13 @@ static int skin_parse_tag(struct skin_element* element, const char** document) char tag_name[3]; char* tag_args; const struct tag_info *tag; + struct skin_tag_parameter* params = NULL; int num_args = 1; int i; int star = 0; /* Flag for the all-or-none option */ int optional = 0; - tag_recursion_level++; /* Checking the tag name */ tag_name[0] = cursor[0]; @@ -597,8 +619,8 @@ static int skin_parse_tag(struct skin_element* element, const char** document) cursor = bookmark; /* Restoring the cursor */ element->params_count = num_args; - element->params = skin_alloc_params(num_args, tag_recursion_level<=1); - if (!element->params) + params = skin_alloc_params(num_args); + if (!params) return 0; /* Now we have to actually parse each argument */ @@ -686,14 +708,14 @@ static int skin_parse_tag(struct skin_element* element, const char** document) else type_code = *tag_args; /* Storing the type code */ - element->params[i].type_code = type_code; + params[i].type_code = type_code; /* Checking a nullable argument for null. */ if(*cursor == DEFAULTSYM && !isdigit(cursor[1])) { if(islower(type_code)) { - element->params[i].type = DEFAULT; + params[i].type = DEFAULT; cursor++; } else @@ -711,8 +733,8 @@ static int skin_parse_tag(struct skin_element* element, const char** document) return 0; } - element->params[i].type = INTEGER; - element->params[i].data.number = scan_int(&cursor); + params[i].type = INTEGER; + params[i].data.number = scan_int(&cursor); } else if(tolower(type_code) == 'd') { @@ -738,23 +760,23 @@ static int skin_parse_tag(struct skin_element* element, const char** document) } if (have_tenth == false) val *= 10; - element->params[i].type = DECIMAL; - element->params[i].data.number = val; + params[i].type = DECIMAL; + params[i].data.number = val; } else if(tolower(type_code) == 'n' || tolower(type_code) == 's' || tolower(type_code) == 'f') { /* Scanning a string argument */ - element->params[i].type = STRING; - element->params[i].data.text = scan_string(&cursor); + params[i].type = STRING; + params[i].data.text = skin_buffer_to_offset(scan_string(&cursor)); } else if(tolower(type_code) == 'c') { /* Recursively parsing a code argument */ - element->params[i].type = CODE; - element->params[i].data.code = skin_parse_code_as_arg(&cursor); - if(!element->params[i].data.code) + params[i].type = CODE; + params[i].data.code = skin_buffer_to_offset(skin_parse_code_as_arg(&cursor)); + if(params[i].data.code < 0) return 0; } else if (tolower(type_code) == 't') @@ -763,9 +785,9 @@ static int skin_parse_tag(struct skin_element* element, const char** document) child->type = TAG; if (!skin_parse_tag(child, &cursor)) return 0; - child->next = NULL; - element->params[i].type = CODE; - element->params[i].data.code = child; + child->next = skin_buffer_to_offset(NULL); + params[i].type = CODE; + params[i].data.code = skin_buffer_to_offset(child); } @@ -796,6 +818,7 @@ static int skin_parse_tag(struct skin_element* element, const char** document) tag_args++; } } + element->params = skin_buffer_to_offset(params); /* Checking for a premature end */ if(*tag_args != '\0' && !optional) @@ -811,7 +834,6 @@ static int skin_parse_tag(struct skin_element* element, const char** document) } #endif *document = cursor; - tag_recursion_level--; return 1; } @@ -855,9 +877,10 @@ static int skin_parse_text(struct skin_element* element, const char** document, /* Copying the text into the element struct */ element->type = TEXT; element->line = skin_line; - element->next = NULL; - element->data = text = skin_alloc_string(length); - if (!element->data) + element->next = skin_buffer_to_offset(NULL); + text = skin_alloc_string(length); + element->data = skin_buffer_to_offset(text); + if (element->data < 0) return 0; for(dest = 0; dest < length; dest++) @@ -896,6 +919,7 @@ static int skin_parse_conditional(struct skin_element* element, const char** doc const char *false_branch = NULL; const char *conditional_end = NULL; #endif + OFFSETTYPE(struct skin_element*)* children_array = NULL; /* Some conditional tags allow for target feature checking, * so to handle that call the callback as usual with type == TAG @@ -994,23 +1018,23 @@ static int skin_parse_conditional(struct skin_element* element, const char** doc { const char* emptyline= ""; children = 1; - element->children = skin_alloc_children(children); - if (!element->children) + children_array = skin_alloc_children(children); + if (!children_array) return 0; element->children_count = children; - element->children[0] = skin_parse_code_as_arg(&emptyline); + children_array[0] = skin_buffer_to_offset(skin_parse_code_as_arg(&emptyline)); } else { - element->children = skin_alloc_children(children); - if (!element->children) + children_array = skin_alloc_children(children); + if (!children_array) return 0; element->children_count = children; for(i = 0; i < children; i++) { - element->children[i] = skin_parse_code_as_arg(&cursor); - if (element->children[i] == NULL) + children_array[i] = skin_buffer_to_offset(skin_parse_code_as_arg(&cursor)); + if (children_array[i] < 0) return 0; skip_whitespace(&cursor); #ifdef ROCKBOX @@ -1035,6 +1059,7 @@ static int skin_parse_conditional(struct skin_element* element, const char** doc } } *document = cursor; + element->children = skin_buffer_to_offset(children_array); return 1; } @@ -1056,7 +1081,7 @@ static int skin_parse_comment(struct skin_element* element, const char** documen element->type = COMMENT; element->line = skin_line; #ifdef ROCKBOX - element->data = NULL; + element->data = INVALID_OFFSET; #else element->data = text = skin_alloc_string(length); if (!element->data) @@ -1122,7 +1147,6 @@ static struct skin_element* skin_parse_code_as_arg(const char** document) return skin_parse_line_optional(document, 1); } - /* Memory management */ struct skin_element* skin_alloc_element() { @@ -1131,10 +1155,12 @@ struct skin_element* skin_alloc_element() if (!retval) return NULL; retval->type = UNKNOWN; - retval->next = NULL; + retval->next = skin_buffer_to_offset(NULL); + retval->params = skin_buffer_to_offset(NULL); retval->tag = NULL; retval->params_count = 0; retval->children_count = 0; + retval->data = INVALID_OFFSET; return retval; @@ -1144,16 +1170,8 @@ struct skin_element* skin_alloc_element() * enough for any tag. params should be used straight away by the callback * so this is safe. */ -struct skin_tag_parameter* skin_alloc_params(int count, bool use_shared_params) +struct skin_tag_parameter* skin_alloc_params(int count) { -#ifdef ROCKBOX - static struct skin_tag_parameter params[MAX_TAG_PARAMS]; - if (use_shared_params && count <= MAX_TAG_PARAMS) - { - memset(params, 0, sizeof(params)); - return params; - } -#endif size_t size = sizeof(struct skin_tag_parameter) * count; return (struct skin_tag_parameter*)skin_buffer_alloc(size); @@ -1164,9 +1182,9 @@ char* skin_alloc_string(int length) return (char*)skin_buffer_alloc(sizeof(char) * (length + 1)); } -struct skin_element** skin_alloc_children(int count) +OFFSETTYPE(struct skin_element*)* skin_alloc_children(int count) { - return (struct skin_element**) + return (OFFSETTYPE(struct skin_element*)*) skin_buffer_alloc(sizeof(struct skin_element*) * count); } diff --git a/lib/skin_parser/skin_parser.h b/lib/skin_parser/skin_parser.h index 3e0634976c..120112d995 100644 --- a/lib/skin_parser/skin_parser.h +++ b/lib/skin_parser/skin_parser.h @@ -29,6 +29,25 @@ extern "C" #include #include +#if defined(ROCKBOX) && !defined(__PCTOOL__) +/* Use this type and macro to convert a pointer from the + * skin buffer to a useable pointer */ +typedef long skinoffset_t; +#define SKINOFFSETTOPTR(base, offset) ((offset) < 0 ? NULL : ((void*)&base[offset])) +#define PTRTOSKINOFFSET(base, pointer) ((pointer) ? ((void*)pointer-(void*)base) : -1) +/* Use this macro when declaring a variable to self-document the code. + * type is the actual type being pointed to (i.e OFFSETTYPE(char*) foo ) + * + * WARNING: Don't use the PTRTOSKINOFFSET() around a function call as it wont + * do what you expect. + */ +#define OFFSETTYPE(type) skinoffset_t +#else +#define SKINOFFSETTOPTR(base, offset) offset +#define PTRTOSKINOFFSET(base, pointer) pointer +#define OFFSETTYPE(type) type +#endif + /******************************************************************** ****** Data Structures ********************************************* *******************************************************************/ @@ -78,8 +97,8 @@ struct skin_tag_parameter union { int number; - char* text; - struct skin_element* code; + OFFSETTYPE(char*) text; + OFFSETTYPE(struct skin_element*) code; } data; char type_code; @@ -92,20 +111,20 @@ struct skin_tag_parameter struct skin_element { /* Link to the next element */ - struct skin_element* next; + OFFSETTYPE(struct skin_element*) next; /* Pointer to an array of children */ - struct skin_element** children; + OFFSETTYPE(struct skin_element**) children; /* Placeholder for element data * TEXT and COMMENT uses it for the text string * TAG, VIEWPORT, LINE, etc may use it for post parse extra storage */ - void* data; + OFFSETTYPE(void*) data; /* The tag or conditional name */ const struct tag_info *tag; /* Pointer to an array of parameters */ - struct skin_tag_parameter* params; + OFFSETTYPE(struct skin_tag_parameter*) params; /* Number of elements in the children array */ short children_count; @@ -140,8 +159,8 @@ struct skin_element* skin_parse(const char* document); #endif /* Memory management functions */ struct skin_element* skin_alloc_element(void); -struct skin_element** skin_alloc_children(int count); -struct skin_tag_parameter* skin_alloc_params(int count, bool use_shared_params); +OFFSETTYPE(struct skin_element*)* skin_alloc_children(int count); +struct skin_tag_parameter* skin_alloc_params(int count); char* skin_alloc_string(int length); void skin_free_tree(struct skin_element* root); diff --git a/tools/checkwps/checkwps.c b/tools/checkwps/checkwps.c index 846dd97191..ec0262bfe7 100644 --- a/tools/checkwps/checkwps.c +++ b/tools/checkwps/checkwps.c @@ -37,6 +37,7 @@ bool debug_wps = true; int wps_verbose_level = 0; +char *skin_buffer; int errno; @@ -252,8 +253,6 @@ int main(int argc, char **argv) struct wps_data wps={0}; enum screen_type screen = SCREEN_MAIN; struct screen* wps_screen; - - char* buffer = NULL; /* No arguments -> print the help text * Also print the help text upon -h or --help */ @@ -278,14 +277,14 @@ int main(int argc, char **argv) wps_verbose_level++; } } - buffer = malloc(SKIN_BUFFER_SIZE); - if (!buffer) + skin_buffer = malloc(SKIN_BUFFER_SIZE); + if (!skin_buffer) { printf("mallloc fail!\n"); return 1; } - skin_buffer_init(buffer, SKIN_BUFFER_SIZE); + skin_buffer_init(skin_buffer, SKIN_BUFFER_SIZE); /* Go through every skin that was thrown at us, error out at the first * flawed wps */ @@ -311,7 +310,7 @@ int main(int argc, char **argv) printf("WPS parsed OK\n\n"); if (wps_verbose_level>2) - skin_debug_tree(wps.tree); + skin_debug_tree(SKINOFFSETTOPTR(skin_buffer, wps.tree)); filearg++; } return 0;