diff --git a/apps/gui/bitmap/list-skinned.c b/apps/gui/bitmap/list-skinned.c index 208b2df..4b2493f 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(skin_buffer, listcfg[screen]->data->tree); viewport; - viewport = viewport->next) + viewport = SKINOFFSETTOPTR(skin_buffer, viewport->next)) { int origional_x, origional_y; int origional_w, origional_h; + char *viewport_label = SKINOFFSETTOPTR(skin_buffer, 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(skin_buffer, wps.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 = SKINOFFSETTOPTR(skin_buffer, token->value.data); img->display = -1; - imglist = imglist->next; + imglist = SKINOFFSETTOPTR(skin_buffer, imglist->next); } #endif - skin_render_viewport(viewport->children[0], + struct skin_element** children = SKINOFFSETTOPTR(skin_buffer, 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 95e4310..4ee7b25 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(skin_buffer, 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(skin_buffer, pb->slider)) { - struct gui_img *img = pb->slider; + struct gui_img *img = SKINOFFSETTOPTR(skin_buffer, 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(skin_buffer, pb->backdrop)) { - struct gui_img *img = pb->backdrop; + struct gui_img *img = SKINOFFSETTOPTR(skin_buffer, pb->backdrop); char *img_data = core_get_data(img->buflib_handle); #if LCD_DEPTH > 1 if(img->bm.format == FORMAT_MONO) { @@ -269,11 +269,12 @@ void draw_progressbar(struct gui_wps *gwps, int line, struct progressbar *pb) if (!pb->nobar) { - if (pb->image) + struct gui_img *img = SKINOFFSETTOPTR(skin_buffer, 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); } @@ -282,11 +283,11 @@ void draw_progressbar(struct gui_wps *gwps, int line, struct progressbar *pb) length, 0, end, flags); } - if (pb->slider) + if (SKINOFFSETTOPTR(skin_buffer, pb->slider)) { int xoff = 0, yoff = 0; int w = width, h = height; - struct gui_img *img = pb->slider; + struct gui_img *img = SKINOFFSETTOPTR(skin_buffer, pb->slider); char *img_data = core_get_data(img->buflib_handle); if (flags&HORIZONTAL) @@ -391,11 +392,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(skin_buffer, 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->using_preloaded_icons && img->display >= 0) { screen_put_icon(display, img->x, img->y, img->display); @@ -406,20 +408,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(skin_buffer, img->vp) == vp) { wps_draw_image(gwps, img, 0); } } - list = list->next; + list = SKINOFFSETTOPTR(skin_buffer, 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(skin_buffer, data->albumart); + if (aa && SKINOFFSETTOPTR(skin_buffer, 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 @@ -442,8 +445,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(skin_buffer, 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 bd875fe..1e0304c 100644 --- a/apps/gui/skin_engine/skin_engine.c +++ b/apps/gui/skin_engine/skin_engine.c @@ -48,7 +48,7 @@ void theme_init_buffer(void) skins_initialising = false; } #else -static char skin_buffer[SKIN_BUFFER_SIZE]; +char skin_buffer[SKIN_BUFFER_SIZE]; void theme_init_buffer(void) { skins_initialising = false; @@ -95,8 +95,13 @@ 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.tree = PTRTOSKINOFFSET(skin_buffer, NULL); +#ifdef HAVE_LCD_BITMAP + skins[j][i].data.font_ids = PTRTOSKINOFFSET(skin_buffer, NULL); + skins[j][i].data.images = PTRTOSKINOFFSET(skin_buffer, NULL); +#endif #ifdef HAVE_ALBUMART - skins[j][i].data.albumart = NULL; + skins[j][i].data.albumart = PTRTOSKINOFFSET(skin_buffer, NULL); skins[j][i].data.playback_aa_slot = -1; #endif } diff --git a/apps/gui/skin_engine/skin_parser.c b/apps/gui/skin_engine/skin_parser.c index d207a1f..de25216 100644 --- a/apps/gui/skin_engine/skin_parser.c +++ b/apps/gui/skin_engine/skin_parser.c @@ -78,11 +78,35 @@ #define GLYPHS_TO_CACHE 256 +#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; @@ -103,16 +127,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(skinoffset *listoffset, struct skin_token_list *item) { - if (*list == NULL) - *list = item; + struct skin_token_list *list = SKINOFFSETTOPTR(skin_buffer, *listoffset); + if (list == NULL) + { + list = item; + *listoffset = PTRTOSKINOFFSET(skin_buffer, list); + } 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); } } @@ -133,22 +160,22 @@ void *skin_find_item(const char *label, enum skin_find_what 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,31 +183,37 @@ 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 @@ -189,9 +222,9 @@ void *skin_find_item(const char *label, enum skin_find_what what, 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); } return NULL; } @@ -212,10 +245,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,12 +259,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; + struct skin_element *def_vp = SKINOFFSETTOPTR(skin_buffer, wps_data->tree); + struct skin_viewport *default_vp = SKINOFFSETTOPTR(skin_buffer, def_vp->data); if (def_vp->params_count == 0) { wps_data->wps_sb_tag = true; @@ -279,7 +312,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 +330,9 @@ static int parse_image_display(struct skin_element *element, { return WPS_ERROR_INVALID_PARAM; } - id->label = label; + id->label = PTRTOSKINOFFSET(skin_buffer, 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 +340,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 +359,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 +377,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 +393,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, id); img->x = x; img->y = y; img->num_subimages = 1; @@ -370,7 +403,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 +411,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 +441,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 +485,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 +507,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 +520,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 +533,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 +559,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 +581,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 +591,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 +604,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 +623,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 +635,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 +668,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 +699,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 +726,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 = PTRTOSKINOFFSET(skin_buffer, get_param_code(element, 0)->data); if (!strncmp(op, "=", 1)) lif->op = IF_EQUALS; @@ -712,9 +746,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 +777,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 +790,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 = PTRTOSKINOFFSET(skin_buffer, get_param_code(element, 2)->data); + token->value.data = PTRTOSKINOFFSET(skin_buffer, ss); return 0; } @@ -773,7 +807,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 +816,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 +883,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 +892,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(param->data.text, "backdrop")) + else if (!strcmp(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); + 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, "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 +972,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 +1031,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 +1054,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 +1064,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 +1088,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 +1120,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 +1134,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 +1150,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 +1176,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 +1199,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 +1261,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 +1277,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 +1341,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 +1404,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")) @@ -1441,21 +1481,23 @@ void skin_data_free_buflib_allocs(struct wps_data *wps_data) (void)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); #endif #endif } @@ -1469,22 +1511,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 = PTRTOSKINOFFSET(skin_buffer, NULL); #endif - wps_data->tree = NULL; + wps_data->tree = PTRTOSKINOFFSET(skin_buffer, NULL); #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 = PTRTOSKINOFFSET(skin_buffer, NULL); #endif #ifdef HAVE_SKIN_VARIABLES - wps_data->skinvars = NULL; + wps_data->skinvars = PTRTOSKINOFFSET(skin_buffer, NULL); #endif #ifdef HAVE_ALBUMART - wps_data->albumart = NULL; + wps_data->albumart = PTRTOSKINOFFSET(skin_buffer, NULL); if (wps_data->playback_aa_slot >= 0) { playback_release_aa_slot(wps_data->playback_aa_slot); @@ -1598,16 +1640,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 { @@ -1619,11 +1662,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; } @@ -1637,11 +1680,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; @@ -1697,19 +1741,20 @@ 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) + int *font_ids = skin_buffer_alloc(font_count * sizeof(int)); + if (!success || font_ids == NULL) { while (font_count > 0) { if(id_array[--font_count] != -1) font_unload(id_array[font_count]); } - data->font_ids = NULL; + data->font_ids = PTRTOSKINOFFSET(skin_buffer, NULL); return false; } - memcpy(data->font_ids, id_array, sizeof(int)*font_count); + memcpy(font_ids, id_array, sizeof(int)*font_count); data->font_count = font_count; + data->font_ids = PTRTOSKINOFFSET(skin_buffer, font_ids); return success; } @@ -1724,10 +1769,10 @@ 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; @@ -1744,11 +1789,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 (!SKINOFFSETTOPTR(skin_buffer, data->tree)) /* first viewport in the skin */ + data->tree = PTRTOSKINOFFSET(skin_buffer, element); skin_vp->label = VP_DEFAULT_LABEL; return CALLBACK_OK; } @@ -1858,7 +1903,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) @@ -1907,7 +1952,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: @@ -1939,7 +1984,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 = PTRTOSKINOFFSET(skin_buffer, get_param_text(element, 0)); break; case SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY: function = parse_image_display; @@ -1962,8 +2007,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; @@ -2000,7 +2048,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: @@ -2011,7 +2059,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: @@ -2020,7 +2068,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; @@ -2049,11 +2097,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 @@ -2114,15 +2163,16 @@ bool skin_data_load(enum screen_type screen, struct wps_data *wps_data, wps_buffer = (char*)buf; } #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) { + 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(); @@ -2157,7 +2207,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) || diff --git a/apps/gui/skin_engine/skin_render.c b/apps/gui/skin_engine/skin_render.c index 4d41a6f..7a6df62 100644 --- a/apps/gui/skin_engine/skin_render.c +++ b/apps/gui/skin_engine/skin_render.c @@ -81,6 +81,14 @@ static void skin_render_playlistviewer(struct playlistviewer* viewer, unsigned long refresh_type); #endif +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]; +} + + static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info, struct skin_element *element, struct viewport* vp) { @@ -88,7 +96,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 +107,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 +126,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 +135,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 +154,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 +162,11 @@ 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); + SKINOFFSETTOPTR(skin_buffer, token->value.data)); break; case SKIN_TOKEN_PEAKMETER: data->peak_meter_enabled = true; @@ -173,7 +187,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 +197,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 +211,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 +238,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 +272,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 @@ -297,12 +315,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 +331,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(branch->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 +359,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 +399,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 +455,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 +464,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 +478,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 +500,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 +515,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 +539,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 +549,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 +563,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 +593,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 +619,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 +641,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; } @@ -648,12 +670,13 @@ void skin_render_viewport(struct skin_element* viewport, struct gui_wps *gwps, bool needs_update; #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 +739,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,6 +753,7 @@ 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; @@ -741,18 +765,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 +816,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 +853,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 +875,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 7c43045..853dab4 100644 --- a/apps/gui/skin_engine/skin_tokens.c +++ b/apps/gui/skin_engine/skin_tokens.c @@ -732,18 +732,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(skin_buffer, 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(skin_buffer, 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 +755,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(skin_buffer, lif->operand.data.code); + struct wps_token *token = SKINOFFSETTOPTR(skin_buffer, 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 +869,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(skin_buffer, 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(skin_buffer, token->value.data); + const char *token_val = get_token_value(gwps, + SKINOFFSETTOPTR(skin_buffer, ss->token), offset, buf, buf_size, intval); if (token_val) { @@ -909,7 +914,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(skin_buffer, token->value.data); case SKIN_TOKEN_TRANSLATEDSTRING: return (char*)P2STR(ID2P(token->value.i)); @@ -929,7 +934,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(skin_buffer, token->value.data); return skinlist_get_item_text(li->offset, li->wrap, buf, buf_size); } case SKIN_TOKEN_LIST_ITEM_NUMBER: @@ -941,7 +946,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(skin_buffer, token->value.data); int icon = skinlist_get_item_icon(li->offset, li->wrap); if (intval) *intval = icon; @@ -997,14 +1002,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(skin_buffer, 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(skin_buffer, data->albumart); + struct dim dim = {aa->width, aa->height}; handle = radio_get_art_hid(&dim); } #endif @@ -1473,9 +1479,10 @@ 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; + struct touchregion_lastpress *data = SKINOFFSETTOPTR(skin_buffer, token->value.data); + struct touchregion *region = SKINOFFSETTOPTR(skin_buffer, data->region); + if (region) + last_touch = region->last_press; if (last_touch != 0xffff && TIME_BEFORE(current_tick, data->timeout + last_touch)) @@ -1805,7 +1812,7 @@ 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; + struct skin_var* var = SKINOFFSETTOPTR(skin_buffer, token->value.data); if (intval) *intval = var->value; snprintf(buf, buf_size, "%d", var->value); @@ -1814,8 +1821,9 @@ 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; + struct skin_var_lastchange *data = SKINOFFSETTOPTR(skin_buffer, token->value.data); + struct skin_var* var = SKINOFFSETTOPTR(skin_buffer, 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 bfca7b7..0000000 --- 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 64c7979..3714f8c 100644 --- a/apps/gui/skin_engine/skin_touchsupport.c +++ b/apps/gui/skin_engine/skin_touchsupport.c @@ -37,11 +37,12 @@ /** Disarms all touchregions. */ void skin_disarm_touchregions(struct wps_data *data) { - struct skin_token_list *regions = data->touchregions; + 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 *)token->value.data)->armed = false; + regions = SKINOFFSETTOPTR(skin_buffer, regions->next); } } @@ -56,35 +57,38 @@ 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; 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 = (struct touchregion *)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 +131,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 +218,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 ed09ad0..5c9474a 100644 --- a/apps/gui/skin_engine/wps_internals.h +++ b/apps/gui/skin_engine/wps_internals.h @@ -25,6 +25,10 @@ #ifndef _WPS_ENGINE_INTERNALS_ #define _WPS_ENGINE_INTERNALS_ +#include "tag_table.h" +#include "skin_parser.h" + +extern char skin_buffer[]; /* Timeout unit expressed in HZ. In WPS, all timeouts are given in seconds (possibly with a decimal fraction) but stored as integer values. @@ -33,9 +37,6 @@ #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 */ @@ -44,41 +45,43 @@ #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 */ +/* 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; +}; -#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 */ +char* get_dir(char* buf, int buf_size, const char* path, int level); -#endif /* HAVE_ALBUMART */ -/* wps_data*/ +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 +89,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 +108,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 +128,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 +155,13 @@ 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 "|" +#define VP_DEFAULT_LABEL -200 +#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 +172,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 +199,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 +210,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 +247,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 +264,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 +284,7 @@ struct logical_if { struct substring { int start; int length; - struct wps_token *token; + OFFSETTYPE(struct wps_token *) token; }; struct listitem { @@ -302,16 +294,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 +315,27 @@ struct skin_var_changer { viewable content of a wps */ struct wps_data { - struct skin_element *tree; + 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 diff --git a/apps/gui/statusbar-skinned.c b/apps/gui/statusbar-skinned.c index f79672c..bec2484 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(skin_buffer, data->tree); + struct skin_element *next_vp = SKINOFFSETTOPTR(skin_buffer, tree->next); if (vp) { @@ -99,7 +100,7 @@ int sb_postproccess(enum screen_type screen, struct wps_data *data) /* hide this viewport, forever */ vp->hidden_flags = VP_NEVER_VISIBLE; } - sb_set_info_vp(screen, VP_DEFAULT_LABEL); + sb_set_info_vp(screen, VP_DEFAULT_LABEL_STRING); } viewportmanager_theme_undo(screen, false); return 1; diff --git a/apps/gui/wps.c b/apps/gui/wps.c index 6486e42..97c945d 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/recorder/albumart.c b/apps/recorder/albumart.c index 43f18cd..af1aac9 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(skin_buffer, data->albumart); if (!aa) return; diff --git a/lib/skin_parser/skin_buffer.c b/lib/skin_parser/skin_buffer.c index 5a9d446..b3c4e0f 100644 --- a/lib/skin_parser/skin_buffer.c +++ b/lib/skin_parser/skin_buffer.c @@ -60,6 +60,16 @@ static size_t buf_size; static unsigned char *buffer_start = NULL; static unsigned char *buffer_front = NULL; + +long skin_buffer_to_offset(void *pointer) +{ + return pointer == NULL ? -1 : (void*)pointer - (void*)buffer_start; +} + +void* skin_buffer_from_offset(long offset) +{ + return offset < 0 ? NULL : buffer_start + offset; +} #endif #ifdef USE_HOST_MALLOC diff --git a/lib/skin_parser/skin_buffer.h b/lib/skin_parser/skin_buffer.h index b2ed34e..e42516e 100644 --- a/lib/skin_parser/skin_buffer.h +++ b/lib/skin_parser/skin_buffer.h @@ -28,6 +28,9 @@ void skin_buffer_init(char* buffer, size_t size); /* Allocate size bytes from the buffer */ +long skin_buffer_to_offset(void *pointer); +void* skin_buffer_from_offset(long offset); + /* #define DEBUG_SKIN_ALLOCATIONS */ #ifdef DEBUG_SKIN_ALLOCATIONS diff --git a/lib/skin_parser/skin_parser.c b/lib/skin_parser/skin_parser.c index 2612cc8..b17f634 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(last->next >= 0) + 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; + 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(last->next >= 0) + 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] = 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; + 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] = 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; + 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,14 @@ 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_parse_line_optional(&cursor, conditional); skip_whitespace(&cursor); if(*cursor != MULTILINESYM && i != sublines - 1) @@ -478,6 +497,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 +510,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 +617,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 +706,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 +731,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 +758,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 +783,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 +816,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 +832,6 @@ static int skin_parse_tag(struct skin_element* element, const char** document) } #endif *document = cursor; - tag_recursion_level--; return 1; } @@ -855,9 +875,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 +917,7 @@ static int skin_parse_conditional(struct skin_element* element, const char** doc const char *false_branch = NULL; const char *conditional_end = NULL; #endif + 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 +1016,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_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_parse_code_as_arg(&cursor); + if (children_array[i] == NULL) return 0; skip_whitespace(&cursor); #ifdef ROCKBOX @@ -1035,6 +1057,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 +1079,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 = -1; #else element->data = text = skin_alloc_string(length); if (!element->data) @@ -1131,7 +1154,8 @@ 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; @@ -1144,16 +1168,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); diff --git a/lib/skin_parser/skin_parser.h b/lib/skin_parser/skin_parser.h index 3e06349..c4df9a2 100644 --- a/lib/skin_parser/skin_parser.h +++ b/lib/skin_parser/skin_parser.h @@ -29,6 +29,20 @@ extern "C" #include #include + +/* Use this type and macro to convert a pointer from the + * skin buffer to a useable pointer */ +typedef long skinoffset; +#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 + /******************************************************************** ****** Data Structures ********************************************* *******************************************************************/ @@ -78,8 +92,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 +106,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; @@ -141,7 +155,7 @@ struct skin_element* skin_parse(const char* document); /* 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); +struct skin_tag_parameter* skin_alloc_params(int count); char* skin_alloc_string(int length); void skin_free_tree(struct skin_element* root);