1
0
Fork 0
forked from len0rd/rockbox

Use buflib for all skin engine allocations.

Massive thanks to Michael Chicoine and other testers for finding the early bugs.

This removes all skin memory limitations

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30991 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Jonathan Gordon 2011-11-15 14:11:08 +00:00
parent 101693fd30
commit 9e07ef2b0a
52 changed files with 954 additions and 862 deletions

View file

@ -175,22 +175,23 @@ bool skinlist_draw(struct screen *display, struct gui_synclist *list)
for (cur_line = 0; cur_line < display_lines; cur_line++) for (cur_line = 0; cur_line < display_lines; cur_line++)
{ {
struct skin_element* viewport; 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) if (list_start_item+cur_line+1 > list->nb_items)
break; break;
current_drawing_line = list_start_item+cur_line; current_drawing_line = list_start_item+cur_line;
is_selected = list->show_selection_marker && is_selected = list->show_selection_marker &&
list_start_item+cur_line == list->selected_item; list_start_item+cur_line == list->selected_item;
for (viewport = listcfg[screen]->data->tree; for (viewport = SKINOFFSETTOPTR(get_skin_buffer(wps.data), listcfg[screen]->data->tree);
viewport; viewport;
viewport = viewport->next) viewport = SKINOFFSETTOPTR(get_skin_buffer(wps.data), viewport->next))
{ {
int origional_x, origional_y; int origional_x, origional_y;
int origional_w, origional_h; int origional_w, origional_h;
char *viewport_label = SKINOFFSETTOPTR(get_skin_buffer(wps.data), skin_viewport->label);
skin_viewport = (struct skin_viewport*)viewport->data; skin_viewport = (struct skin_viewport*)viewport->data;
if (viewport->children == 0 || !skin_viewport->label || if (viewport->children == 0 || !viewport_label ||
(skin_viewport->label && strcmp(label, skin_viewport->label)) (skin_viewport->label && strcmp(label, viewport_label))
) )
continue; continue;
if (is_selected) if (is_selected)
@ -220,15 +221,17 @@ bool skinlist_draw(struct screen *display, struct gui_synclist *list)
display->set_viewport(&skin_viewport->vp); display->set_viewport(&skin_viewport->vp);
#ifdef HAVE_LCD_BITMAP #ifdef HAVE_LCD_BITMAP
/* Set images to not to be displayed */ /* Set images to not to be displayed */
struct skin_token_list *imglist = wps.data->images; struct skin_token_list *imglist = SKINOFFSETTOPTR(get_skin_buffer(wps.data), wps.data->images);
while (imglist) while (imglist)
{ {
struct gui_img *img = (struct gui_img *)imglist->token->value.data; struct wps_token *token = SKINOFFSETTOPTR(get_skin_buffer(wps.data), imglist->token);
struct gui_img *img = SKINOFFSETTOPTR(get_skin_buffer(wps.data), token->value.data);
img->display = -1; img->display = -1;
imglist = imglist->next; imglist = SKINOFFSETTOPTR(get_skin_buffer(wps.data), imglist->next);
} }
#endif #endif
skin_render_viewport(viewport->children[0], struct skin_element** children = SKINOFFSETTOPTR(get_skin_buffer(wps.data), viewport->children);
skin_render_viewport(children[0],
&wps, skin_viewport, SKIN_REFRESH_ALL); &wps, skin_viewport, SKIN_REFRESH_ALL);
#ifdef HAVE_LCD_BITMAP #ifdef HAVE_LCD_BITMAP
wps_display_images(&wps, &skin_viewport->vp); wps_display_images(&wps, &skin_viewport->vp);

View file

@ -102,7 +102,7 @@ void skin_statusbar_changed(struct gui_wps *skin)
struct wps_data *data = skin->data; struct wps_data *data = skin->data;
const struct screen *display = skin->display; const struct screen *display = skin->display;
const int screen = display->screen_type; 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; struct viewport *vp = &svp->vp;
viewport_set_defaults(vp, screen); 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) void draw_progressbar(struct gui_wps *gwps, int line, struct progressbar *pb)
{ {
struct screen *display = gwps->display; struct screen *display = gwps->display;
struct viewport *vp = pb->vp; struct viewport *vp = SKINOFFSETTOPTR(get_skin_buffer(gwps->data), pb->vp);
struct wps_state *state = skin_get_global_state(); struct wps_state *state = skin_get_global_state();
struct mp3entry *id3 = state->id3; struct mp3entry *id3 = state->id3;
int x = pb->x, y = pb->y, width = pb->width, height = pb->height; 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; flags |= INNER_NOFILL;
} }
if (pb->slider) if (SKINOFFSETTOPTR(get_skin_buffer(gwps->data), pb->slider))
{ {
struct gui_img *img = pb->slider; struct gui_img *img = SKINOFFSETTOPTR(get_skin_buffer(gwps->data), pb->slider);
/* clear the slider */ /* clear the slider */
screen_clear_area(display, x, y, width, height); screen_clear_area(display, x, y, width, height);
@ -245,9 +245,9 @@ void draw_progressbar(struct gui_wps *gwps, int line, struct progressbar *pb)
} }
} }
if (pb->backdrop) if (SKINOFFSETTOPTR(get_skin_buffer(gwps->data), pb->backdrop))
{ {
struct gui_img *img = pb->backdrop; struct gui_img *img = SKINOFFSETTOPTR(get_skin_buffer(gwps->data), pb->backdrop);
img->bm.data = core_get_data(img->buflib_handle); img->bm.data = core_get_data(img->buflib_handle);
display->bmp_part(&img->bm, 0, 0, x, y, width, height); display->bmp_part(&img->bm, 0, 0, x, y, width, height);
flags |= DONT_CLEAR_EXCESS; flags |= DONT_CLEAR_EXCESS;
@ -255,11 +255,12 @@ void draw_progressbar(struct gui_wps *gwps, int line, struct progressbar *pb)
if (!pb->nobar) if (!pb->nobar)
{ {
if (pb->image) struct gui_img *img = SKINOFFSETTOPTR(get_skin_buffer(gwps->data), pb->image);
if (img)
{ {
char *img_data = core_get_data(pb->image->buflib_handle); char *img_data = core_get_data(img->buflib_handle);
pb->image->bm.data = img_data; img->bm.data = img_data;
gui_bitmap_scrollbar_draw(display, &pb->image->bm, gui_bitmap_scrollbar_draw(display, &img->bm,
x, y, width, height, x, y, width, height,
length, 0, end, flags); length, 0, end, flags);
} }
@ -268,11 +269,11 @@ void draw_progressbar(struct gui_wps *gwps, int line, struct progressbar *pb)
length, 0, end, flags); length, 0, end, flags);
} }
if (pb->slider) if (SKINOFFSETTOPTR(get_skin_buffer(gwps->data), pb->slider))
{ {
int xoff = 0, yoff = 0; int xoff = 0, yoff = 0;
int w = width, h = height; int w = width, h = height;
struct gui_img *img = pb->slider; struct gui_img *img = SKINOFFSETTOPTR(get_skin_buffer(gwps->data), pb->slider);
img->bm.data = core_get_data(img->buflib_handle); img->bm.data = core_get_data(img->buflib_handle);
if (flags&HORIZONTAL) if (flags&HORIZONTAL)
@ -347,11 +348,12 @@ void wps_display_images(struct gui_wps *gwps, struct viewport* vp)
struct wps_data *data = gwps->data; struct wps_data *data = gwps->data;
struct screen *display = gwps->display; struct screen *display = gwps->display;
struct skin_token_list *list = data->images; struct skin_token_list *list = SKINOFFSETTOPTR(get_skin_buffer(data), data->images);
while (list) while (list)
{ {
struct gui_img *img = (struct gui_img*)list->token->value.data; struct wps_token *token = SKINOFFSETTOPTR(get_skin_buffer(data), list->token);
struct gui_img *img = (struct gui_img*)SKINOFFSETTOPTR(get_skin_buffer(data), token->value.data);
if (img->using_preloaded_icons && img->display >= 0) if (img->using_preloaded_icons && img->display >= 0)
{ {
screen_put_icon(display, img->x, img->y, img->display); screen_put_icon(display, img->x, img->y, img->display);
@ -362,20 +364,21 @@ void wps_display_images(struct gui_wps *gwps, struct viewport* vp)
{ {
wps_draw_image(gwps, img, img->display); wps_draw_image(gwps, img, img->display);
} }
else if (img->always_display && img->vp == vp) else if (img->always_display && SKINOFFSETTOPTR(get_skin_buffer(data), img->vp) == vp)
{ {
wps_draw_image(gwps, img, 0); wps_draw_image(gwps, img, 0);
} }
} }
list = list->next; list = SKINOFFSETTOPTR(get_skin_buffer(data), list->next);
} }
#ifdef HAVE_ALBUMART #ifdef HAVE_ALBUMART
/* now draw the AA */ /* now draw the AA */
if (data->albumart && data->albumart->vp == vp struct skin_albumart *aa = SKINOFFSETTOPTR(get_skin_buffer(data), data->albumart);
&& data->albumart->draw_handle >= 0) if (aa && SKINOFFSETTOPTR(get_skin_buffer(data), aa->vp) == vp
&& aa->draw_handle >= 0)
{ {
draw_album_art(gwps, data->albumart->draw_handle, false); draw_album_art(gwps, aa->draw_handle, false);
data->albumart->draw_handle = -1; aa->draw_handle = -1;
} }
#endif #endif
@ -398,8 +401,8 @@ int evaluate_conditional(struct gui_wps *gwps, int offset,
int intval = num_options < 2 ? 2 : num_options; int intval = num_options < 2 ? 2 : num_options;
/* get_token_value needs to know the number of options in the enum */ /* get_token_value needs to know the number of options in the enum */
value = get_token_value(gwps, conditional->token, offset, value = get_token_value(gwps, SKINOFFSETTOPTR(get_skin_buffer(gwps->data), conditional->token),
result, sizeof(result), &intval); offset, result, sizeof(result), &intval);
/* intval is now the number of the enum option we want to read, /* 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. */ starting from 1. If intval is -1, we check if value is empty. */

View file

@ -41,19 +41,10 @@
static bool skins_initialising = true; static bool skins_initialising = true;
/* App uses the host malloc to manage the buffer */ /* App uses the host malloc to manage the buffer */
#ifdef APPLICATION
#define skin_buffer NULL
void theme_init_buffer(void) void theme_init_buffer(void)
{ {
skins_initialising = false; skins_initialising = false;
} }
#else
static char skin_buffer[SKIN_BUFFER_SIZE];
void theme_init_buffer(void)
{
skins_initialising = false;
}
#endif
void skin_data_free_buflib_allocs(struct wps_data *wps_data); void skin_data_free_buflib_allocs(struct wps_data *wps_data);
char* wps_default_skin(enum screen_type screen); char* wps_default_skin(enum screen_type screen);
@ -95,8 +86,20 @@ void gui_sync_skin_init(void)
skins[j][i].gui_wps.display = &screens[i]; skins[j][i].gui_wps.display = &screens[i];
memset(skins[j][i].gui_wps.data, 0, sizeof(struct wps_data)); memset(skins[j][i].gui_wps.data, 0, sizeof(struct wps_data));
skins[j][i].data.wps_loaded = false; skins[j][i].data.wps_loaded = false;
skins[j][i].data.buflib_handle = -1;
skins[j][i].data.tree = -1;
#ifdef HAVE_TOUCHSCREEN
skins[j][i].data.touchregions = -1;
#endif
#ifdef HAVE_SKIN_VARIABLES
skins[j][i].data.skinvars = -1;
#endif
#ifdef HAVE_LCD_BITMAP
skins[j][i].data.font_ids = -1;
skins[j][i].data.images = -1;
#endif
#ifdef HAVE_ALBUMART #ifdef HAVE_ALBUMART
skins[j][i].data.albumart = NULL; skins[j][i].data.albumart = -1;
skins[j][i].data.playback_aa_slot = -1; skins[j][i].data.playback_aa_slot = -1;
#endif #endif
} }
@ -113,8 +116,6 @@ void skin_unload_all(void)
skin_data_free_buflib_allocs(&skins[j][i].data); skin_data_free_buflib_allocs(&skins[j][i].data);
} }
skin_buffer_init(skin_buffer, SKIN_BUFFER_SIZE);
#ifdef HAVE_LCD_BITMAP #ifdef HAVE_LCD_BITMAP
skin_backdrop_init(); skin_backdrop_init();
#endif #endif
@ -245,7 +246,6 @@ struct gui_wps *skin_get_gwps(enum skinnable_screens skin, enum screen_type scre
cpu_boost(false); cpu_boost(false);
loading_a_sbs = false; loading_a_sbs = false;
} }
return &skins[skin][screen].gui_wps; return &skins[skin][screen].gui_wps;
} }

File diff suppressed because it is too large Load diff

View file

@ -27,6 +27,7 @@
#include "strlcat.h" #include "strlcat.h"
#include "config.h" #include "config.h"
#include "core_alloc.h"
#include "kernel.h" #include "kernel.h"
#ifdef HAVE_ALBUMART #ifdef HAVE_ALBUMART
#include "albumart.h" #include "albumart.h"
@ -81,6 +82,18 @@ static void skin_render_playlistviewer(struct playlistviewer* viewer,
unsigned long refresh_type); unsigned long refresh_type);
#endif #endif
static char* skin_buffer;
/* hack alert: fix skin_parser.c's skin_buffer pointer */
void skinparser_set_buffer(char* pointer);
static inline struct skin_element*
get_child(OFFSETTYPE(struct skin_element**) children, int child)
{
OFFSETTYPE(struct skin_element*) *kids = SKINOFFSETTOPTR(skin_buffer, children);
return SKINOFFSETTOPTR(skin_buffer, kids[child]);
}
static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info, static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
struct skin_element *element, struct viewport* vp) struct skin_element *element, struct viewport* vp)
{ {
@ -88,7 +101,7 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
(void)vp; /* silence warnings */ (void)vp; /* silence warnings */
(void)info; (void)info;
#endif #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 #ifdef HAVE_LCD_BITMAP
struct wps_data *data = gwps->data; struct wps_data *data = gwps->data;
@ -99,14 +112,16 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
#if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)) #if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1))
case SKIN_TOKEN_VIEWPORT_FGCOLOUR: case SKIN_TOKEN_VIEWPORT_FGCOLOUR:
{ {
struct viewport_colour *col = token->value.data; struct viewport_colour *col = SKINOFFSETTOPTR(skin_buffer, token->value.data);
col->vp->fg_pattern = col->colour; struct viewport *vp = SKINOFFSETTOPTR(skin_buffer, col->vp);
vp->fg_pattern = col->colour;
} }
break; break;
case SKIN_TOKEN_VIEWPORT_BGCOLOUR: case SKIN_TOKEN_VIEWPORT_BGCOLOUR:
{ {
struct viewport_colour *col = token->value.data; struct viewport_colour *col = SKINOFFSETTOPTR(skin_buffer, token->value.data);
col->vp->bg_pattern = col->colour; struct viewport *vp = SKINOFFSETTOPTR(skin_buffer, col->vp);
vp->bg_pattern = col->colour;
} }
break; break;
case SKIN_TOKEN_VIEWPORT_TEXTSTYLE: case SKIN_TOKEN_VIEWPORT_TEXTSTYLE:
@ -116,7 +131,7 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
#ifdef HAVE_LCD_COLOR #ifdef HAVE_LCD_COLOR
case SKIN_TOKEN_VIEWPORT_GRADIENT_SETUP: 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->lss_pattern = cfg->start;
vp->lse_pattern = cfg->end; vp->lse_pattern = cfg->end;
vp->lst_pattern = cfg->text; vp->lst_pattern = cfg->text;
@ -125,14 +140,18 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
#endif #endif
case SKIN_TOKEN_VIEWPORT_ENABLE: case SKIN_TOKEN_VIEWPORT_ENABLE:
{ {
char *label = token->value.data; char *label = SKINOFFSETTOPTR(skin_buffer, token->value.data);
char temp = VP_DRAW_HIDEABLE; char temp = VP_DRAW_HIDEABLE;
struct skin_element *viewport = gwps->data->tree; struct skin_element *viewport = SKINOFFSETTOPTR(skin_buffer, gwps->data->tree);
while (viewport) while (viewport)
{ {
struct skin_viewport *skinvp = (struct skin_viewport*)viewport->data; struct skin_viewport *skinvp = SKINOFFSETTOPTR(skin_buffer, viewport->data);
if (skinvp->label && !skinvp->is_infovp &&
!strcmp(skinvp->label, label)) 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) if (skinvp->hidden_flags&VP_DRAW_HIDDEN)
{ {
@ -140,7 +159,7 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
} }
skinvp->hidden_flags = temp; skinvp->hidden_flags = temp;
} }
viewport = viewport->next; viewport = SKINOFFSETTOPTR(skin_buffer, viewport->next);
} }
} }
break; break;
@ -148,11 +167,10 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
case SKIN_TOKEN_LIST_ITEM_CFG: case SKIN_TOKEN_LIST_ITEM_CFG:
if (do_refresh) if (do_refresh)
skinlist_set_cfg(gwps->display->screen_type, skinlist_set_cfg(gwps->display->screen_type,
token->value.data); SKINOFFSETTOPTR(skin_buffer, token->value.data));
break; break;
case SKIN_TOKEN_UIVIEWPORT_ENABLE: case SKIN_TOKEN_UIVIEWPORT_ENABLE:
sb_set_info_vp(gwps->display->screen_type, sb_set_info_vp(gwps->display->screen_type, token->value.data);
token->value.data);
break; break;
case SKIN_TOKEN_PEAKMETER: case SKIN_TOKEN_PEAKMETER:
data->peak_meter_enabled = true; data->peak_meter_enabled = true;
@ -173,7 +191,7 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
case SKIN_TOKEN_TUNER_RSSI_BAR: case SKIN_TOKEN_TUNER_RSSI_BAR:
case SKIN_TOKEN_LIST_SCROLLBAR: 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) if (do_refresh)
draw_progressbar(gwps, info->line_number, bar); draw_progressbar(gwps, info->line_number, bar);
} }
@ -183,12 +201,12 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
case SKIN_TOKEN_IMAGE_DISPLAY_LISTICON: case SKIN_TOKEN_IMAGE_DISPLAY_LISTICON:
case SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY: case SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY:
{ {
struct image_display *id = token->value.data; struct image_display *id = SKINOFFSETTOPTR(skin_buffer, token->value.data);
const char* label = id->label; const char* label = SKINOFFSETTOPTR(skin_buffer, id->label);
struct gui_img *img = skin_find_item(label,SKIN_FIND_IMAGE, data); struct gui_img *img = skin_find_item(label,SKIN_FIND_IMAGE, data);
if (img && img->loaded) if (img && img->loaded)
{ {
if (id->token == NULL) if (SKINOFFSETTOPTR(skin_buffer, id->token) == NULL)
{ {
img->display = id->subimage; img->display = id->subimage;
} }
@ -197,8 +215,8 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
char buf[16]; char buf[16];
const char *out; const char *out;
int a = img->num_subimages; int a = img->num_subimages;
out = get_token_value(gwps, id->token, info->offset, out = get_token_value(gwps, SKINOFFSETTOPTR(skin_buffer, id->token),
buf, sizeof(buf), &a); info->offset, buf, sizeof(buf), &a);
/* NOTE: get_token_value() returns values starting at 1! */ /* NOTE: get_token_value() returns values starting at 1! */
if (a == -1) if (a == -1)
@ -224,29 +242,32 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
} }
#ifdef HAVE_ALBUMART #ifdef HAVE_ALBUMART
case SKIN_TOKEN_ALBUMART_DISPLAY: case SKIN_TOKEN_ALBUMART_DISPLAY:
{
struct skin_albumart *aa = SKINOFFSETTOPTR(skin_buffer, data->albumart);
/* now draw the AA */ /* now draw the AA */
if (do_refresh && data->albumart) if (do_refresh && aa)
{ {
int handle = playback_current_aa_hid(data->playback_aa_slot); int handle = playback_current_aa_hid(data->playback_aa_slot);
#if CONFIG_TUNER #if CONFIG_TUNER
if (in_radio_screen() || (get_radio_status() != FMRADIO_OFF)) 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); handle = radio_get_art_hid(&dim);
} }
#endif #endif
data->albumart->draw_handle = handle; aa->draw_handle = handle;
} }
break; break;
}
#endif #endif
case SKIN_TOKEN_DRAW_INBUILTBAR: case SKIN_TOKEN_DRAW_INBUILTBAR:
gui_statusbar_draw(&(statusbars.statusbars[gwps->display->screen_type]), gui_statusbar_draw(&(statusbars.statusbars[gwps->display->screen_type]),
info->refresh_type == SKIN_REFRESH_ALL, info->refresh_type == SKIN_REFRESH_ALL,
token->value.data); SKINOFFSETTOPTR(skin_buffer, token->value.data));
break; break;
case SKIN_TOKEN_VIEWPORT_CUSTOMLIST: case SKIN_TOKEN_VIEWPORT_CUSTOMLIST:
if (do_refresh) 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); info->skin_vp, info->refresh_type);
break; break;
@ -255,23 +276,24 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
case SKIN_TOKEN_VAR_SET: case SKIN_TOKEN_VAR_SET:
if (do_refresh) 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) if (data->direct)
data->var->value = data->newval; var->value = data->newval;
else else
{ {
data->var->value += data->newval; var->value += data->newval;
if (data->max) if (data->max)
{ {
if (data->var->value > data->max) if (var->value > data->max)
data->var->value = 1; var->value = 1;
else if (data->var->value < 1) else if (var->value < 1)
data->var->value = data->max; var->value = data->max;
} }
} }
if (data->var->value < 1) if (var->value < 1)
data->var->value = 1; var->value = 1;
data->var->last_changed = current_tick; var->last_changed = current_tick;
} }
break; break;
#endif #endif
@ -289,7 +311,7 @@ static void do_tags_in_hidden_conditional(struct skin_element* branch,
#ifdef HAVE_LCD_BITMAP #ifdef HAVE_LCD_BITMAP
struct gui_wps *gwps = info->gwps; struct gui_wps *gwps = info->gwps;
struct wps_data *data = gwps->data; struct wps_data *data = gwps->data;
#endif #endif
/* Tags here are ones which need to be "turned off" or cleared /* Tags here are ones which need to be "turned off" or cleared
* if they are in a conditional branch which isnt being used */ * if they are in a conditional branch which isnt being used */
if (branch->type == LINE_ALTERNATOR) if (branch->type == LINE_ALTERNATOR)
@ -297,12 +319,12 @@ static void do_tags_in_hidden_conditional(struct skin_element* branch,
int i; int i;
for (i=0; i<branch->children_count; i++) for (i=0; i<branch->children_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) 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) #if defined(HAVE_LCD_BITMAP) || defined(HAVE_ALBUMART)
struct wps_token *token; struct wps_token *token;
#endif #endif
@ -313,25 +335,25 @@ static void do_tags_in_hidden_conditional(struct skin_element* branch,
int i; int i;
for (i=0; i<child->children_count; i++) for (i=0; i<child->children_count; i++)
{ {
do_tags_in_hidden_conditional(child->children[i], info); do_tags_in_hidden_conditional(get_child(child->children, i), info);
} }
child = child->next; child = SKINOFFSETTOPTR(skin_buffer, child->next);
continue; 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; continue;
} }
#if defined(HAVE_LCD_BITMAP) || defined(HAVE_ALBUMART) #if defined(HAVE_LCD_BITMAP) || defined(HAVE_ALBUMART)
token = (struct wps_token *)child->data; token = (struct wps_token *)SKINOFFSETTOPTR(skin_buffer, child->data);
#endif #endif
#ifdef HAVE_LCD_BITMAP #ifdef HAVE_LCD_BITMAP
/* clear all pictures in the conditional and nested ones */ /* clear all pictures in the conditional and nested ones */
if (token->type == SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY) if (token->type == SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY)
{ {
struct image_display *id = token->value.data; struct image_display *id = SKINOFFSETTOPTR(skin_buffer, token->value.data);
struct gui_img *img = skin_find_item(id->label, struct gui_img *img = skin_find_item(SKINOFFSETTOPTR(skin_buffer, id->label),
SKIN_FIND_IMAGE, data); SKIN_FIND_IMAGE, data);
clear_image_pos(gwps, img); clear_image_pos(gwps, img);
} }
@ -341,14 +363,18 @@ static void do_tags_in_hidden_conditional(struct skin_element* branch,
} }
else if (token->type == SKIN_TOKEN_VIEWPORT_ENABLE) 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; struct skin_element *viewport;
for (viewport = data->tree; for (viewport = SKINOFFSETTOPTR(skin_buffer, data->tree);
viewport; viewport;
viewport = viewport->next) viewport = SKINOFFSETTOPTR(skin_buffer, viewport->next))
{ {
struct skin_viewport *skin_viewport = (struct skin_viewport*)viewport->data; struct skin_viewport *skin_viewport = SKINOFFSETTOPTR(skin_buffer, viewport->data);
if (skin_viewport->label && strcmp(skin_viewport->label, label))
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; continue;
if (skin_viewport->hidden_flags&VP_NEVER_VISIBLE) if (skin_viewport->hidden_flags&VP_NEVER_VISIBLE)
{ {
@ -377,7 +403,7 @@ static void do_tags_in_hidden_conditional(struct skin_element* branch,
playback_current_aa_hid(data->playback_aa_slot), true); playback_current_aa_hid(data->playback_aa_slot), true);
} }
#endif #endif
child = child->next; child = SKINOFFSETTOPTR(skin_buffer, child->next);
} }
} }
} }
@ -433,7 +459,7 @@ static bool skin_render_line(struct skin_element* line, struct skin_draw_info *i
if (line->children_count == 0) if (line->children_count == 0)
return false; /* empty line, do nothing */ 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; struct conditional *conditional;
skin_render_func func = skin_render_line; skin_render_func func = skin_render_line;
int old_refresh_mode = info->refresh_type; int old_refresh_mode = info->refresh_type;
@ -442,7 +468,7 @@ static bool skin_render_line(struct skin_element* line, struct skin_draw_info *i
switch (child->type) switch (child->type)
{ {
case CONDITIONAL: case CONDITIONAL:
conditional = (struct conditional*)child->data; conditional = SKINOFFSETTOPTR(skin_buffer, child->data);
last_value = conditional->last_value; last_value = conditional->last_value;
value = evaluate_conditional(info->gwps, info->offset, value = evaluate_conditional(info->gwps, info->offset,
conditional, child->children_count); conditional, child->children_count);
@ -456,20 +482,20 @@ static bool skin_render_line(struct skin_element* line, struct skin_draw_info *i
{ {
/* we are in a false branch of a %?aa<true> conditional */ /* we are in a false branch of a %?aa<true> conditional */
if (last_value == 0) 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; break;
} }
} }
else else
{ {
if (last_value >= 0 && value != last_value && last_value < child->children_count) 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; func = skin_render_alternator;
} }
else if (child->children[value]->type == LINE) else if (get_child(child->children, value)->type == LINE)
func = skin_render_line; func = skin_render_line;
if (value != last_value) if (value != last_value)
@ -478,7 +504,7 @@ static bool skin_render_line(struct skin_element* line, struct skin_draw_info *i
info->force_redraw = true; info->force_redraw = true;
} }
if (func(child->children[value], info)) if (func(get_child(child->children, value), info))
needs_update = true; needs_update = true;
else else
needs_update = needs_update || (last_value != value); needs_update = needs_update || (last_value != value);
@ -493,14 +519,14 @@ static bool skin_render_line(struct skin_element* line, struct skin_draw_info *i
fix_line_alignment(info, child); fix_line_alignment(info, child);
if (!child->data) if (!SKINOFFSETTOPTR(skin_buffer, child->data))
{ {
break; break;
} }
if (!do_non_text_tags(info->gwps, info, child, &info->skin_vp->vp)) if (!do_non_text_tags(info->gwps, info, child, &info->skin_vp->vp))
{ {
static char tempbuf[128]; 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, info->offset, tempbuf,
sizeof(tempbuf), NULL); sizeof(tempbuf), NULL);
if (valuestr) if (valuestr)
@ -517,7 +543,7 @@ static bool skin_render_line(struct skin_element* line, struct skin_draw_info *i
} }
break; break;
case TEXT: 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)); info->buf_size - (info->cur_align_start-info->buf));
needs_update = needs_update || needs_update = needs_update ||
(info->refresh_type&SKIN_REFRESH_STATIC) != 0; (info->refresh_type&SKIN_REFRESH_STATIC) != 0;
@ -527,7 +553,7 @@ static bool skin_render_line(struct skin_element* line, struct skin_draw_info *i
break; break;
} }
child = child->next; child = SKINOFFSETTOPTR(skin_buffer, child->next);
} }
return needs_update; return needs_update;
} }
@ -541,29 +567,29 @@ static int get_subline_timeout(struct gui_wps *gwps, struct skin_element* line)
{ {
if (element->children_count == 0) if (element->children_count == 0)
return retval; /* empty line, so force redraw */ return retval; /* empty line, so force redraw */
element = element->children[0]; element = get_child(element->children, 0);
} }
while (element) while (element)
{ {
if (element->type == TAG && if (element->type == TAG &&
element->tag->type == SKIN_TOKEN_SUBLINE_TIMEOUT ) element->tag->type == SKIN_TOKEN_SUBLINE_TIMEOUT )
{ {
token = element->data; token = SKINOFFSETTOPTR(skin_buffer, element->data);
return token->value.i; return token->value.i;
} }
else if (element->type == CONDITIONAL) 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, int val = evaluate_conditional(gwps, 0, conditional,
element->children_count); element->children_count);
if (val >= 0) if (val >= 0)
{ {
retval = get_subline_timeout(gwps, element->children[val]); retval = get_subline_timeout(gwps, get_child(element->children, val));
if (retval >= 0) if (retval >= 0)
return retval; return retval;
} }
} }
element = element->next; element = SKINOFFSETTOPTR(skin_buffer, element->next);
} }
return retval; return retval;
} }
@ -571,7 +597,7 @@ static int get_subline_timeout(struct gui_wps *gwps, struct skin_element* line)
bool skin_render_alternator(struct skin_element* element, struct skin_draw_info *info) bool skin_render_alternator(struct skin_element* element, struct skin_draw_info *info)
{ {
bool changed_lines = false; 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; unsigned old_refresh = info->refresh_type;
if (info->refresh_type == SKIN_REFRESH_ALL) if (info->refresh_type == SKIN_REFRESH_ALL)
{ {
@ -597,11 +623,11 @@ bool skin_render_alternator(struct skin_element* element, struct skin_draw_info
try_line++; try_line++;
if (try_line >= element->children_count) if (try_line >= element->children_count)
try_line = 0; 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, rettimeout = get_subline_timeout(info->gwps,
current_line->children[0]); get_child(current_line->children, 0));
if (rettimeout > 0) if (rettimeout > 0)
{ {
suitable = true; suitable = true;
@ -619,7 +645,7 @@ bool skin_render_alternator(struct skin_element* element, struct skin_draw_info
info->refresh_type = SKIN_REFRESH_ALL; info->refresh_type = SKIN_REFRESH_ALL;
info->force_redraw = true; 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; info->refresh_type = old_refresh;
return changed_lines || ret; return changed_lines || ret;
} }
@ -646,14 +672,17 @@ void skin_render_viewport(struct skin_element* viewport, struct gui_wps *gwps,
struct align_pos * align = &info.align; struct align_pos * align = &info.align;
bool needs_update; bool needs_update;
skin_buffer = get_skin_buffer(gwps->data);
skinparser_set_buffer(skin_buffer);
#ifdef HAVE_LCD_BITMAP #ifdef HAVE_LCD_BITMAP
/* Set images to not to be displayed */ /* 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) 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; img->display = -1;
imglist = imglist->next; imglist = SKINOFFSETTOPTR(skin_buffer, imglist->next);
} }
/* fix font ID's */ /* fix font ID's */
@ -716,7 +745,7 @@ void skin_render_viewport(struct skin_element* viewport, struct gui_wps *gwps,
} }
if (!info.no_line_break) if (!info.no_line_break)
info.line_number++; info.line_number++;
line = line->next; line = SKINOFFSETTOPTR(skin_buffer, line->next);
} }
#ifdef HAVE_LCD_BITMAP #ifdef HAVE_LCD_BITMAP
wps_display_images(gwps, &skin_viewport->vp); wps_display_images(gwps, &skin_viewport->vp);
@ -730,8 +759,11 @@ void skin_render(struct gui_wps *gwps, unsigned refresh_mode)
struct skin_element* viewport; struct skin_element* viewport;
struct skin_viewport* skin_viewport; struct skin_viewport* skin_viewport;
char *label;
int old_refresh_mode = refresh_mode; int old_refresh_mode = refresh_mode;
skin_buffer = get_skin_buffer(gwps->data);
skinparser_set_buffer(skin_buffer);
#ifdef HAVE_LCD_CHARCELLS #ifdef HAVE_LCD_CHARCELLS
int i; int i;
@ -741,18 +773,21 @@ void skin_render(struct gui_wps *gwps, unsigned refresh_mode)
data->wps_progress_pat[i] = display->get_locked_pattern(); data->wps_progress_pat[i] = display->get_locked_pattern();
} }
#endif #endif
viewport = data->tree; viewport = SKINOFFSETTOPTR(skin_buffer, data->tree);
skin_viewport = (struct skin_viewport *)viewport->data; skin_viewport = SKINOFFSETTOPTR(skin_buffer, viewport->data);
if (skin_viewport->label && viewport->next && label = SKINOFFSETTOPTR(skin_buffer, skin_viewport->label);
!strcmp(skin_viewport->label,VP_DEFAULT_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; refresh_mode = 0;
for (viewport = data->tree; for (viewport = SKINOFFSETTOPTR(skin_buffer, data->tree);
viewport; viewport;
viewport = viewport->next) viewport = SKINOFFSETTOPTR(skin_buffer, viewport->next))
{ {
/* SETUP */ /* SETUP */
skin_viewport = (struct skin_viewport*)viewport->data; skin_viewport = SKINOFFSETTOPTR(skin_buffer, viewport->data);
unsigned vp_refresh_mode = refresh_mode; unsigned vp_refresh_mode = refresh_mode;
#if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1) #if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1)
skin_viewport->vp.fg_pattern = skin_viewport->start_fgcolour; skin_viewport->vp.fg_pattern = skin_viewport->start_fgcolour;
@ -789,7 +824,7 @@ void skin_render(struct gui_wps *gwps, unsigned refresh_mode)
} }
/* render */ /* render */
if (viewport->children_count) 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); skin_viewport, vp_refresh_mode);
refresh_mode = old_refresh_mode; refresh_mode = old_refresh_mode;
} }
@ -826,7 +861,7 @@ void skin_render_playlistviewer(struct playlistviewer* viewer,
struct align_pos * align = &info.align; struct align_pos * align = &info.align;
bool needs_update; bool needs_update;
int cur_pos, start_item, max; 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 CONFIG_TUNER
if (get_current_activity() == ACTIVITY_FM) if (get_current_activity() == ACTIVITY_FM)
{ {
@ -848,7 +883,7 @@ void skin_render_playlistviewer(struct playlistviewer* viewer,
if (max-start_item > nb_lines) if (max-start_item > nb_lines)
max = start_item + nb_lines; max = start_item + nb_lines;
line = viewer->line; line = SKINOFFSETTOPTR(skin_buffer, viewer->line);
while (start_item < max) while (start_item < max)
{ {
linebuf[0] = '\0'; linebuf[0] = '\0';

View file

@ -36,6 +36,7 @@
#include "debug.h" #include "debug.h"
#include "cuesheet.h" #include "cuesheet.h"
#include "replaygain.h" #include "replaygain.h"
#include "core_alloc.h"
#ifdef HAVE_LCD_CHARCELLS #ifdef HAVE_LCD_CHARCELLS
#include "hwcompat.h" #include "hwcompat.h"
#endif #endif
@ -732,18 +733,21 @@ static const char* NOINLINE get_lif_token_value(struct gui_wps *gwps,
{ {
int a = lif->num_options; int a = lif->num_options;
int b; int b;
const char* out_text = get_token_value(gwps, lif->token, offset, struct wps_token *liftoken = SKINOFFSETTOPTR(get_skin_buffer(gwps->data), lif->token);
buf, buf_size, &a); const char* out_text = get_token_value(gwps, liftoken, offset, buf, buf_size, &a);
if (a == -1 && lif->token->type != SKIN_TOKEN_VOLUME) if (a == -1 && liftoken->type != SKIN_TOKEN_VOLUME)
a = (out_text && *out_text) ? 1 : 0; a = (out_text && *out_text) ? 1 : 0;
switch (lif->operand.type) switch (lif->operand.type)
{ {
case STRING: case STRING:
{
char *cmp = SKINOFFSETTOPTR(get_skin_buffer(gwps->data), lif->operand.data.text);
if (out_text == NULL) if (out_text == NULL)
return NULL; return NULL;
a = strcmp(out_text, lif->operand.data.text); a = strcmp(out_text, cmp);
b = 0; b = 0;
break; break;
}
case INTEGER: case INTEGER:
case DECIMAL: case DECIMAL:
b = lif->operand.data.number; b = lif->operand.data.number;
@ -752,11 +756,12 @@ static const char* NOINLINE get_lif_token_value(struct gui_wps *gwps,
{ {
char temp_buf[MAX_PATH]; char temp_buf[MAX_PATH];
const char *outb; const char *outb;
struct wps_token *token = lif->operand.data.code->data; struct skin_element *element = SKINOFFSETTOPTR(get_skin_buffer(gwps->data), lif->operand.data.code);
struct wps_token *token = SKINOFFSETTOPTR(get_skin_buffer(gwps->data), element->data);
b = lif->num_options; b = lif->num_options;
outb = get_token_value(gwps, token, offset, temp_buf, outb = get_token_value(gwps, token, offset, temp_buf,
sizeof(temp_buf), &b); 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) if (!out_text || !outb)
return (lif->op == IF_EQUALS) ? NULL : "neq"; return (lif->op == IF_EQUALS) ? NULL : "neq";
@ -865,14 +870,15 @@ const char *get_token_value(struct gui_wps *gwps,
{ {
case SKIN_TOKEN_LOGICAL_IF: case SKIN_TOKEN_LOGICAL_IF:
{ {
struct logical_if *lif = token->value.data; struct logical_if *lif = SKINOFFSETTOPTR(get_skin_buffer(data), token->value.data);
return get_lif_token_value(gwps, lif, offset, buf, buf_size); return get_lif_token_value(gwps, lif, offset, buf, buf_size);
} }
break; break;
case SKIN_TOKEN_SUBSTRING: case SKIN_TOKEN_SUBSTRING:
{ {
struct substring *ss = token->value.data; struct substring *ss = SKINOFFSETTOPTR(get_skin_buffer(data), token->value.data);
const char *token_val = get_token_value(gwps, ss->token, offset, const char *token_val = get_token_value(gwps,
SKINOFFSETTOPTR(get_skin_buffer(data), ss->token), offset,
buf, buf_size, intval); buf, buf_size, intval);
if (token_val) if (token_val)
{ {
@ -909,7 +915,7 @@ const char *get_token_value(struct gui_wps *gwps,
return &(token->value.c); return &(token->value.c);
case SKIN_TOKEN_STRING: case SKIN_TOKEN_STRING:
return (char*)token->value.data; return (char*)SKINOFFSETTOPTR(get_skin_buffer(data), token->value.data);
case SKIN_TOKEN_TRANSLATEDSTRING: case SKIN_TOKEN_TRANSLATEDSTRING:
return (char*)P2STR(ID2P(token->value.i)); return (char*)P2STR(ID2P(token->value.i));
@ -929,7 +935,7 @@ const char *get_token_value(struct gui_wps *gwps,
return buf; return buf;
case SKIN_TOKEN_LIST_ITEM_TEXT: case SKIN_TOKEN_LIST_ITEM_TEXT:
{ {
struct listitem *li = (struct listitem *)token->value.data; struct listitem *li = (struct listitem *)SKINOFFSETTOPTR(get_skin_buffer(data), token->value.data);
return skinlist_get_item_text(li->offset, li->wrap, buf, buf_size); return skinlist_get_item_text(li->offset, li->wrap, buf, buf_size);
} }
case SKIN_TOKEN_LIST_ITEM_NUMBER: case SKIN_TOKEN_LIST_ITEM_NUMBER:
@ -941,7 +947,7 @@ const char *get_token_value(struct gui_wps *gwps,
return skinlist_is_selected_item()?"s":""; return skinlist_is_selected_item()?"s":"";
case SKIN_TOKEN_LIST_ITEM_ICON: case SKIN_TOKEN_LIST_ITEM_ICON:
{ {
struct listitem *li = (struct listitem *)token->value.data; struct listitem *li = (struct listitem *)SKINOFFSETTOPTR(get_skin_buffer(data), token->value.data);
int icon = skinlist_get_item_icon(li->offset, li->wrap); int icon = skinlist_get_item_icon(li->offset, li->wrap);
if (intval) if (intval)
*intval = icon; *intval = icon;
@ -997,14 +1003,15 @@ const char *get_token_value(struct gui_wps *gwps,
return buf; return buf;
#ifdef HAVE_ALBUMART #ifdef HAVE_ALBUMART
case SKIN_TOKEN_ALBUMART_FOUND: case SKIN_TOKEN_ALBUMART_FOUND:
if (data->albumart) if (SKINOFFSETTOPTR(get_skin_buffer(data), data->albumart))
{ {
int handle = -1; int handle = -1;
handle = playback_current_aa_hid(data->playback_aa_slot); handle = playback_current_aa_hid(data->playback_aa_slot);
#if CONFIG_TUNER #if CONFIG_TUNER
if (in_radio_screen() || (get_radio_status() != FMRADIO_OFF)) if (in_radio_screen() || (get_radio_status() != FMRADIO_OFF))
{ {
struct dim dim = {data->albumart->width, data->albumart->height}; struct skin_albumart *aa = SKINOFFSETTOPTR(get_skin_buffer(data), data->albumart);
struct dim dim = {aa->width, aa->height};
handle = radio_get_art_hid(&dim); handle = radio_get_art_hid(&dim);
} }
#endif #endif
@ -1473,9 +1480,11 @@ const char *get_token_value(struct gui_wps *gwps,
{ {
#ifdef HAVE_TOUCHSCREEN #ifdef HAVE_TOUCHSCREEN
unsigned int last_touch = touchscreen_last_touch(); unsigned int last_touch = touchscreen_last_touch();
struct touchregion_lastpress *data = token->value.data; char *skin_base = get_skin_buffer(data);
if (data->region) struct touchregion_lastpress *data = SKINOFFSETTOPTR(skin_base, token->value.data);
last_touch = data->region->last_press; struct touchregion *region = SKINOFFSETTOPTR(skin_base, data->region);
if (region)
last_touch = region->last_press;
if (last_touch != 0xffff && if (last_touch != 0xffff &&
TIME_BEFORE(current_tick, data->timeout + last_touch)) TIME_BEFORE(current_tick, data->timeout + last_touch))
@ -1805,7 +1814,8 @@ const char *get_token_value(struct gui_wps *gwps,
#ifdef HAVE_SKIN_VARIABLES #ifdef HAVE_SKIN_VARIABLES
case SKIN_TOKEN_VAR_GETVAL: case SKIN_TOKEN_VAR_GETVAL:
{ {
struct skin_var* var = token->value.data; char *skin_base = get_skin_buffer(data);
struct skin_var* var = SKINOFFSETTOPTR(skin_base, token->value.data);
if (intval) if (intval)
*intval = var->value; *intval = var->value;
snprintf(buf, buf_size, "%d", var->value); snprintf(buf, buf_size, "%d", var->value);
@ -1814,8 +1824,10 @@ const char *get_token_value(struct gui_wps *gwps,
break; break;
case SKIN_TOKEN_VAR_TIMEOUT: case SKIN_TOKEN_VAR_TIMEOUT:
{ {
struct skin_var_lastchange *data = token->value.data; char *skin_base = get_skin_buffer(data);
unsigned int last_change = data->var->last_changed; struct skin_var_lastchange *data = SKINOFFSETTOPTR(skin_base, token->value.data);
struct skin_var* var = SKINOFFSETTOPTR(skin_base, data->var);
unsigned int last_change = var->last_changed;
if (last_change != 0xffff && if (last_change != 0xffff &&
TIME_BEFORE(current_tick, data->timeout + last_change)) TIME_BEFORE(current_tick, data->timeout + last_change))

View file

@ -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 <stdbool.h>
#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

View file

@ -37,11 +37,14 @@
/** Disarms all touchregions. */ /** Disarms all touchregions. */
void skin_disarm_touchregions(struct wps_data *data) void skin_disarm_touchregions(struct wps_data *data)
{ {
struct skin_token_list *regions = data->touchregions; char* skin_buffer = get_skin_buffer(data);
struct skin_token_list *regions = SKINOFFSETTOPTR(skin_buffer, data->touchregions);
while (regions) while (regions)
{ {
((struct touchregion *)regions->token->value.data)->armed = false; struct wps_token *token = SKINOFFSETTOPTR(skin_buffer, regions->token);
regions = regions->next; struct touchregion *region = SKINOFFSETTOPTR(skin_buffer, token->value.data);
region->armed = false;
regions = SKINOFFSETTOPTR(skin_buffer, regions->next);
} }
} }
@ -56,35 +59,39 @@ int skin_get_touchaction(struct wps_data *data, int* edge_offset,
short x,y; short x,y;
short vx, vy; short vx, vy;
int type = action_get_touchscreen_press(&x, &y); int type = action_get_touchscreen_press(&x, &y);
struct skin_viewport *wvp;
struct touchregion *r, *temp = NULL; struct touchregion *r, *temp = NULL;
char* skin_buffer = get_skin_buffer(data);
bool repeated = (type == BUTTON_REPEAT); bool repeated = (type == BUTTON_REPEAT);
bool released = (type == BUTTON_REL); bool released = (type == BUTTON_REL);
bool pressed = (type == BUTTON_TOUCHSCREEN); 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; bool needs_repeat;
while (regions) while (regions)
{ {
r = (struct touchregion *)regions->token->value.data; struct wps_token *token = SKINOFFSETTOPTR(skin_buffer, regions->token);
r = SKINOFFSETTOPTR(skin_buffer, token->value.data);
wvp = SKINOFFSETTOPTR(skin_buffer, r->wvp);
/* make sure this region's viewport is visible */ /* 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; continue;
} }
if (data->touchscreen_locked && if (data->touchscreen_locked &&
(r->action != ACTION_TOUCH_SOFTLOCK && !r->allow_while_locked)) (r->action != ACTION_TOUCH_SOFTLOCK && !r->allow_while_locked))
{ {
regions = regions->next; regions = SKINOFFSETTOPTR(skin_buffer, regions->next);
continue; continue;
} }
needs_repeat = r->press_length != PRESS; needs_repeat = r->press_length != PRESS;
/* check if it's inside this viewport */ /* 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 { /* reposition the touch inside the viewport since touchregions
* are relative to a preceding viewport */ * are relative to a preceding viewport */
vx = x - r->wvp->vp.x; vx = x - wvp->vp.x;
vy = y - r->wvp->vp.y; vy = y - wvp->vp.y;
/* now see if the point is inside this region */ /* now see if the point is inside this region */
if (vx >= r->x && vx < r->x+r->width && if (vx >= r->x && vx < r->x+r->width &&
vy >= r->y && vy < r->y+r->height) vy >= r->y && vy < r->y+r->height)
@ -127,7 +134,7 @@ int skin_get_touchaction(struct wps_data *data, int* edge_offset,
} }
} }
} }
regions = regions->next; regions = SKINOFFSETTOPTR(skin_buffer, regions->next);
} }
/* On release, all regions are disarmed. */ /* On release, all regions are disarmed. */
@ -214,7 +221,7 @@ int skin_get_touchaction(struct wps_data *data, int* edge_offset,
{ {
case F_T_CUSTOM: case F_T_CUSTOM:
s->custom_setting s->custom_setting
->load_from_cfg(s->setting, data->value.text); ->load_from_cfg(s->setting, SKINOFFSETTOPTR(skin_buffer, data->value.text));
break; break;
case F_T_INT: case F_T_INT:
case F_T_UINT: case F_T_UINT:

View file

@ -25,6 +25,11 @@
#ifndef _WPS_ENGINE_INTERNALS_ #ifndef _WPS_ENGINE_INTERNALS_
#define _WPS_ENGINE_INTERNALS_ #define _WPS_ENGINE_INTERNALS_
#include "tag_table.h"
#include "skin_parser.h"
#ifndef __PCTOOL__
#include "core_alloc.h"
#endif
/* Timeout unit expressed in HZ. In WPS, all timeouts are given in seconds /* Timeout unit expressed in HZ. In WPS, all timeouts are given in seconds
(possibly with a decimal fraction) but stored as integer values. (possibly with a decimal fraction) but stored as integer values.
@ -33,52 +38,48 @@
#define TIMEOUT_UNIT (HZ/10) /* I.e. 0.1 sec */ #define TIMEOUT_UNIT (HZ/10) /* I.e. 0.1 sec */
#define DEFAULT_SUBLINE_TIME_MULTIPLIER 20 /* In TIMEOUT_UNIT's */ #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 */ /* TODO: sort this mess out */
#include "screen_access.h" #include "screen_access.h"
#include "statusbar.h" #include "statusbar.h"
#include "metadata.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 #define TOKEN_VALUE_ONLY 0x0DEADC0D
#ifdef HAVE_ALBUMART
/* albumart definitions */
#define WPS_ALBUMART_NONE 0 /* WPS does not contain AA tag */
#define WPS_ALBUMART_CHECK 1 /* WPS contains AA conditional tag */
#define WPS_ALBUMART_LOAD 2 /* WPS contains AA tag */
#define WPS_ALBUMART_ALIGN_RIGHT 1 /* x align: right */
#define WPS_ALBUMART_ALIGN_CENTER 2 /* x/y align: center */
#define WPS_ALBUMART_ALIGN_LEFT 4 /* x align: left */
#define WPS_ALBUMART_ALIGN_TOP 1 /* y align: top */
#define WPS_ALBUMART_ALIGN_BOTTOM 4 /* y align: bottom */
#endif /* HAVE_ALBUMART */
/* wps_data*/ /* wps_data*/
struct wps_token {
union {
char c;
unsigned short i;
long l;
OFFSETTYPE(void*) data;
} value;
enum skin_token_type type; /* enough to store the token type */
/* Whether the tag (e.g. track name or the album) refers the
current or the next song (false=current, true=next) */
bool next;
};
char* get_dir(char* buf, int buf_size, const char* path, int level);
struct skin_token_list {
OFFSETTYPE(struct wps_token *) token;
OFFSETTYPE(struct skin_token_list *) next;
};
#ifdef HAVE_LCD_BITMAP #ifdef HAVE_LCD_BITMAP
struct gui_img { 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 x; /* x-pos */
short int y; /* y-pos */ short int y; /* y-pos */
short int num_subimages; /* number of sub-images */ short int num_subimages; /* number of sub-images */
short int subimage_height; /* height of each sub-image */ short int subimage_height; /* height of each sub-image */
struct bitmap bm; struct bitmap bm;
int buflib_handle; int buflib_handle;
const char *label; OFFSETTYPE(char*) label;
bool loaded; /* load state */ bool loaded; /* load state */
bool always_display; /* not using the preload/display mechanism */ bool always_display; /* not using the preload/display mechanism */
int display; int display;
@ -86,15 +87,15 @@ struct gui_img {
}; };
struct image_display { struct image_display {
const char *label; OFFSETTYPE(char*) label;
int subimage; 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 */ int offset; /* offset into the bitmap strip to start */
}; };
struct progressbar { struct progressbar {
enum skin_token_type type; enum skin_token_type type;
struct viewport *vp; OFFSETTYPE(struct viewport *) vp;
/* regular pb */ /* regular pb */
short x; short x;
/* >=0: explicitly set in the tag -> y-coord within the viewport /* >=0: explicitly set in the tag -> y-coord within the viewport
@ -105,14 +106,14 @@ struct progressbar {
short height; short height;
bool follow_lang_direction; bool follow_lang_direction;
struct gui_img *image; OFFSETTYPE(struct gui_img *) image;
bool invert_fill_direction; bool invert_fill_direction;
bool nofill; bool nofill;
bool nobar; bool nobar;
struct gui_img *slider; OFFSETTYPE(struct gui_img *) slider;
bool horizontal; bool horizontal;
struct gui_img *backdrop; OFFSETTYPE(struct gui_img *) backdrop;
}; };
#endif #endif
@ -125,35 +126,11 @@ struct align_pos {
}; };
#ifdef HAVE_LCD_BITMAP #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_TOKENS 1150
#define WPS_MAX_STRINGS 128
#define STRING_BUFFER_SIZE 1024
#define WPS_MAX_COND_LEVEL 10
#else #else
#define WPS_MAX_VIEWPORTS 2
#define WPS_MAX_LINES 2
#define WPS_MAX_SUBLINES 12
#define WPS_MAX_TOKENS 64 #define WPS_MAX_TOKENS 64
#define WPS_MAX_STRINGS 32
#define STRING_BUFFER_SIZE 64
#define WPS_MAX_COND_LEVEL 5
#endif #endif
#define SUBLINE_RESET -1
enum wps_parse_error { enum wps_parse_error {
PARSE_OK, PARSE_OK,
PARSE_FAIL_UNCLOSED_COND, PARSE_FAIL_UNCLOSED_COND,
@ -176,12 +153,17 @@ struct gradient_config {
#define VP_DRAW_WASHIDDEN 0x4 #define VP_DRAW_WASHIDDEN 0x4
/* these are never drawn, nor cleared, i.e. just ignored */ /* these are never drawn, nor cleared, i.e. just ignored */
#define VP_NEVER_VISIBLE 0x8 #define VP_NEVER_VISIBLE 0x8
#define VP_DEFAULT_LABEL "|" #ifndef __PCTOOL__
#define VP_DEFAULT_LABEL -200
#else
#define VP_DEFAULT_LABEL NULL
#endif
#define VP_DEFAULT_LABEL_STRING "|"
struct skin_viewport { struct skin_viewport {
struct viewport vp; /* The LCD viewport struct */ struct viewport vp; /* The LCD viewport struct */
char hidden_flags; char hidden_flags;
bool is_infovp; bool is_infovp;
char* label; OFFSETTYPE(char*) label;
int parsed_fontid; int parsed_fontid;
#if LCD_DEPTH > 1 #if LCD_DEPTH > 1
unsigned start_fgcolour; unsigned start_fgcolour;
@ -192,14 +174,14 @@ struct skin_viewport {
#endif #endif
}; };
struct viewport_colour { struct viewport_colour {
struct viewport *vp; OFFSETTYPE(struct viewport *) vp;
unsigned colour; unsigned colour;
}; };
#ifdef HAVE_TOUCHSCREEN #ifdef HAVE_TOUCHSCREEN
struct touchregion { struct touchregion {
char* label; /* label to identify this region */ OFFSETTYPE(char*) label; /* label to identify this region */
struct skin_viewport* wvp;/* The viewport this region is in */ OFFSETTYPE(struct skin_viewport*) wvp;/* The viewport this region is in */
short int x; /* x-pos */ short int x; /* x-pos */
short int y; /* y-pos */ short int y; /* y-pos */
short int width; /* width */ short int width; /* width */
@ -219,7 +201,7 @@ struct touchregion {
const struct settings_list *setting; /* setting being controlled */ const struct settings_list *setting; /* setting being controlled */
union { /* Value to set the setting to for ACTION_SETTING_SET */ union { /* Value to set the setting to for ACTION_SETTING_SET */
int number; int number;
char* text; OFFSETTYPE(char*) text;
} value; } value;
} setting_data; } setting_data;
int value; int value;
@ -230,20 +212,32 @@ struct touchregion {
struct touchregion_lastpress { struct touchregion_lastpress {
struct touchregion *region; OFFSETTYPE(struct touchregion *) region;
long timeout; long timeout;
}; };
#endif #endif
struct playlistviewer { struct playlistviewer {
struct viewport *vp; OFFSETTYPE(struct viewport *) vp;
bool show_icons; bool show_icons;
int start_offset; int start_offset;
struct skin_element *line; OFFSETTYPE(struct skin_element *) line;
}; };
#ifdef HAVE_ALBUMART #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 { struct skin_albumart {
/* Album art support */ /* Album art support */
int x; int x;
@ -255,7 +249,7 @@ struct skin_albumart {
unsigned char yalign; /* WPS_ALBUMART_ALIGN_TOP, _CENTER, _BOTTOM */ unsigned char yalign; /* WPS_ALBUMART_ALIGN_TOP, _CENTER, _BOTTOM */
unsigned char state; /* WPS_ALBUMART_NONE, _CHECK, _LOAD */ unsigned char state; /* WPS_ALBUMART_NONE, _CHECK, _LOAD */
struct viewport *vp; OFFSETTYPE(struct viewport *) vp;
int draw_handle; int draw_handle;
}; };
#endif #endif
@ -272,11 +266,11 @@ struct line_alternator {
struct conditional { struct conditional {
int last_value; int last_value;
struct wps_token *token; OFFSETTYPE(struct wps_token *) token;
}; };
struct logical_if { struct logical_if {
struct wps_token *token; OFFSETTYPE(struct wps_token *) token;
enum { enum {
IF_EQUALS, /* == */ IF_EQUALS, /* == */
IF_NOTEQUALS, /* != */ IF_NOTEQUALS, /* != */
@ -292,7 +286,7 @@ struct logical_if {
struct substring { struct substring {
int start; int start;
int length; int length;
struct wps_token *token; OFFSETTYPE(struct wps_token *) token;
}; };
struct listitem { struct listitem {
@ -302,16 +296,16 @@ struct listitem {
#ifdef HAVE_SKIN_VARIABLES #ifdef HAVE_SKIN_VARIABLES
struct skin_var { struct skin_var {
const char *label; OFFSETTYPE(const char *) label;
int value; int value;
long last_changed; long last_changed;
}; };
struct skin_var_lastchange { struct skin_var_lastchange {
struct skin_var *var; OFFSETTYPE(struct skin_var *) var;
long timeout; long timeout;
}; };
struct skin_var_changer { struct skin_var_changer {
struct skin_var *var; OFFSETTYPE(struct skin_var *) var;
int newval; int newval;
bool direct; /* true to make val=newval, false for val += newval */ bool direct; /* true to make val=newval, false for val += newval */
int max; int max;
@ -323,30 +317,29 @@ struct skin_var_changer {
viewable content of a wps */ viewable content of a wps */
struct wps_data struct wps_data
{ {
struct skin_element *tree; int buflib_handle;
OFFSETTYPE(struct skin_element *) tree;
#ifdef HAVE_LCD_BITMAP #ifdef HAVE_LCD_BITMAP
struct skin_token_list *images; OFFSETTYPE(struct skin_token_list *) images;
int *font_ids; OFFSETTYPE(int *) font_ids;
int font_count; int font_count;
#endif #endif
#if LCD_DEPTH > 1 || defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1 #if LCD_DEPTH > 1 || defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1
struct { int backdrop_id;
char *backdrop;
int backdrop_id;
};
#endif #endif
#ifdef HAVE_TOUCHSCREEN #ifdef HAVE_TOUCHSCREEN
struct skin_token_list *touchregions; OFFSETTYPE(struct skin_token_list *) touchregions;
bool touchscreen_locked; bool touchscreen_locked;
#endif #endif
#ifdef HAVE_ALBUMART #ifdef HAVE_ALBUMART
struct skin_albumart *albumart; OFFSETTYPE(struct skin_albumart *) albumart;
int playback_aa_slot; int playback_aa_slot;
#endif #endif
#ifdef HAVE_SKIN_VARIABLES #ifdef HAVE_SKIN_VARIABLES
struct skin_token_list *skinvars; OFFSETTYPE(struct skin_token_list *) skinvars;
#endif #endif
#ifdef HAVE_LCD_BITMAP #ifdef HAVE_LCD_BITMAP
@ -360,6 +353,17 @@ struct wps_data
bool wps_loaded; bool wps_loaded;
}; };
#ifndef __PCTOOL__
static inline char* get_skin_buffer(struct wps_data* data)
{
if (data->buflib_handle >= 0)
return core_get_data(data->buflib_handle);
return NULL;
}
#else
#define get_skin_buffer(d) skin_buffer
#endif
/* wps_data end */ /* wps_data end */
/* wps_state /* wps_state

View file

@ -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 /* hide the sb's default viewport because it has nasty effect with stuff
* not part of the statusbar, * not part of the statusbar,
* hence .sbs's without any other vps are unsupported*/ * 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_viewport *vp = skin_find_item(VP_DEFAULT_LABEL_STRING, SKIN_FIND_VP, data);
struct skin_element *next_vp = data->tree->next; struct skin_element *tree = SKINOFFSETTOPTR(get_skin_buffer(data), data->tree);
struct skin_element *next_vp = SKINOFFSETTOPTR(get_skin_buffer(data), tree->next);
if (vp) if (vp)
{ {
@ -105,9 +106,9 @@ int sb_postproccess(enum screen_type screen, struct wps_data *data)
return 1; return 1;
} }
static char *infovp_label[NB_SCREENS]; static OFFSETTYPE(char*) infovp_label[NB_SCREENS];
static char *oldinfovp_label[NB_SCREENS]; static OFFSETTYPE(char*) oldinfovp_label[NB_SCREENS];
void sb_set_info_vp(enum screen_type screen, char *label) void sb_set_info_vp(enum screen_type screen, OFFSETTYPE(char*) label)
{ {
infovp_label[screen] = label; infovp_label[screen] = label;
} }
@ -116,15 +117,19 @@ struct viewport *sb_skin_get_info_vp(enum screen_type screen)
{ {
struct wps_data *data = skin_get_gwps(CUSTOM_STATUSBAR, screen)->data; struct wps_data *data = skin_get_gwps(CUSTOM_STATUSBAR, screen)->data;
struct skin_viewport *vp = NULL; struct skin_viewport *vp = NULL;
char *label;
if (oldinfovp_label[screen] && if (oldinfovp_label[screen] &&
strcmp(oldinfovp_label[screen], infovp_label[screen])) (oldinfovp_label[screen] != infovp_label[screen]))
{ {
/* UI viewport changed, so force a redraw */ /* UI viewport changed, so force a redraw */
oldinfovp_label[screen] = infovp_label[screen]; oldinfovp_label[screen] = infovp_label[screen];
viewportmanager_theme_enable(screen, false, NULL); viewportmanager_theme_enable(screen, false, NULL);
viewportmanager_theme_undo(screen, true); viewportmanager_theme_undo(screen, true);
} }
vp = skin_find_item(infovp_label[screen], SKIN_FIND_UIVP, data); label = SKINOFFSETTOPTR(get_skin_buffer(data), infovp_label[screen]);
if (infovp_label[screen] == VP_DEFAULT_LABEL)
label = VP_DEFAULT_LABEL_STRING;
vp = skin_find_item(label, SKIN_FIND_UIVP, data);
if (!vp) if (!vp)
return NULL; return NULL;
if (vp->parsed_fontid == 1) if (vp->parsed_fontid == 1)
@ -270,7 +275,7 @@ void sb_skin_init(void)
{ {
FOR_NB_SCREENS(i) FOR_NB_SCREENS(i)
{ {
oldinfovp_label[i] = NULL; oldinfovp_label[i] = VP_DEFAULT_LABEL;
} }
} }

View file

@ -36,7 +36,7 @@ void sb_skin_data_load(enum screen_type screen, const char *buf, bool isfile);
char* sb_create_from_settings(enum screen_type screen); char* sb_create_from_settings(enum screen_type screen);
void sb_skin_init(void) INIT_ATTR; void sb_skin_init(void) INIT_ATTR;
void sb_set_info_vp(enum screen_type screen, char *label); void sb_set_info_vp(enum screen_type screen, OFFSETTYPE(char*) label);
struct viewport *sb_skin_get_info_vp(enum screen_type screen); struct viewport *sb_skin_get_info_vp(enum screen_type screen);
void sb_skin_update(enum screen_type screen, bool force); void sb_skin_update(enum screen_type screen, bool force);

View file

@ -667,7 +667,7 @@ static void gwps_enter_wps(void)
#if LCD_DEPTH > 1 #if LCD_DEPTH > 1
if (display->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); SKIN_FIND_VP, gwps->data);
if (svp) if (svp)
{ {

View file

@ -11502,16 +11502,16 @@
</phrase> </phrase>
<phrase> <phrase>
id: LANG_SKIN_RAM_USAGE id: LANG_SKIN_RAM_USAGE
desc: how much RAM the skins are using desc: deprecated
user: core user: core
<source> <source>
*: "Skin RAM usage:" *: ""
</source> </source>
<dest> <dest>
*: "Azalaren RAM erabilera:" *: ""
</dest> </dest>
<voice> <voice>
*: "Azalaren RAM erabilera:" *: ""
</voice> </voice>
</phrase> </phrase>
<phrase> <phrase>

View file

@ -12255,16 +12255,16 @@
</phrase> </phrase>
<phrase> <phrase>
id: LANG_SKIN_RAM_USAGE id: LANG_SKIN_RAM_USAGE
desc: how much RAM the skins are using desc: deprecated
user: core user: core
<source> <source>
*: "Skin RAM usage:" *: ""
</source> </source>
<dest> <dest>
*: "Използвана RAM от скина:" *: ""
</dest> </dest>
<voice> <voice>
*: "Използвана RAM от скина" *: ""
</voice> </voice>
</phrase> </phrase>
<phrase> <phrase>

View file

@ -11494,16 +11494,16 @@
</phrase> </phrase>
<phrase> <phrase>
id: LANG_SKIN_RAM_USAGE id: LANG_SKIN_RAM_USAGE
desc: how much RAM the skins are using desc: deprecated
user: core user: core
<source> <source>
*: "Skin RAM usage:" *: ""
</source> </source>
<dest> <dest>
*: "Ús de RAM per part del tema:" *: ""
</dest> </dest>
<voice> <voice>
*: "Ús de RAM per part del tema" *: ""
</voice> </voice>
</phrase> </phrase>
<phrase> <phrase>

View file

@ -11821,16 +11821,16 @@
</phrase> </phrase>
<phrase> <phrase>
id: LANG_SKIN_RAM_USAGE id: LANG_SKIN_RAM_USAGE
desc: how much RAM the skins are using desc: deprecated
user: core user: core
<source> <source>
*: "Skin RAM usage:" *: ""
</source> </source>
<dest> <dest>
*: "Skin RAM usage:" *: ""
</dest> </dest>
<voice> <voice>
*: "Skin RAM usage" *: ""
</voice> </voice>
</phrase> </phrase>
<phrase> <phrase>

View file

@ -11504,16 +11504,16 @@
</phrase> </phrase>
<phrase> <phrase>
id: LANG_SKIN_RAM_USAGE id: LANG_SKIN_RAM_USAGE
desc: how much RAM the skins are using desc: deprecated
user: core user: core
<source> <source>
*: "Skin RAM usage:" *: ""
</source> </source>
<dest> <dest>
*: "Využití RAM pro skiny:" *: ""
</dest> </dest>
<voice> <voice>
*: "Využití RAM pro skiny" *: ""
</voice> </voice>
</phrase> </phrase>
<phrase> <phrase>

View file

@ -11446,16 +11446,16 @@
</phrase> </phrase>
<phrase> <phrase>
id: LANG_SKIN_RAM_USAGE id: LANG_SKIN_RAM_USAGE
desc: how much RAM the skins are using desc: deprecated
user: core user: core
<source> <source>
*: "Skin RAM usage:" *: ""
</source> </source>
<dest> <dest>
*: "Temas RAM-forbrug:" *: ""
</dest> </dest>
<voice> <voice>
*: "Temas RAM-forbrug" *: ""
</voice> </voice>
</phrase> </phrase>
<phrase> <phrase>

View file

@ -11445,16 +11445,16 @@
</phrase> </phrase>
<phrase> <phrase>
id: LANG_SKIN_RAM_USAGE id: LANG_SKIN_RAM_USAGE
desc: how much RAM the skins are using desc: deprecated
user: core user: core
<source> <source>
*: "Skin RAM usage:" *: ""
</source> </source>
<dest> <dest>
*: "Themen-Speicher:" *: ""
</dest> </dest>
<voice> <voice>
*: "Themen-Speicher" *: ""
</voice> </voice>
</phrase> </phrase>
<phrase> <phrase>

View file

@ -11500,16 +11500,16 @@
</phrase> </phrase>
<phrase> <phrase>
id: LANG_SKIN_RAM_USAGE id: LANG_SKIN_RAM_USAGE
desc: how much RAM the skins are using desc: deprecated
user: core user: core
<source> <source>
*: "Skin RAM usage:" *: ""
</source> </source>
<dest> <dest>
*: "Skin RAM usage:" *: ""
</dest> </dest>
<voice> <voice>
*: "Skin RAM usage" *: ""
</voice> </voice>
</phrase> </phrase>
<phrase> <phrase>

View file

@ -11587,16 +11587,16 @@
</phrase> </phrase>
<phrase> <phrase>
id: LANG_SKIN_RAM_USAGE id: LANG_SKIN_RAM_USAGE
desc: how much RAM the skins are using desc: deprecated
user: core user: core
<source> <source>
*: "Skin RAM usage:" *: ""
</source> </source>
<dest> <dest>
*: "Skin RAM usage:" *: ""
</dest> </dest>
<voice> <voice>
*: "Skin RAM usage" *: ""
</voice> </voice>
</phrase> </phrase>
<phrase> <phrase>

View file

@ -11816,16 +11816,16 @@
</phrase> </phrase>
<phrase> <phrase>
id: LANG_SKIN_RAM_USAGE id: LANG_SKIN_RAM_USAGE
desc: how much RAM the skins are using desc: deprecated
user: core user: core
<source> <source>
*: "Skin RAM usage:" *: ""
</source> </source>
<dest> <dest>
*: "Uso de RAM de la piel:" *: ""
</dest> </dest>
<voice> <voice>
*: "Uso de RAM de la piel" *: ""
</voice> </voice>
</phrase> </phrase>
<phrase> <phrase>

View file

@ -11383,16 +11383,16 @@
</phrase> </phrase>
<phrase> <phrase>
id: LANG_SKIN_RAM_USAGE id: LANG_SKIN_RAM_USAGE
desc: how much RAM the skins are using desc: deprecated
user: core user: core
<source> <source>
*: "Skin RAM usage:" *: ""
</source> </source>
<dest> <dest>
*: "Nahan käyttämä RAM-muisti:" *: ""
</dest> </dest>
<voice> <voice>
*: "Nahan käyttämä RAM-muisti" *: ""
</voice> </voice>
</phrase> </phrase>
<phrase> <phrase>

View file

@ -11528,16 +11528,16 @@
</phrase> </phrase>
<phrase> <phrase>
id: LANG_SKIN_RAM_USAGE id: LANG_SKIN_RAM_USAGE
desc: how much RAM the skins are using desc: deprecated
user: core user: core
<source> <source>
*: "Skin RAM usage:" *: ""
</source> </source>
<dest> <dest>
*: "Tampon du thème:" *: ""
</dest> </dest>
<voice> <voice>
*: "Tampon du thème utilisé" *: ""
</voice> </voice>
</phrase> </phrase>
<phrase> <phrase>

View file

@ -10883,16 +10883,16 @@ ipod*,iaudiox5,iaudiom5,iriverh10,iriverh10_5gb,sansae200*,sansac200*,gigabeat*,
</phrase> </phrase>
<phrase> <phrase>
id: LANG_SKIN_RAM_USAGE id: LANG_SKIN_RAM_USAGE
desc: how much RAM the skins are using desc: deprecated
user: core user: core
<source> <source>
*: "Skin RAM usage:" *: ""
</source> </source>
<dest> <dest>
*: "Uso de RAM pola skin:" *: ""
</dest> </dest>
<voice> <voice>
*: "Uso de RAM pola skin" *: ""
</voice> </voice>
</phrase> </phrase>
<phrase> <phrase>

View file

@ -11509,16 +11509,16 @@
</phrase> </phrase>
<phrase> <phrase>
id: LANG_SKIN_RAM_USAGE id: LANG_SKIN_RAM_USAGE
desc: how much RAM the skins are using desc: deprecated
user: core user: core
<source> <source>
*: "Skin RAM usage:" *: ""
</source> </source>
<dest> <dest>
*: "Skin RAM usage:" *: ""
</dest> </dest>
<voice> <voice>
*: "Skin RAM usage" *: ""
</voice> </voice>
</phrase> </phrase>
<phrase> <phrase>

View file

@ -11503,16 +11503,16 @@
</phrase> </phrase>
<phrase> <phrase>
id: LANG_SKIN_RAM_USAGE id: LANG_SKIN_RAM_USAGE
desc: how much RAM the skins are using desc: deprecated
user: core user: core
<source> <source>
*: "Skin RAM usage:" *: ""
</source> </source>
<dest> <dest>
*: "Korištenje RAM-a presvlake:" *: ""
</dest> </dest>
<voice> <voice>
*: "Korištenje RAM-a presvlake" *: ""
</voice> </voice>
</phrase> </phrase>
<phrase> <phrase>

View file

@ -11504,16 +11504,16 @@ desc: deprecated
</phrase> </phrase>
<phrase> <phrase>
id: LANG_SKIN_RAM_USAGE id: LANG_SKIN_RAM_USAGE
desc: how much RAM the skins are using desc: deprecated
user: core user: core
<source> <source>
*: "Skin RAM usage:" *: ""
</source> </source>
<dest> <dest>
*: "RAM usata per Skin:" *: ""
</dest> </dest>
<voice> <voice>
*: "RAM usata per Skin" *: ""
</voice> </voice>
</phrase> </phrase>
<phrase> <phrase>

View file

@ -11509,16 +11509,16 @@
</phrase> </phrase>
<phrase> <phrase>
id: LANG_SKIN_RAM_USAGE id: LANG_SKIN_RAM_USAGE
desc: how much RAM the skins are using desc: deprecated
user: core user: core
<source> <source>
*: "Skin RAM usage:" *: ""
</source> </source>
<dest> <dest>
*: "スキンのRAM使用量:" *: ""
</dest> </dest>
<voice> <voice>
*: "スキンのRAM使用量" *: ""
</voice> </voice>
</phrase> </phrase>
<phrase> <phrase>

View file

@ -11505,16 +11505,16 @@
</phrase> </phrase>
<phrase> <phrase>
id: LANG_SKIN_RAM_USAGE id: LANG_SKIN_RAM_USAGE
desc: how much RAM the skins are using desc: deprecated
user: core user: core
<source> <source>
*: "Skin RAM usage:" *: ""
</source> </source>
<dest> <dest>
*: "Ādas RAM izl.:" *: ""
</dest> </dest>
<voice> <voice>
*: "aadas ram izlietojums" *: ""
</voice> </voice>
</phrase> </phrase>
<phrase> <phrase>

View file

@ -11366,16 +11366,16 @@
</phrase> </phrase>
<phrase> <phrase>
id: LANG_SKIN_RAM_USAGE id: LANG_SKIN_RAM_USAGE
desc: how much RAM the skins are using desc: deprecated
user: core user: core
<source> <source>
*: "Skin RAM usage:" *: ""
</source> </source>
<dest> <dest>
*: "Téma RAM használat:" *: ""
</dest> </dest>
<voice> <voice>
*: "Téma RAM használat" *: ""
</voice> </voice>
</phrase> </phrase>
<phrase> <phrase>

View file

@ -11852,16 +11852,16 @@
</phrase> </phrase>
<phrase> <phrase>
id: LANG_SKIN_RAM_USAGE id: LANG_SKIN_RAM_USAGE
desc: how much RAM the skins are using desc: deprecated
user: core user: core
<source> <source>
*: "Skin RAM usage:" *: ""
</source> </source>
<dest> <dest>
*: "Uitzicht RAM gebruik:" *: ""
</dest> </dest>
<voice> <voice>
*: "Uitzicht RAM gebruik" *: ""
</voice> </voice>
</phrase> </phrase>
<phrase> <phrase>

View file

@ -11426,16 +11426,16 @@
</phrase> </phrase>
<phrase> <phrase>
id: LANG_SKIN_RAM_USAGE id: LANG_SKIN_RAM_USAGE
desc: how much RAM the skins are using desc: deprecated
user: core user: core
<source> <source>
*: "Skin RAM usage:" *: ""
</source> </source>
<dest> <dest>
*: "Pamięć zajmowana przez styl:" *: ""
</dest> </dest>
<voice> <voice>
*: "Pamięć zajmowana przez styl" *: ""
</voice> </voice>
</phrase> </phrase>
<phrase> <phrase>

View file

@ -11501,16 +11501,16 @@
</phrase> </phrase>
<phrase> <phrase>
id: LANG_SKIN_RAM_USAGE id: LANG_SKIN_RAM_USAGE
desc: how much RAM the skins are using desc: deprecated
user: core user: core
<source> <source>
*: "Skin RAM usage:" *: ""
</source> </source>
<dest> <dest>
*: "Uso de RAM do Skin:" *: ""
</dest> </dest>
<voice> <voice>
*: "Uso de RAM do Skin" *: ""
</voice> </voice>
</phrase> </phrase>
<phrase> <phrase>

View file

@ -11679,16 +11679,16 @@
</phrase> </phrase>
<phrase> <phrase>
id: LANG_SKIN_RAM_USAGE id: LANG_SKIN_RAM_USAGE
desc: how much RAM the skins are using desc: deprecated
user: core user: core
<source> <source>
*: "Skin RAM usage:" *: ""
</source> </source>
<dest> <dest>
*: "Uso de RAM do Visual:" *: ""
</dest> </dest>
<voice> <voice>
*: "Uso de RAM do Visual" *: ""
</voice> </voice>
</phrase> </phrase>
<phrase> <phrase>

View file

@ -12501,16 +12501,16 @@
<phrase> <phrase>
id: LANG_SKIN_RAM_USAGE id: LANG_SKIN_RAM_USAGE
desc: how much RAM the skins are using desc: deprecated
user: core user: core
<source> <source>
*: "Skin RAM usage:" *: ""
</source> </source>
<dest> <dest>
*: "Utilizare RAM de către skin:" *: ""
</dest> </dest>
<voice> <voice>
*: "Utilizare RAM de către skin:" *: ""
</voice> </voice>
</phrase> </phrase>

View file

@ -12219,16 +12219,16 @@
</phrase> </phrase>
<phrase> <phrase>
id: LANG_SKIN_RAM_USAGE id: LANG_SKIN_RAM_USAGE
desc: how much RAM the skins are using desc: deprecated
user: core user: core
<source> <source>
*: "Skin RAM usage:" *: ""
</source> </source>
<dest> <dest>
*: "RAM для темы:" *: ""
</dest> </dest>
<voice> <voice>
*: "RAM для темы" *: ""
</voice> </voice>
</phrase> </phrase>
<phrase> <phrase>

View file

@ -11500,16 +11500,16 @@
</phrase> </phrase>
<phrase> <phrase>
id: LANG_SKIN_RAM_USAGE id: LANG_SKIN_RAM_USAGE
desc: how much RAM the skins are using desc: deprecated
user: core user: core
<source> <source>
*: "Skin RAM usage:" *: ""
</source> </source>
<dest> <dest>
*: "Pamäť Ram využitá vzhľadom" *: ""
</dest> </dest>
<voice> <voice>
*: "Pamäť RAM využitá vzhľadom" *: ""
</voice> </voice>
</phrase> </phrase>
<phrase> <phrase>

View file

@ -9764,16 +9764,16 @@
</phrase> </phrase>
<phrase> <phrase>
id: LANG_SKIN_RAM_USAGE id: LANG_SKIN_RAM_USAGE
desc: how much RAM the skins are using desc: deprecated
user: core user: core
<source> <source>
*: "Skin RAM usage:" *: ""
</source> </source>
<dest> <dest>
*: "Skin RAM usage:" *: ""
</dest> </dest>
<voice> <voice>
*: "Skin RAM usage" *: ""
</voice> </voice>
</phrase> </phrase>
<phrase> <phrase>

View file

@ -11784,16 +11784,16 @@
</phrase> </phrase>
<phrase> <phrase>
id: LANG_SKIN_RAM_USAGE id: LANG_SKIN_RAM_USAGE
desc: how much RAM the skins are using desc: deprecated
user: core user: core
<source> <source>
*: "Skin RAM usage:" *: ""
</source> </source>
<dest> <dest>
*: "Потрошња RAM за скинове:" *: ""
</dest> </dest>
<voice> <voice>
*: "Потрошња RAM за скинове" *: ""
</voice> </voice>
</phrase> </phrase>
<phrase> <phrase>

View file

@ -11506,16 +11506,16 @@
</phrase> </phrase>
<phrase> <phrase>
id: LANG_SKIN_RAM_USAGE id: LANG_SKIN_RAM_USAGE
desc: how much RAM the skins are using desc: deprecated
user: core user: core
<source> <source>
*: "Skin RAM usage:" *: ""
</source> </source>
<dest> <dest>
*: "Tema:" *: ""
</dest> </dest>
<voice> <voice>
*: "Tema" *: ""
</voice> </voice>
</phrase> </phrase>
<phrase> <phrase>

View file

@ -11394,16 +11394,16 @@
</phrase> </phrase>
<phrase> <phrase>
id: LANG_SKIN_RAM_USAGE id: LANG_SKIN_RAM_USAGE
desc: how much RAM the skins are using desc: deprecated
user: core user: core
<source> <source>
*: "Skin RAM usage:" *: ""
</source> </source>
<dest> <dest>
*: "Skin RAM usage:" *: ""
</dest> </dest>
<voice> <voice>
*: "Skin RAM usage" *: ""
</voice> </voice>
</phrase> </phrase>
<phrase> <phrase>

View file

@ -11342,16 +11342,16 @@
</phrase> </phrase>
<phrase> <phrase>
id: LANG_SKIN_RAM_USAGE id: LANG_SKIN_RAM_USAGE
desc: how much RAM the skins are using desc: deprecated
user: core user: core
<source> <source>
*: "Skin RAM usage:" *: ""
</source> </source>
<dest> <dest>
*: "หน่วยความจำหน้ากาก:" *: ""
</dest> </dest>
<voice> <voice>
*: "Skin RAM usage" *: ""
</voice> </voice>
</phrase> </phrase>
<phrase> <phrase>

View file

@ -11505,16 +11505,16 @@
</phrase> </phrase>
<phrase> <phrase>
id: LANG_SKIN_RAM_USAGE id: LANG_SKIN_RAM_USAGE
desc: how much RAM the skins are using desc: deprecated
user: core user: core
<source> <source>
*: "Skin RAM usage:" *: ""
</source> </source>
<dest> <dest>
*: "Memwere eployeye pol pea:" *: ""
</dest> </dest>
<voice> <voice>
*: "Memwere eployeye pol pea" *: ""
</voice> </voice>
</phrase> </phrase>
<phrase> <phrase>

View file

@ -147,9 +147,6 @@ enum infoscreenorder
INFO_DISK1, /* capacity or internal capacity/free on hotswap */ INFO_DISK1, /* capacity or internal capacity/free on hotswap */
INFO_DISK2, /* free space or external capacity/free on hotswap */ INFO_DISK2, /* free space or external capacity/free on hotswap */
INFO_BUFFER, INFO_BUFFER,
#ifndef APPLICATION
INFO_SKIN_USAGE, /* ram usage of the skins */
#endif
INFO_VERSION, INFO_VERSION,
INFO_COUNT INFO_COUNT
}; };
@ -159,7 +156,7 @@ static const char* info_getname(int selected_item, void *data,
{ {
struct info_data *info = (struct info_data*)data; struct info_data *info = (struct info_data*)data;
char s1[32]; char s1[32];
#if defined(HAVE_MULTIVOLUME) || !defined(APPLICATION) #if defined(HAVE_MULTIVOLUME)
char s2[32]; char s2[32];
#endif #endif
if (info->new_data) if (info->new_data)
@ -246,14 +243,6 @@ static const char* info_getname(int selected_item, void *data,
snprintf(buffer, buffer_len, SIZE_FMT, str(LANG_DISK_SIZE_INFO), s1); snprintf(buffer, buffer_len, SIZE_FMT, str(LANG_DISK_SIZE_INFO), s1);
#endif #endif
break; break;
#ifndef APPLICATION
case INFO_SKIN_USAGE:
output_dyn_value(s1, sizeof s1, skin_buffer_usage(), byte_units, true);
output_dyn_value(s2, sizeof s2, skin_buffer_usage()
+skin_buffer_freespace(), byte_units, true);
snprintf(buffer, buffer_len, "%s %s / %s", str(LANG_SKIN_RAM_USAGE), s1, s2);
break;
#endif
} }
return buffer; return buffer;
} }
@ -334,12 +323,6 @@ static int info_speak_item(int selected_item, void * data)
output_dyn_value(NULL, 0, info->size, kbyte_units, true); output_dyn_value(NULL, 0, info->size, kbyte_units, true);
#endif #endif
break; break;
#ifndef APPLICATION
case INFO_SKIN_USAGE:
talk_id(LANG_SKIN_RAM_USAGE, false);
output_dyn_value(NULL, 0, skin_buffer_usage(), byte_units, true);
break;
#endif
} }
return 0; return 0;

View file

@ -305,7 +305,7 @@ void draw_album_art(struct gui_wps *gwps, int handle_id, bool clear)
return; return;
struct wps_data *data = gwps->data; struct wps_data *data = gwps->data;
struct skin_albumart *aa = data->albumart; struct skin_albumart *aa = SKINOFFSETTOPTR(get_skin_buffer(data), data->albumart);
if (!aa) if (!aa)
return; return;

View file

@ -47,54 +47,26 @@
#ifdef ROCKBOX #ifdef ROCKBOX
#include "config.h" #include "config.h"
#include "skin_debug.h" #include "skin_debug.h"
#ifdef APPLICATION
# define USE_HOST_MALLOC
#else
# define USE_ROCKBOX_ALLOC
#endif
#endif
#ifdef USE_ROCKBOX_ALLOC
static size_t buf_size; static size_t buf_size;
static unsigned char *buffer_start = NULL; static unsigned char *buffer_start = NULL;
static unsigned char *buffer_front = NULL; static unsigned char *buffer_front = NULL;
#endif
#ifdef USE_HOST_MALLOC #ifndef __PCTOOL__
long skin_buffer_to_offset(void *pointer)
struct malloc_object {
struct malloc_object *next;
char buf[0];
};
static struct malloc_object *malloced_head = NULL, *malloced_tail = NULL;
static void skin_free_malloced(void)
{ {
struct malloc_object *obj = malloced_head; return pointer == NULL ? -1 : (void*)pointer - (void*)buffer_start;
struct malloc_object *this;
while (obj)
{
this = obj;
obj = this->next;
free(this);
}
malloced_head = NULL;
malloced_tail = NULL;
} }
void* skin_buffer_from_offset(long offset)
{
return offset < 0 ? NULL : buffer_start + offset;
}
#endif #endif
void skin_buffer_init(char* buffer, size_t size) void skin_buffer_init(char* buffer, size_t size)
{ {
#ifdef USE_ROCKBOX_ALLOC
buffer_start = buffer_front = buffer; buffer_start = buffer_front = buffer;
buf_size = size; buf_size = size;
#elif defined(USE_HOST_MALLOC)
(void)buffer; (void)size;
skin_free_malloced();
#endif
} }
/* Allocate size bytes from the buffer */ /* Allocate size bytes from the buffer */
@ -108,8 +80,6 @@ void* skin_buffer_alloc(size_t size)
{ {
void *retval = NULL; void *retval = NULL;
#endif #endif
#ifdef USE_ROCKBOX_ALLOC
/* 32-bit aligned */ /* 32-bit aligned */
size = (size + 3) & ~3; size = (size + 3) & ~3;
if (size > skin_buffer_freespace()) if (size > skin_buffer_freespace())
@ -119,25 +89,9 @@ void* skin_buffer_alloc(size_t size)
} }
retval = buffer_front; retval = buffer_front;
buffer_front += size; buffer_front += size;
#elif defined(USE_HOST_MALLOC)
size_t malloc_size = sizeof(struct malloc_object) + size;
struct malloc_object *obj = malloc(malloc_size);
retval = &obj->buf;
obj->next = NULL;
if (malloced_tail == NULL)
malloced_head = malloced_tail = obj;
else
malloced_tail->next = obj;
malloced_tail = obj;
#else
retval = malloc(size);
#endif
return retval; return retval;
} }
#ifdef USE_ROCKBOX_ALLOC
/* get the number of bytes currently being used */ /* get the number of bytes currently being used */
size_t skin_buffer_usage(void) size_t skin_buffer_usage(void)
{ {
@ -147,16 +101,9 @@ size_t skin_buffer_freespace(void)
{ {
return buf_size - skin_buffer_usage(); return buf_size - skin_buffer_usage();
} }
#else
static unsigned char *saved_buffer_pos = NULL; void* skin_buffer_alloc(size_t size)
void skin_buffer_save_position(void)
{ {
saved_buffer_pos = buffer_front; return malloc(size);
}
void skin_buffer_restore_position(void)
{
if (saved_buffer_pos)
buffer_front = saved_buffer_pos;
} }
#endif #endif

View file

@ -28,6 +28,18 @@
void skin_buffer_init(char* buffer, size_t size); void skin_buffer_init(char* buffer, size_t size);
/* Allocate size bytes from the buffer */ /* Allocate size bytes from the buffer */
#ifndef __PCTOOL__
#define INVALID_OFFSET (-1)
#define IS_VALID_OFFSET(o) ((o) >= 0)
long skin_buffer_to_offset(void *pointer);
void* skin_buffer_from_offset(long offset);
#else
#define INVALID_OFFSET (NULL)
#define IS_VALID_OFFSET(o) ((o) != NULL)
#define skin_buffer_to_offset(p) p
#define skin_buffer_from_offset(o) o
#endif
/* #define DEBUG_SKIN_ALLOCATIONS */ /* #define DEBUG_SKIN_ALLOCATIONS */
#ifdef DEBUG_SKIN_ALLOCATIONS #ifdef DEBUG_SKIN_ALLOCATIONS
@ -44,7 +56,4 @@ void* skin_buffer_alloc(size_t size);
size_t skin_buffer_usage(void); size_t skin_buffer_usage(void);
size_t skin_buffer_freespace(void); size_t skin_buffer_freespace(void);
/* save and restore a buffer position incase a skin fails to load */
void skin_buffer_save_position(void);
void skin_buffer_restore_position(void);
#endif #endif

View file

@ -31,6 +31,7 @@
int debug_indent_level = 0; int debug_indent_level = 0;
extern int skin_line; extern int skin_line;
extern char* skin_start; extern char* skin_start;
extern char* skin_buffer;
/* Global error variables */ /* Global error variables */
int error_line; int error_line;
@ -38,6 +39,14 @@ int error_col;
const char *error_line_start; const char *error_line_start;
char* error_message; char* error_message;
static inline struct skin_element*
get_child(OFFSETTYPE(struct skin_element**) children, int child)
{
struct skin_element **kids = SKINOFFSETTOPTR(skin_buffer, children);
return kids[child];
}
/* Debugging functions */ /* Debugging functions */
void skin_error(enum skin_errorcode error, const char* cursor) void skin_error(enum skin_errorcode error, const char* cursor)
{ {
@ -144,14 +153,14 @@ void skin_debug_tree(struct skin_element* root)
printf("{ Viewport \n"); printf("{ Viewport \n");
debug_indent_level++; debug_indent_level++;
skin_debug_tree(current->children[0]); skin_debug_tree(get_child(current->children, 0));
debug_indent_level--; debug_indent_level--;
printf("}"); printf("}");
break; break;
case TEXT: case TEXT:
text = current->data; text = SKINOFFSETTOPTR(skin_buffer, current->data);
printf("* Plain text on line %d: \"%s\"\n", current->line, text); printf("* Plain text on line %d: \"%s\"\n", current->line, text);
break; break;
@ -166,7 +175,7 @@ void skin_debug_tree(struct skin_element* root)
current->tag->name, current->tag->name,
current->line, current->params_count); current->line, current->params_count);
debug_indent_level++; debug_indent_level++;
skin_debug_params(current->params_count, current->params); skin_debug_params(current->params_count, SKINOFFSETTOPTR(skin_buffer, current->params));
debug_indent_level--; debug_indent_level--;
skin_debug_indent(); skin_debug_indent();
printf(")\n"); printf(")\n");
@ -185,7 +194,7 @@ void skin_debug_tree(struct skin_element* root)
debug_indent_level++; debug_indent_level++;
for(i = 0; i < current->children_count; i++) for(i = 0; i < current->children_count; i++)
{ {
skin_debug_tree(current->children[i]); skin_debug_tree(get_child(current->children, i));
} }
debug_indent_level--; debug_indent_level--;
@ -203,7 +212,7 @@ void skin_debug_tree(struct skin_element* root)
skin_debug_indent(); skin_debug_indent();
printf("[ Enumeration %d\n", i); printf("[ Enumeration %d\n", i);
debug_indent_level++; debug_indent_level++;
skin_debug_tree(current->children[i]); skin_debug_tree(get_child(current->children, i));
debug_indent_level--; debug_indent_level--;
skin_debug_indent(); skin_debug_indent();
printf("]\n"); printf("]\n");
@ -221,7 +230,7 @@ void skin_debug_tree(struct skin_element* root)
debug_indent_level++; debug_indent_level++;
if (current->children) if (current->children)
skin_debug_tree(current->children[0]); skin_debug_tree(get_child(current->children, 0));
debug_indent_level--; debug_indent_level--;
skin_debug_indent(); skin_debug_indent();
@ -229,7 +238,7 @@ void skin_debug_tree(struct skin_element* root)
break; break;
} }
current = current->next; current = SKINOFFSETTOPTR(skin_buffer, current->next);
} }
} }
@ -248,7 +257,7 @@ void skin_debug_params(int count, struct skin_tag_parameter params[])
break; break;
case STRING: case STRING:
printf("string: \"%s\"", params[i].data.text); printf("string: \"%s\"", SKINOFFSETTOPTR(skin_buffer, params[i].data.text));
break; break;
case INTEGER: case INTEGER:
@ -263,7 +272,7 @@ void skin_debug_params(int count, struct skin_tag_parameter params[])
case CODE: case CODE:
printf("Skin Code: \n"); printf("Skin Code: \n");
debug_indent_level++; debug_indent_level++;
skin_debug_tree(params[i].data.code); skin_debug_tree(SKINOFFSETTOPTR(skin_buffer, params[i].data.code));
debug_indent_level--; debug_indent_level--;
skin_debug_indent(); skin_debug_indent();
break; break;

View file

@ -37,8 +37,6 @@ int skin_line = 0;
char* skin_start = 0; char* skin_start = 0;
int viewport_line = 0; int viewport_line = 0;
static int tag_recursion_level = 0;
#ifdef ROCKBOX #ifdef ROCKBOX
static skin_callback callback = NULL; static skin_callback callback = NULL;
static void* callback_data; static void* callback_data;
@ -81,8 +79,6 @@ struct skin_element* skin_parse(const char* document)
struct skin_element* root = NULL; struct skin_element* root = NULL;
struct skin_element* last = NULL; struct skin_element* last = NULL;
struct skin_element** to_write = 0;
const char* cursor = document; /*Keeps track of location in the document*/ const char* cursor = document; /*Keeps track of location in the document*/
skin_line = 1; skin_line = 1;
@ -93,14 +89,18 @@ struct skin_element* skin_parse(const char* document)
while(*cursor != '\0') while(*cursor != '\0')
{ {
struct skin_element* tree = skin_parse_viewport(&cursor);
if(!root) if(!root)
to_write = &root; {
root = tree;
last = root;
}
else 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) if(!last)
{ {
skin_free_tree(root); /* Clearing any memory already used */ 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 */ /* Making sure last is at the end */
while(last->next) while(IS_VALID_OFFSET(last->next))
last = last->next; last = skin_buffer_from_offset(last->next);
} }
return root; return root;
@ -121,8 +121,6 @@ static struct skin_element* skin_parse_viewport(const char** document)
struct skin_element* root = NULL; struct skin_element* root = NULL;
struct skin_element* last = NULL; struct skin_element* last = NULL;
struct skin_element* retval = NULL; struct skin_element* retval = NULL;
tag_recursion_level = 0;
retval = skin_alloc_element(); retval = skin_alloc_element();
if (!retval) if (!retval)
@ -132,7 +130,7 @@ static struct skin_element* skin_parse_viewport(const char** document)
retval->line = skin_line; retval->line = skin_line;
viewport_line = skin_line; viewport_line = skin_line;
struct skin_element** to_write = 0; OFFSETTYPE(struct skin_element*)* children;
const char* cursor = *document; /* Keeps track of location in the document */ const char* cursor = *document; /* Keeps track of location in the document */
const char* bookmark; /* Used when we need to look ahead */ 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; return retval;
} }
retval->children_count = 1; retval->children_count = 1;
retval->children = skin_alloc_children(1); children = skin_alloc_children(1);
if (!retval->children) if (!children)
return NULL; return NULL;
do do
{ {
@ -212,15 +210,19 @@ static struct skin_element* skin_parse_viewport(const char** document)
} }
cursor = bookmark; cursor = bookmark;
if(!root)
to_write = &root;
else
to_write = &(last->next);
if(sublines) if(sublines)
{ {
*to_write = skin_parse_sublines(&cursor); struct skin_element* out = skin_parse_sublines(&cursor);
last = *to_write; if (!root)
{
root = out;
last = root;
}
else
{
last->next = skin_buffer_to_offset(out);
last = out;
}
if(!last) if(!last)
return NULL; return NULL;
} }
@ -237,15 +239,25 @@ static struct skin_element* skin_parse_viewport(const char** document)
if (check_viewport(cursor)) if (check_viewport(cursor))
break; break;
#endif #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) if(!last)
return NULL; return NULL;
} }
/* Making sure last is at the end */ /* Making sure last is at the end */
while(last->next) while(IS_VALID_OFFSET(last->next))
last = last->next; last = skin_buffer_from_offset(last->next);
if(*cursor == '\n') if(*cursor == '\n')
{ {
@ -269,7 +281,8 @@ static struct skin_element* skin_parse_viewport(const char** document)
*document = cursor; *document = cursor;
retval->children[0] = root; children[0] = skin_buffer_to_offset(root);
retval->children = skin_buffer_to_offset(children);
return retval; 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* root = NULL;
struct skin_element* current = NULL; struct skin_element* current = NULL;
struct skin_element* retval = NULL; struct skin_element* retval = NULL;
OFFSETTYPE(struct skin_element*)* children = NULL;
/* A wrapper for the line */ /* A wrapper for the line */
retval = skin_alloc_element(); retval = skin_alloc_element();
@ -315,8 +329,8 @@ static struct skin_element* skin_parse_line_optional(const char** document,
if(retval->children_count > 0) if(retval->children_count > 0)
{ {
retval->children = skin_alloc_children(1); children = skin_alloc_children(1);
if (!retval->children) if (!children)
return NULL; return NULL;
} }
@ -344,10 +358,11 @@ static struct skin_element* skin_parse_line_optional(const char** document,
/* Allocating memory if necessary */ /* Allocating memory if necessary */
if(root) if(root)
{ {
current->next = skin_alloc_element(); struct skin_element *next = skin_alloc_element();
if (!current->next) if (!next)
return NULL; return NULL;
current = current->next; current->next = skin_buffer_to_offset(next);
current = next;
} }
else else
{ {
@ -384,7 +399,10 @@ static struct skin_element* skin_parse_line_optional(const char** document,
*document = cursor; *document = cursor;
if(root) if(root)
retval->children[0] = root; {
children[0] = skin_buffer_to_offset(root);
retval->children = skin_buffer_to_offset(children);
}
return retval; return retval;
} }
@ -397,6 +415,7 @@ static struct skin_element* skin_parse_sublines_optional(const char** document,
int conditional) int conditional)
{ {
struct skin_element* retval; struct skin_element* retval;
OFFSETTYPE(struct skin_element*)* children;
const char* cursor = *document; const char* cursor = *document;
int sublines = 1; int sublines = 1;
int i; int i;
@ -405,7 +424,7 @@ static struct skin_element* skin_parse_sublines_optional(const char** document,
if (!retval) if (!retval)
return NULL; return NULL;
retval->type = LINE_ALTERNATOR; retval->type = LINE_ALTERNATOR;
retval->next = NULL; retval->next = skin_buffer_to_offset(NULL);
retval->line = skin_line; retval->line = skin_line;
/* First we count the sublines */ /* First we count the sublines */
@ -449,14 +468,16 @@ static struct skin_element* skin_parse_sublines_optional(const char** document,
/* ...and then we parse them */ /* ...and then we parse them */
retval->children_count = sublines; retval->children_count = sublines;
retval->children = skin_alloc_children(sublines); children = skin_alloc_children(sublines);
if (!retval->children) if (!children)
return NULL; return NULL;
cursor = *document; cursor = *document;
for(i = 0; i < sublines; i++) for(i = 0; i < sublines; i++)
{ {
retval->children[i] = skin_parse_line_optional(&cursor, conditional); children[i] = skin_buffer_to_offset(skin_parse_line_optional(&cursor, conditional));
if (children[i] < 0)
return NULL;
skip_whitespace(&cursor); skip_whitespace(&cursor);
if(*cursor != MULTILINESYM && i != sublines - 1) if(*cursor != MULTILINESYM && i != sublines - 1)
@ -478,6 +499,7 @@ static struct skin_element* skin_parse_sublines_optional(const char** document,
} }
#endif #endif
*document = cursor; *document = cursor;
retval->children = skin_buffer_to_offset(children);
return retval; return retval;
} }
@ -490,13 +512,13 @@ static int skin_parse_tag(struct skin_element* element, const char** document)
char tag_name[3]; char tag_name[3];
char* tag_args; char* tag_args;
const struct tag_info *tag; const struct tag_info *tag;
struct skin_tag_parameter* params = NULL;
int num_args = 1; int num_args = 1;
int i; int i;
int star = 0; /* Flag for the all-or-none option */ int star = 0; /* Flag for the all-or-none option */
int optional = 0; int optional = 0;
tag_recursion_level++;
/* Checking the tag name */ /* Checking the tag name */
tag_name[0] = cursor[0]; tag_name[0] = cursor[0];
@ -597,8 +619,8 @@ static int skin_parse_tag(struct skin_element* element, const char** document)
cursor = bookmark; /* Restoring the cursor */ cursor = bookmark; /* Restoring the cursor */
element->params_count = num_args; element->params_count = num_args;
element->params = skin_alloc_params(num_args, tag_recursion_level<=1); params = skin_alloc_params(num_args);
if (!element->params) if (!params)
return 0; return 0;
/* Now we have to actually parse each argument */ /* Now we have to actually parse each argument */
@ -686,14 +708,14 @@ static int skin_parse_tag(struct skin_element* element, const char** document)
else else
type_code = *tag_args; type_code = *tag_args;
/* Storing the type code */ /* Storing the type code */
element->params[i].type_code = type_code; params[i].type_code = type_code;
/* Checking a nullable argument for null. */ /* Checking a nullable argument for null. */
if(*cursor == DEFAULTSYM && !isdigit(cursor[1])) if(*cursor == DEFAULTSYM && !isdigit(cursor[1]))
{ {
if(islower(type_code)) if(islower(type_code))
{ {
element->params[i].type = DEFAULT; params[i].type = DEFAULT;
cursor++; cursor++;
} }
else else
@ -711,8 +733,8 @@ static int skin_parse_tag(struct skin_element* element, const char** document)
return 0; return 0;
} }
element->params[i].type = INTEGER; params[i].type = INTEGER;
element->params[i].data.number = scan_int(&cursor); params[i].data.number = scan_int(&cursor);
} }
else if(tolower(type_code) == 'd') else if(tolower(type_code) == 'd')
{ {
@ -738,23 +760,23 @@ static int skin_parse_tag(struct skin_element* element, const char** document)
} }
if (have_tenth == false) if (have_tenth == false)
val *= 10; val *= 10;
element->params[i].type = DECIMAL; params[i].type = DECIMAL;
element->params[i].data.number = val; params[i].data.number = val;
} }
else if(tolower(type_code) == 'n' || else if(tolower(type_code) == 'n' ||
tolower(type_code) == 's' || tolower(type_code) == 'f') tolower(type_code) == 's' || tolower(type_code) == 'f')
{ {
/* Scanning a string argument */ /* Scanning a string argument */
element->params[i].type = STRING; params[i].type = STRING;
element->params[i].data.text = scan_string(&cursor); params[i].data.text = skin_buffer_to_offset(scan_string(&cursor));
} }
else if(tolower(type_code) == 'c') else if(tolower(type_code) == 'c')
{ {
/* Recursively parsing a code argument */ /* Recursively parsing a code argument */
element->params[i].type = CODE; params[i].type = CODE;
element->params[i].data.code = skin_parse_code_as_arg(&cursor); params[i].data.code = skin_buffer_to_offset(skin_parse_code_as_arg(&cursor));
if(!element->params[i].data.code) if(params[i].data.code < 0)
return 0; return 0;
} }
else if (tolower(type_code) == 't') else if (tolower(type_code) == 't')
@ -763,9 +785,9 @@ static int skin_parse_tag(struct skin_element* element, const char** document)
child->type = TAG; child->type = TAG;
if (!skin_parse_tag(child, &cursor)) if (!skin_parse_tag(child, &cursor))
return 0; return 0;
child->next = NULL; child->next = skin_buffer_to_offset(NULL);
element->params[i].type = CODE; params[i].type = CODE;
element->params[i].data.code = child; params[i].data.code = skin_buffer_to_offset(child);
} }
@ -796,6 +818,7 @@ static int skin_parse_tag(struct skin_element* element, const char** document)
tag_args++; tag_args++;
} }
} }
element->params = skin_buffer_to_offset(params);
/* Checking for a premature end */ /* Checking for a premature end */
if(*tag_args != '\0' && !optional) if(*tag_args != '\0' && !optional)
@ -811,7 +834,6 @@ static int skin_parse_tag(struct skin_element* element, const char** document)
} }
#endif #endif
*document = cursor; *document = cursor;
tag_recursion_level--;
return 1; return 1;
} }
@ -855,9 +877,10 @@ static int skin_parse_text(struct skin_element* element, const char** document,
/* Copying the text into the element struct */ /* Copying the text into the element struct */
element->type = TEXT; element->type = TEXT;
element->line = skin_line; element->line = skin_line;
element->next = NULL; element->next = skin_buffer_to_offset(NULL);
element->data = text = skin_alloc_string(length); text = skin_alloc_string(length);
if (!element->data) element->data = skin_buffer_to_offset(text);
if (element->data < 0)
return 0; return 0;
for(dest = 0; dest < length; dest++) for(dest = 0; dest < length; dest++)
@ -896,6 +919,7 @@ static int skin_parse_conditional(struct skin_element* element, const char** doc
const char *false_branch = NULL; const char *false_branch = NULL;
const char *conditional_end = NULL; const char *conditional_end = NULL;
#endif #endif
OFFSETTYPE(struct skin_element*)* children_array = NULL;
/* Some conditional tags allow for target feature checking, /* Some conditional tags allow for target feature checking,
* so to handle that call the callback as usual with type == TAG * so to handle that call the callback as usual with type == TAG
@ -994,23 +1018,23 @@ static int skin_parse_conditional(struct skin_element* element, const char** doc
{ {
const char* emptyline= ""; const char* emptyline= "";
children = 1; children = 1;
element->children = skin_alloc_children(children); children_array = skin_alloc_children(children);
if (!element->children) if (!children_array)
return 0; return 0;
element->children_count = children; element->children_count = children;
element->children[0] = skin_parse_code_as_arg(&emptyline); children_array[0] = skin_buffer_to_offset(skin_parse_code_as_arg(&emptyline));
} }
else else
{ {
element->children = skin_alloc_children(children); children_array = skin_alloc_children(children);
if (!element->children) if (!children_array)
return 0; return 0;
element->children_count = children; element->children_count = children;
for(i = 0; i < children; i++) for(i = 0; i < children; i++)
{ {
element->children[i] = skin_parse_code_as_arg(&cursor); children_array[i] = skin_buffer_to_offset(skin_parse_code_as_arg(&cursor));
if (element->children[i] == NULL) if (children_array[i] < 0)
return 0; return 0;
skip_whitespace(&cursor); skip_whitespace(&cursor);
#ifdef ROCKBOX #ifdef ROCKBOX
@ -1035,6 +1059,7 @@ static int skin_parse_conditional(struct skin_element* element, const char** doc
} }
} }
*document = cursor; *document = cursor;
element->children = skin_buffer_to_offset(children_array);
return 1; return 1;
} }
@ -1056,7 +1081,7 @@ static int skin_parse_comment(struct skin_element* element, const char** documen
element->type = COMMENT; element->type = COMMENT;
element->line = skin_line; element->line = skin_line;
#ifdef ROCKBOX #ifdef ROCKBOX
element->data = NULL; element->data = INVALID_OFFSET;
#else #else
element->data = text = skin_alloc_string(length); element->data = text = skin_alloc_string(length);
if (!element->data) if (!element->data)
@ -1122,7 +1147,6 @@ static struct skin_element* skin_parse_code_as_arg(const char** document)
return skin_parse_line_optional(document, 1); return skin_parse_line_optional(document, 1);
} }
/* Memory management */ /* Memory management */
struct skin_element* skin_alloc_element() struct skin_element* skin_alloc_element()
{ {
@ -1131,10 +1155,12 @@ struct skin_element* skin_alloc_element()
if (!retval) if (!retval)
return NULL; return NULL;
retval->type = UNKNOWN; retval->type = UNKNOWN;
retval->next = NULL; retval->next = skin_buffer_to_offset(NULL);
retval->params = skin_buffer_to_offset(NULL);
retval->tag = NULL; retval->tag = NULL;
retval->params_count = 0; retval->params_count = 0;
retval->children_count = 0; retval->children_count = 0;
retval->data = INVALID_OFFSET;
return retval; return retval;
@ -1144,16 +1170,8 @@ struct skin_element* skin_alloc_element()
* enough for any tag. params should be used straight away by the callback * enough for any tag. params should be used straight away by the callback
* so this is safe. * 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; size_t size = sizeof(struct skin_tag_parameter) * count;
return (struct skin_tag_parameter*)skin_buffer_alloc(size); return (struct skin_tag_parameter*)skin_buffer_alloc(size);
@ -1164,9 +1182,9 @@ char* skin_alloc_string(int length)
return (char*)skin_buffer_alloc(sizeof(char) * (length + 1)); return (char*)skin_buffer_alloc(sizeof(char) * (length + 1));
} }
struct skin_element** skin_alloc_children(int count) OFFSETTYPE(struct skin_element*)* skin_alloc_children(int count)
{ {
return (struct skin_element**) return (OFFSETTYPE(struct skin_element*)*)
skin_buffer_alloc(sizeof(struct skin_element*) * count); skin_buffer_alloc(sizeof(struct skin_element*) * count);
} }

View file

@ -29,6 +29,25 @@ extern "C"
#include <stdlib.h> #include <stdlib.h>
#include <stdbool.h> #include <stdbool.h>
#if defined(ROCKBOX) && !defined(__PCTOOL__)
/* Use this type and macro to convert a pointer from the
* skin buffer to a useable pointer */
typedef long skinoffset_t;
#define SKINOFFSETTOPTR(base, offset) ((offset) < 0 ? NULL : ((void*)&base[offset]))
#define PTRTOSKINOFFSET(base, pointer) ((pointer) ? ((void*)pointer-(void*)base) : -1)
/* Use this macro when declaring a variable to self-document the code.
* type is the actual type being pointed to (i.e OFFSETTYPE(char*) foo )
*
* WARNING: Don't use the PTRTOSKINOFFSET() around a function call as it wont
* do what you expect.
*/
#define OFFSETTYPE(type) skinoffset_t
#else
#define SKINOFFSETTOPTR(base, offset) offset
#define PTRTOSKINOFFSET(base, pointer) pointer
#define OFFSETTYPE(type) type
#endif
/******************************************************************** /********************************************************************
****** Data Structures ********************************************* ****** Data Structures *********************************************
*******************************************************************/ *******************************************************************/
@ -78,8 +97,8 @@ struct skin_tag_parameter
union union
{ {
int number; int number;
char* text; OFFSETTYPE(char*) text;
struct skin_element* code; OFFSETTYPE(struct skin_element*) code;
} data; } data;
char type_code; char type_code;
@ -92,20 +111,20 @@ struct skin_tag_parameter
struct skin_element struct skin_element
{ {
/* Link to the next element */ /* Link to the next element */
struct skin_element* next; OFFSETTYPE(struct skin_element*) next;
/* Pointer to an array of children */ /* Pointer to an array of children */
struct skin_element** children; OFFSETTYPE(struct skin_element**) children;
/* Placeholder for element data /* Placeholder for element data
* TEXT and COMMENT uses it for the text string * TEXT and COMMENT uses it for the text string
* TAG, VIEWPORT, LINE, etc may use it for post parse extra storage * TAG, VIEWPORT, LINE, etc may use it for post parse extra storage
*/ */
void* data; OFFSETTYPE(void*) data;
/* The tag or conditional name */ /* The tag or conditional name */
const struct tag_info *tag; const struct tag_info *tag;
/* Pointer to an array of parameters */ /* Pointer to an array of parameters */
struct skin_tag_parameter* params; OFFSETTYPE(struct skin_tag_parameter*) params;
/* Number of elements in the children array */ /* Number of elements in the children array */
short children_count; short children_count;
@ -140,8 +159,8 @@ struct skin_element* skin_parse(const char* document);
#endif #endif
/* Memory management functions */ /* Memory management functions */
struct skin_element* skin_alloc_element(void); struct skin_element* skin_alloc_element(void);
struct skin_element** skin_alloc_children(int count); OFFSETTYPE(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); char* skin_alloc_string(int length);
void skin_free_tree(struct skin_element* root); void skin_free_tree(struct skin_element* root);

View file

@ -37,6 +37,7 @@
bool debug_wps = true; bool debug_wps = true;
int wps_verbose_level = 0; int wps_verbose_level = 0;
char *skin_buffer;
int errno; int errno;
@ -252,8 +253,6 @@ int main(int argc, char **argv)
struct wps_data wps={0}; struct wps_data wps={0};
enum screen_type screen = SCREEN_MAIN; enum screen_type screen = SCREEN_MAIN;
struct screen* wps_screen; struct screen* wps_screen;
char* buffer = NULL;
/* No arguments -> print the help text /* No arguments -> print the help text
* Also print the help text upon -h or --help */ * Also print the help text upon -h or --help */
@ -278,14 +277,14 @@ int main(int argc, char **argv)
wps_verbose_level++; wps_verbose_level++;
} }
} }
buffer = malloc(SKIN_BUFFER_SIZE); skin_buffer = malloc(SKIN_BUFFER_SIZE);
if (!buffer) if (!skin_buffer)
{ {
printf("mallloc fail!\n"); printf("mallloc fail!\n");
return 1; return 1;
} }
skin_buffer_init(buffer, SKIN_BUFFER_SIZE); skin_buffer_init(skin_buffer, SKIN_BUFFER_SIZE);
/* Go through every skin that was thrown at us, error out at the first /* Go through every skin that was thrown at us, error out at the first
* flawed wps */ * flawed wps */
@ -311,7 +310,7 @@ int main(int argc, char **argv)
printf("WPS parsed OK\n\n"); printf("WPS parsed OK\n\n");
if (wps_verbose_level>2) if (wps_verbose_level>2)
skin_debug_tree(wps.tree); skin_debug_tree(SKINOFFSETTOPTR(skin_buffer, wps.tree));
filearg++; filearg++;
} }
return 0; return 0;