summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonathan Gordon <rockbox@jdgordon.info>2009-08-16 18:23:00 +0000
committerJonathan Gordon <rockbox@jdgordon.info>2009-08-16 18:23:00 +0000
commit18a8e529b5d14413dce83cdb9103f3426db10708 (patch)
tree5ac9e53a987b6a48c92281b32aba9b6ca9bcab08
parenteefe832785407c387e71aba476091e805eecc3f4 (diff)
downloadrockbox-18a8e529b5d14413dce83cdb9103f3426db10708.tar.gz
rockbox-18a8e529b5d14413dce83cdb9103f3426db10708.tar.bz2
rockbox-18a8e529b5d14413dce83cdb9103f3426db10708.zip
more wps->skin engine work..
start redoing memory management in the skins to use a single larger buffer instead of lots of arrays for things like images and progressbars. This commit removes the limit on the amount of progressbars allowed on the screen, still 1 per viewport, but unlimited otherwise(!) Also a larger buffer for remote targets, same size for non-remote targets but very easy to make it bigger (technically removed the 52(?) image limit in skins, except still limited to 1 char identifiers) Unlimited "string" tokens now (limit was 1024 which was rediculously wasteful) git-svn-id: svn://svn.rockbox.org/rockbox/trunk@22350 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/SOURCES3
-rw-r--r--apps/gui/skin_engine/skin_buffer.c100
-rw-r--r--apps/gui/skin_engine/skin_buffer.h51
-rw-r--r--apps/gui/skin_engine/skin_display.c102
-rw-r--r--apps/gui/skin_engine/skin_engine.h2
-rw-r--r--apps/gui/skin_engine/skin_parser.c (renamed from apps/gui/skin_engine/wps_parser.c)267
-rw-r--r--apps/gui/skin_engine/skin_tokens.c2
-rw-r--r--apps/gui/skin_engine/skin_tokens.h218
-rw-r--r--apps/gui/skin_engine/wps_debug.c13
-rw-r--r--apps/gui/skin_engine/wps_internals.h201
-rw-r--r--apps/settings.c3
11 files changed, 597 insertions, 365 deletions
diff --git a/apps/SOURCES b/apps/SOURCES
index 807f3ded9d..143d9d50ea 100644
--- a/apps/SOURCES
+++ b/apps/SOURCES
@@ -84,9 +84,10 @@ gui/statusbar.c
gui/yesno.c
gui/viewport.c
+gui/skin_engine/skin_buffer.c
gui/skin_engine/wps_debug.c
gui/skin_engine/skin_display.c
-gui/skin_engine/wps_parser.c
+gui/skin_engine/skin_parser.c
gui/skin_engine/skin_tokens.c
#if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1))
diff --git a/apps/gui/skin_engine/skin_buffer.c b/apps/gui/skin_engine/skin_buffer.c
new file mode 100644
index 0000000000..2d10a931ec
--- /dev/null
+++ b/apps/gui/skin_engine/skin_buffer.c
@@ -0,0 +1,100 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id: wps_parser.c 19880 2009-01-29 20:49:43Z mcuelenaere $
+ *
+ * Copyright (C) 2002 by Linus Nielsen Feltzing
+ * Copyright (C) 2009 Jonathan Gordon
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "config.h"
+#include "buffer.h"
+#include "settings.h"
+#include "screen_access.h"
+
+/* skin buffer management.
+ * This module is used to allocate space in a single global skin buffer for
+ * tokens for both/all screens.
+ *
+ * This is mostly just copy/paste from firmware/buffer.c
+ */
+
+#define IMG_BUFSIZE (((LCD_HEIGHT*LCD_WIDTH*LCD_DEPTH/8) \
+ + (2*LCD_HEIGHT*LCD_WIDTH/8)) * NB_SCREENS)
+
+static unsigned char buffer_start[IMG_BUFSIZE], *buffer_pos = NULL;
+static size_t buf_size = IMG_BUFSIZE;
+
+void skin_buffer_init(void)
+{
+#if 0 /* this will go in again later probably */
+ if (buffer_start == NULL)
+ {
+ buf_size = IMG_BUFSIZE;/* global_settings.skin_buf_size */
+
+ buffer_start = buffer_alloc(buf_size);
+ buffer_pos = buffer_start;
+ }
+ else
+#endif
+ {
+ /* reset the buffer.... */
+ buffer_pos = buffer_start;
+ }
+}
+
+/* get the number of bytes currently being used */
+size_t skin_buffer_usage(void)
+{
+ return buffer_pos-buffer_start;
+}
+
+/* Allocate size bytes from the buffer */
+void* skin_buffer_alloc(size_t size)
+{
+ void* retval = buffer_pos;
+ if (skin_buffer_usage()+size >= buf_size)
+ {
+ return NULL;
+ }
+ buffer_pos += size;
+ /* 32-bit aligned */
+ buffer_pos = (void *)(((unsigned long)buffer_pos + 3) & ~3);
+ return retval;
+}
+
+/* Get a pointer to the skin buffer and the count of how much is free
+ * used to do your own buffer management.
+ * Any memory used will be overwritten next time wps_buffer_alloc()
+ * is called unless skin_buffer_increment() is called first
+ */
+void* skin_buffer_grab(size_t *freespace)
+{
+ *freespace = buf_size - skin_buffer_usage();
+ return buffer_pos;
+}
+
+/* Use after skin_buffer_grab() to specify how much buffer was used */
+void skin_buffer_increment(size_t used)
+{
+ buffer_pos += used;
+ /* 32-bit aligned */
+ buffer_pos = (void *)(((unsigned long)buffer_pos + 3) & ~3);
+}
+
diff --git a/apps/gui/skin_engine/skin_buffer.h b/apps/gui/skin_engine/skin_buffer.h
new file mode 100644
index 0000000000..779f575689
--- /dev/null
+++ b/apps/gui/skin_engine/skin_buffer.h
@@ -0,0 +1,51 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id: wps_parser.c 19880 2009-01-29 20:49:43Z mcuelenaere $
+ *
+ * Copyright (C) 2002 by Linus Nielsen Feltzing
+ * Copyright (C) 2009 Jonathan Gordon
+ *
+ * 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_BUFFER_H_
+#define _SKIN_BUFFER_H_
+
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+/* int the global buffer */
+void skin_buffer_init(void);
+
+/* get the number of bytes currently being used */
+size_t skin_buffer_usage(void);
+
+/* Allocate size bytes from the buffer */
+void* skin_buffer_alloc(size_t size);
+
+
+/* Get a pointer to the skin buffer and the count of how much is free
+ * used to do your own buffer management.
+ * Any memory used will be overwritten next time wps_buffer_alloc()
+ * is called unless skin_buffer_increment() is called first
+ */
+void* skin_buffer_grab(size_t *freespace);
+
+/* Use after skin_buffer_grab() to specify how much buffer was used */
+void skin_buffer_increment(size_t used);
+
+#endif /* _SKIN_BUFFER_H_ */
diff --git a/apps/gui/skin_engine/skin_display.c b/apps/gui/skin_engine/skin_display.c
index bf342116a6..4e264b0489 100644
--- a/apps/gui/skin_engine/skin_display.c
+++ b/apps/gui/skin_engine/skin_display.c
@@ -68,34 +68,16 @@
static bool skin_redraw(struct gui_wps *gwps, unsigned refresh_mode);
-#ifdef HAVE_LCD_BITMAP
-/* Clear the WPS image cache */
-static void wps_images_clear(struct wps_data *data)
-{
- int i;
- /* set images to unloaded and not displayed */
- for (i = 0; i < MAX_IMAGES; i++)
- {
- data->img[i].loaded = false;
- data->img[i].display = -1;
- data->img[i].always_display = false;
- data->img[i].num_subimages = 1;
- }
-}
-#endif
-
/* initial setup of wps_data */
void skin_data_init(struct wps_data *wps_data)
{
#ifdef HAVE_LCD_BITMAP
- wps_images_clear(wps_data);
wps_data->wps_sb_tag = false;
wps_data->show_sb_on_wps = false;
- wps_data->img_buf_ptr = wps_data->img_buf; /* where in image buffer */
- wps_data->img_buf_free = IMG_BUFSIZE; /* free space in image buffer */
wps_data->peak_meter_enabled = false;
+ wps_data->images = NULL;
+ wps_data->progressbars = NULL;
/* progress bars */
- wps_data->progressbar_count = 0;
#else /* HAVE_LCD_CHARCELLS */
int i;
for (i = 0; i < 8; i++)
@@ -191,41 +173,38 @@ static void draw_progressbar(struct gui_wps *gwps,
}
/* clears the area where the image was shown */
-static void clear_image_pos(struct gui_wps *gwps, int n)
+static void clear_image_pos(struct gui_wps *gwps, struct gui_img *img)
{
if(!gwps)
return;
- struct wps_data *data = gwps->data;
gwps->display->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
- gwps->display->fillrect(data->img[n].x, data->img[n].y,
- data->img[n].bm.width, data->img[n].subimage_height);
+ gwps->display->fillrect(img->x, img->y, img->bm.width, img->subimage_height);
gwps->display->set_drawmode(DRMODE_SOLID);
}
-static void wps_draw_image(struct gui_wps *gwps, int n, int subimage)
+static void wps_draw_image(struct gui_wps *gwps, struct gui_img *img, int subimage)
{
struct screen *display = gwps->display;
- struct wps_data *data = gwps->data;
- if(data->img[n].always_display)
+ if(img->always_display)
display->set_drawmode(DRMODE_FG);
else
display->set_drawmode(DRMODE_SOLID);
#if LCD_DEPTH > 1
- if(data->img[n].bm.format == FORMAT_MONO) {
+ if(img->bm.format == FORMAT_MONO) {
#endif
- display->mono_bitmap_part(data->img[n].bm.data,
- 0, data->img[n].subimage_height * subimage,
- data->img[n].bm.width, data->img[n].x,
- data->img[n].y, data->img[n].bm.width,
- data->img[n].subimage_height);
+ display->mono_bitmap_part(img->bm.data,
+ 0, img->subimage_height * subimage,
+ img->bm.width, img->x,
+ img->y, img->bm.width,
+ img->subimage_height);
#if LCD_DEPTH > 1
} else {
- display->transparent_bitmap_part((fb_data *)data->img[n].bm.data,
- 0, data->img[n].subimage_height * subimage,
- data->img[n].bm.width, data->img[n].x,
- data->img[n].y, data->img[n].bm.width,
- data->img[n].subimage_height);
+ display->transparent_bitmap_part((fb_data *)img->bm.data,
+ 0, img->subimage_height * subimage,
+ img->bm.width, img->x,
+ img->y, img->bm.width,
+ img->subimage_height);
}
#endif
}
@@ -235,22 +214,25 @@ static void wps_display_images(struct gui_wps *gwps, struct viewport* vp)
if(!gwps || !gwps->data || !gwps->display)
return;
- int n;
struct wps_data *data = gwps->data;
struct screen *display = gwps->display;
+ struct skin_token_list *list = data->images;
- for (n = 0; n < MAX_IMAGES; n++)
+ while (list)
{
- if (data->img[n].loaded)
+ struct gui_img *img = (struct gui_img*)list->token->value.data;
+ if (img->loaded)
{
- if (data->img[n].display >= 0)
+ if (img->display >= 0)
{
- wps_draw_image(gwps, n, data->img[n].display);
- } else if (data->img[n].always_display && data->img[n].vp == vp)
+ wps_draw_image(gwps, img, img->display);
+ }
+ else if (img->always_display && img->vp == vp)
{
- wps_draw_image(gwps, n, 0);
+ wps_draw_image(gwps, img, 0);
}
}
+ list = list->next;
}
display->set_drawmode(DRMODE_SOLID);
}
@@ -484,7 +466,7 @@ static bool evaluate_conditional(struct gui_wps *gwps, int *token_index)
#ifdef HAVE_LCD_BITMAP
/* clear all pictures in the conditional and nested ones */
if (data->tokens[i].type == WPS_TOKEN_IMAGE_PRELOAD_DISPLAY)
- clear_image_pos(gwps, data->tokens[i].value.i & 0xFF);
+ clear_image_pos(gwps, find_image(data->tokens[i].value.i&0xFF, gwps->data));
#endif
#ifdef HAVE_ALBUMART
if (data->tokens[i].type == WPS_TOKEN_ALBUMART_DISPLAY)
@@ -494,7 +476,20 @@ static bool evaluate_conditional(struct gui_wps *gwps, int *token_index)
return true;
}
-
+struct gui_img* find_image(int n, struct wps_data *data)
+{
+ struct skin_token_list *list = data->images;
+ while (list)
+ {
+ struct gui_img *img = (struct gui_img *)list->token->value.data;
+ if (img->id == n)
+ return img;
+ list = list->next;
+ }
+ return NULL;
+}
+
+
/* Read a (sub)line to the given alignment format buffer.
linebuf is the buffer where the data is actually stored.
align is the alignment format that'll be used to display the text.
@@ -544,12 +539,12 @@ static bool get_line(struct gui_wps *gwps,
#ifdef HAVE_LCD_BITMAP
case WPS_TOKEN_IMAGE_PRELOAD_DISPLAY:
{
- struct gui_img *img = data->img;
int n = data->tokens[i].value.i & 0xFF;
int subimage = data->tokens[i].value.i >> 8;
+ struct gui_img *img = find_image(n, data);
- if (n >= 0 && n < MAX_IMAGES && img[n].loaded)
- img[n].display = subimage;
+ if (img && img->loaded)
+ img->display = subimage;
break;
}
#endif
@@ -992,9 +987,12 @@ static bool skin_redraw(struct gui_wps *gwps, unsigned refresh_mode)
#ifdef HAVE_LCD_BITMAP
/* Set images to not to be displayed */
- for (i = 0; i < MAX_IMAGES; i++)
+ struct skin_token_list *imglist = data->images;
+ while (imglist)
{
- data->img[i].display = -1;
+ struct gui_img *img = (struct gui_img *)imglist->token->value.data;
+ img->display = -1;
+ imglist = imglist->next;
}
#endif
/* dont redraw the viewport if its disabled */
diff --git a/apps/gui/skin_engine/skin_engine.h b/apps/gui/skin_engine/skin_engine.h
index 1f5236fc15..3ec7b93a9d 100644
--- a/apps/gui/skin_engine/skin_engine.h
+++ b/apps/gui/skin_engine/skin_engine.h
@@ -23,6 +23,8 @@
#ifndef _SKIN_ENGINE_H
#define _SKIN_ENGINE_H
+#include "skin_buffer.h"
+
#include "wps_internals.h" /* TODO: remove this line.. shoudlnt be needed */
diff --git a/apps/gui/skin_engine/wps_parser.c b/apps/gui/skin_engine/skin_parser.c
index 4a41a26c7d..4445ee86c3 100644
--- a/apps/gui/skin_engine/wps_parser.c
+++ b/apps/gui/skin_engine/skin_parser.c
@@ -355,6 +355,40 @@ static const struct wps_tag all_tags[] = {
/* the array MUST end with an empty string (first char is \0) */
};
+
+/* add a wpsll item to the list chain. ALWAYS appended because some of the
+ * chains require the order to be kept.
+ */
+static void add_to_ll_chain(struct skin_token_list **list, struct skin_token_list *item)
+{
+ if (*list == NULL)
+ *list = item;
+ else
+ {
+ struct skin_token_list *t = *list;
+ while (t->next)
+ t = t->next;
+ t->next = item;
+ }
+}
+/* create and init a new wpsll item.
+ * passing NULL to token will alloc a new one.
+ */
+static struct skin_token_list *new_skin_token_list_item(struct wps_token *token,
+ void* token_data)
+{
+ struct skin_token_list *llitem = skin_buffer_alloc(sizeof(struct skin_token_list));
+ if (!token)
+ token = skin_buffer_alloc(sizeof(struct wps_token));
+ if (!llitem || !token)
+ return NULL;
+ llitem->next = NULL;
+ llitem->token = token;
+ if (token_data)
+ llitem->token->value.data = token_data;
+ return llitem;
+}
+
/* Returns the number of chars that should be skipped to jump
immediately after the first eol, i.e. to the start of the next line */
static int skip_end_of_line(const char *wps_bufptr)
@@ -406,37 +440,6 @@ static int parse_statusbar_disable(const char *wps_bufptr,
return skip_end_of_line(wps_bufptr);
}
-static bool load_bitmap(struct wps_data *wps_data,
- char* filename,
- struct bitmap *bm)
-{
- int format;
-#ifdef HAVE_REMOTE_LCD
- if (wps_data->remote_wps)
- format = FORMAT_ANY|FORMAT_REMOTE;
- else
-#endif
- format = FORMAT_ANY|FORMAT_TRANSPARENT;
-
- int ret = read_bmp_file(filename, bm,
- wps_data->img_buf_free,
- format,NULL);
-
- if (ret > 0)
- {
-#if LCD_DEPTH == 16
- if (ret % 2) ret++;
- /* Always consume an even number of bytes */
-#endif
- wps_data->img_buf_ptr += ret;
- wps_data->img_buf_free -= ret;
-
- return true;
- }
- else
- return false;
-}
-
static int get_image_id(int c)
{
if(c >= 'a' && c <= 'z')
@@ -472,9 +475,9 @@ static int parse_image_display(const char *wps_bufptr,
struct wps_token *token,
struct wps_data *wps_data)
{
- (void)wps_data;
int n = get_image_id(wps_bufptr[0]);
int subimage;
+ struct gui_img *img;;
if (n == -1)
{
@@ -484,8 +487,9 @@ static int parse_image_display(const char *wps_bufptr,
if ((subimage = get_image_id(wps_bufptr[1])) != -1)
{
+ img = find_image(n, wps_data);
/* Sanity check */
- if (subimage >= wps_data->img[n].num_subimages)
+ if (!img || subimage >= img->num_subimages)
return WPS_ERROR_INVALID_PARAM;
/* Store sub-image number to display in high bits */
@@ -508,6 +512,7 @@ static int parse_image_load(const char *wps_bufptr,
const char* id;
const char *newline;
int x,y;
+ struct gui_img *img;
/* format: %x|n|filename.bmp|x|y|
or %xl|n|filename.bmp|x|y|
@@ -530,24 +535,28 @@ static int parse_image_load(const char *wps_bufptr,
n = get_image_id(*id);
/* check the image number and load state */
- if(n < 0 || n >= MAX_IMAGES || wps_data->img[n].loaded)
+ if(n < 0 || find_image(n, wps_data))
{
/* Invalid image ID */
return WPS_ERROR_INVALID_PARAM;
}
-
+ img = skin_buffer_alloc(sizeof(struct gui_img));
+ if (!img)
+ return WPS_ERROR_INVALID_PARAM;
/* save a pointer to the filename */
- bmp_names[n] = filename;
-
- wps_data->img[n].x = x;
- wps_data->img[n].y = y;
+ img->bm.data = (char*)filename;
+ img->id = n;
+ img->x = x;
+ img->y = y;
+ img->num_subimages = 1;
+ img->always_display = false;
/* save current viewport */
- wps_data->img[n].vp = &wps_data->viewports[wps_data->num_viewports].vp;
+ img->vp = &wps_data->viewports[wps_data->num_viewports].vp;
if (token->type == WPS_TOKEN_IMAGE_DISPLAY)
{
- wps_data->img[n].always_display = true;
+ img->always_display = true;
}
else
{
@@ -556,11 +565,15 @@ static int parse_image_load(const char *wps_bufptr,
newline = strchr(ptr, '\n');
pos = strchr(ptr, '|');
if (pos && pos < newline)
- wps_data->img[n].num_subimages = atoi(ptr);
+ img->num_subimages = atoi(ptr);
- if (wps_data->img[n].num_subimages <= 0)
+ if (img->num_subimages <= 0)
return WPS_ERROR_INVALID_PARAM;
}
+ struct skin_token_list *item = new_skin_token_list_item(NULL, img);
+ if (!item)
+ return WPS_ERROR_INVALID_PARAM;
+ add_to_ll_chain(&wps_data->images, item);
/* Skip the rest of the line */
return skip_end_of_line(wps_bufptr);
@@ -781,7 +794,6 @@ static int parse_progressbar(const char *wps_bufptr,
struct wps_token *token,
struct wps_data *wps_data)
{
- (void)token; /* Kill warnings */
/* %pb or %pb|filename|x|y|width|height|
using - for any of the params uses "sane" values */
#ifdef HAVE_LCD_BITMAP
@@ -796,7 +808,12 @@ static int parse_progressbar(const char *wps_bufptr,
int x, y, height, width;
uint32_t set = 0;
const char *ptr = wps_bufptr;
- struct progressbar *pb;
+ struct progressbar *pb = skin_buffer_alloc(sizeof(struct progressbar));
+ struct skin_token_list *item = new_skin_token_list_item(token, pb);
+
+ if (!pb || !item)
+ return WPS_ERROR_INVALID_PARAM;
+
struct viewport *vp = &wps_data->viewports[wps_data->num_viewports].vp;
#ifndef __PCTOOL__
int font_height = font_get(vp->font)->height;
@@ -806,11 +823,8 @@ static int parse_progressbar(const char *wps_bufptr,
int line_num = wps_data->num_lines -
wps_data->viewports[wps_data->num_viewports].first_line;
- if (wps_data->progressbar_count >= MAX_PROGRESSBARS)
- return WPS_ERROR_INVALID_PARAM;
-
- pb = &wps_data->progressbar[wps_data->progressbar_count];
pb->have_bitmap_pb = false;
+ pb->bm.data = NULL; /* no bitmap specified */
if (*wps_bufptr != '|') /* regular old style */
{
@@ -820,7 +834,7 @@ static int parse_progressbar(const char *wps_bufptr,
pb->y = -line_num - 1; /* Will be computed during the rendering */
wps_data->viewports[wps_data->num_viewports].pb = pb;
- wps_data->progressbar_count++;
+ add_to_ll_chain(&wps_data->progressbars, item);
return 0;
}
ptr = wps_bufptr + 1;
@@ -830,7 +844,7 @@ static int parse_progressbar(const char *wps_bufptr,
return WPS_ERROR_INVALID_PARAM;
if (LIST_VALUE_PARSED(set, PB_FILENAME)) /* filename */
- bmp_names[PROGRESSBAR_BMP+wps_data->progressbar_count] = filename;
+ pb->bm.data = (char*)filename;
if (LIST_VALUE_PARSED(set, PB_X)) /* x */
pb->x = x;
@@ -865,7 +879,7 @@ static int parse_progressbar(const char *wps_bufptr,
pb->y = -line_num - 1; /* Will be computed during the rendering */
wps_data->viewports[wps_data->num_viewports].pb = pb;
- wps_data->progressbar_count++;
+ add_to_ll_chain(&wps_data->progressbars, item);
/* Skip the rest of the line */
return skip_end_of_line(wps_bufptr)-1;
@@ -1250,9 +1264,6 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr)
{
if (!data || !wps_bufptr || !*wps_bufptr)
return false;
-
- char *stringbuf = data->string_buffer;
- int stringbuf_used = 0;
enum wps_parse_error fail = PARSE_OK;
int ret;
line = 1;
@@ -1404,42 +1415,45 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr)
}
/* look if we already have that string */
- char **str;
- int i;
- bool found;
- for (i = 0, str = data->strings, found = false;
- i < data->num_strings &&
- !(found = (strlen(*str) == len &&
- strncmp(string_start, *str, len) == 0));
- i++, str++);
+ char *str;
+ bool found = false;
+ struct skin_token_list *list = data->strings;
+ while (list)
+ {
+ str = (char*)list->token->value.data;
+ found = (strlen(str) == len &&
+ strncmp(string_start, str, len) == 0);
+ if (found)
+ break; /* break here because the list item is
+ used if its found */
+ list = list->next;
+ }
/* If a matching string is found, found is true and i is
the index of the string. If not, found is false */
if (!found)
{
/* new string */
-
- if (stringbuf_used + len > STRING_BUFFER_SIZE - 1
- || data->num_strings >= WPS_MAX_STRINGS)
- {
- /* too many strings or characters */
- fail = PARSE_FAIL_LIMITS_EXCEEDED;
- break;
+ str = (char*)skin_buffer_alloc(len+1);
+ if (!str)
+ {
+ fail = PARSE_FAIL_LIMITS_EXCEEDED;
+ break;
}
-
- strlcpy(stringbuf, string_start, len+1);
-
- data->strings[data->num_strings] = stringbuf;
- stringbuf += len + 1;
- stringbuf_used += len + 1;
- data->tokens[data->num_tokens].value.i =
- data->num_strings;
- data->num_strings++;
+ strlcpy(str, string_start, len+1);
+ struct skin_token_list *item =
+ new_skin_token_list_item(&data->tokens[data->num_tokens], str);
+ if(!item)
+ {
+ fail = PARSE_FAIL_LIMITS_EXCEEDED;
+ break;
+ }
+ add_to_ll_chain(&data->strings, item);
}
else
{
/* another occurrence of an existing string */
- data->tokens[data->num_tokens].value.i = i;
+ data->tokens[data->num_tokens].value.data = list->token->value.data;
}
data->tokens[data->num_tokens].type = WPS_TOKEN_STRING;
data->num_tokens++;
@@ -1480,54 +1494,75 @@ static void wps_reset(struct wps_data *data)
}
#ifdef HAVE_LCD_BITMAP
+static bool load_skin_bmp(struct wps_data *wps_data, struct bitmap *bitmap, char* bmpdir)
+{
+ (void)wps_data; /* only needed for remote targets */
+ bool loaded = false;
+ char img_path[MAX_PATH];
+ get_image_filename(bitmap->data, bmpdir,
+ img_path, sizeof(img_path));
+
+ /* load the image */
+ int format;
+#ifdef HAVE_REMOTE_LCD
+ if (wps_data->remote_wps)
+ format = FORMAT_ANY|FORMAT_REMOTE;
+ else
+#endif
+ format = FORMAT_ANY|FORMAT_TRANSPARENT;
+
+ size_t max_buf;
+ char* imgbuf = (char*)skin_buffer_grab(&max_buf);
+ bitmap->data = imgbuf;
+ int ret = read_bmp_file(img_path, bitmap, max_buf, format, NULL);
+
+ if (ret > 0)
+ {
+ skin_buffer_increment(ret);
+ loaded = true;
+ }
+ else
+ {
+ /* Abort if we can't load an image */
+ DEBUGF("ERR: Failed to load image - %s\n",img_path);
+ loaded = false;
+ }
+ return loaded;
+}
static bool load_skin_bitmaps(struct wps_data *wps_data, char *bmpdir)
{
- char img_path[MAX_PATH];
- struct bitmap *bitmap;
- bool *loaded;
- int n;
- for (n = 0; n < BACKDROP_BMP; n++)
+ struct skin_token_list *list;
+ /* do the progressbars */
+ list = wps_data->progressbars;
+ while (list)
{
- if (bmp_names[n])
+ struct progressbar *pb = (struct progressbar*)list->token->value.data;
+ if (pb->bm.data)
{
- get_image_filename(bmp_names[n], bmpdir,
- img_path, sizeof(img_path));
-
- if (n >= PROGRESSBAR_BMP ) {
- /* progressbar bitmap */
- bitmap = &wps_data->progressbar[n-PROGRESSBAR_BMP].bm;
- loaded = &wps_data->progressbar[n-PROGRESSBAR_BMP].have_bitmap_pb;
- } else {
- /* regular bitmap */
- bitmap = &wps_data->img[n].bm;
- loaded = &wps_data->img[n].loaded;
- }
-
- /* load the image */
- bitmap->data = wps_data->img_buf_ptr;
- if (load_bitmap(wps_data, img_path, bitmap))
- {
- *loaded = true;
-
- /* Calculate and store height if this image has sub-images */
- if (n < MAX_IMAGES)
- wps_data->img[n].subimage_height = wps_data->img[n].bm.height /
- wps_data->img[n].num_subimages;
- }
- else
- {
- /* Abort if we can't load an image */
- DEBUGF("ERR: Failed to load image %d - %s\n",n,img_path);
- return false;
- }
+ pb->have_bitmap_pb = load_skin_bmp(wps_data, &pb->bm, bmpdir);
+ }
+ list = list->next;
+ }
+ /* regular images */
+ list = wps_data->images;
+ while (list)
+ {
+ struct gui_img *img = (struct gui_img*)list->token->value.data;
+ if (img->bm.data)
+ {
+ img->loaded = load_skin_bmp(wps_data, &img->bm, bmpdir);
+ if (img->loaded)
+ img->subimage_height = img->bm.height / img->num_subimages;
}
+ list = list->next;
}
#if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1))
if (bmp_names[BACKDROP_BMP])
{
int screen = SCREEN_MAIN;
+ char img_path[MAX_PATH];
get_image_filename(bmp_names[BACKDROP_BMP], bmpdir,
img_path, sizeof(img_path));
#if defined(HAVE_REMOTE_LCD)
diff --git a/apps/gui/skin_engine/skin_tokens.c b/apps/gui/skin_engine/skin_tokens.c
index b1163aa88a..386dc5ded8 100644
--- a/apps/gui/skin_engine/skin_tokens.c
+++ b/apps/gui/skin_engine/skin_tokens.c
@@ -167,7 +167,7 @@ const char *get_token_value(struct gui_wps *gwps,
return &(token->value.c);
case WPS_TOKEN_STRING:
- return data->strings[token->value.i];
+ return (char*)token->value.data;
case WPS_TOKEN_TRACK_TIME_ELAPSED:
format_time(buf, buf_size,
diff --git a/apps/gui/skin_engine/skin_tokens.h b/apps/gui/skin_engine/skin_tokens.h
new file mode 100644
index 0000000000..ea59053c7a
--- /dev/null
+++ b/apps/gui/skin_engine/skin_tokens.h
@@ -0,0 +1,218 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id: wps_internals.h 22223 2009-08-09 17:30:05Z jdgordon $
+ *
+ * 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>
+
+
+enum wps_token_type {
+ WPS_NO_TOKEN, /* for WPS tags we don't want to save as tokens */
+ WPS_TOKEN_UNKNOWN,
+
+ /* Markers */
+ WPS_TOKEN_CHARACTER,
+ WPS_TOKEN_STRING,
+
+ /* Alignment */
+ WPS_TOKEN_ALIGN_LEFT,
+ WPS_TOKEN_ALIGN_CENTER,
+ WPS_TOKEN_ALIGN_RIGHT,
+
+ /* Sublines */
+ WPS_TOKEN_SUBLINE_TIMEOUT,
+
+ /* Battery */
+ WPS_TOKEN_BATTERY_PERCENT,
+ WPS_TOKEN_BATTERY_VOLTS,
+ WPS_TOKEN_BATTERY_TIME,
+ WPS_TOKEN_BATTERY_CHARGER_CONNECTED,
+ WPS_TOKEN_BATTERY_CHARGING,
+ WPS_TOKEN_BATTERY_SLEEPTIME,
+
+ /* Sound */
+#if (CONFIG_CODEC != MAS3507D)
+ WPS_TOKEN_SOUND_PITCH,
+#endif
+#if (CONFIG_CODEC == SWCODEC)
+ WPS_TOKEN_REPLAYGAIN,
+ WPS_TOKEN_CROSSFADE,
+#endif
+
+ /* Time */
+
+ WPS_TOKEN_RTC_PRESENT,
+
+ /* The begin/end values allow us to know if a token is an RTC one.
+ New RTC tokens should be added between the markers. */
+
+ WPS_TOKENS_RTC_BEGIN, /* just the start marker, not an actual token */
+
+ WPS_TOKEN_RTC_DAY_OF_MONTH,
+ WPS_TOKEN_RTC_DAY_OF_MONTH_BLANK_PADDED,
+ WPS_TOKEN_RTC_12HOUR_CFG,
+ WPS_TOKEN_RTC_HOUR_24_ZERO_PADDED,
+ WPS_TOKEN_RTC_HOUR_24,
+ WPS_TOKEN_RTC_HOUR_12_ZERO_PADDED,
+ WPS_TOKEN_RTC_HOUR_12,
+ WPS_TOKEN_RTC_MONTH,
+ WPS_TOKEN_RTC_MINUTE,
+ WPS_TOKEN_RTC_SECOND,
+ WPS_TOKEN_RTC_YEAR_2_DIGITS,
+ WPS_TOKEN_RTC_YEAR_4_DIGITS,
+ WPS_TOKEN_RTC_AM_PM_UPPER,
+ WPS_TOKEN_RTC_AM_PM_LOWER,
+ WPS_TOKEN_RTC_WEEKDAY_NAME,
+ WPS_TOKEN_RTC_MONTH_NAME,
+ WPS_TOKEN_RTC_DAY_OF_WEEK_START_MON,
+ WPS_TOKEN_RTC_DAY_OF_WEEK_START_SUN,
+
+ WPS_TOKENS_RTC_END, /* just the end marker, not an actual token */
+
+ /* Conditional */
+ WPS_TOKEN_CONDITIONAL,
+ WPS_TOKEN_CONDITIONAL_START,
+ WPS_TOKEN_CONDITIONAL_OPTION,
+ WPS_TOKEN_CONDITIONAL_END,
+
+ /* Database */
+#ifdef HAVE_TAGCACHE
+ WPS_TOKEN_DATABASE_PLAYCOUNT,
+ WPS_TOKEN_DATABASE_RATING,
+ WPS_TOKEN_DATABASE_AUTOSCORE,
+#endif
+
+ /* File */
+ WPS_TOKEN_FILE_BITRATE,
+ WPS_TOKEN_FILE_CODEC,
+ WPS_TOKEN_FILE_FREQUENCY,
+ WPS_TOKEN_FILE_FREQUENCY_KHZ,
+ WPS_TOKEN_FILE_NAME,
+ WPS_TOKEN_FILE_NAME_WITH_EXTENSION,
+ WPS_TOKEN_FILE_PATH,
+ WPS_TOKEN_FILE_SIZE,
+ WPS_TOKEN_FILE_VBR,
+ WPS_TOKEN_FILE_DIRECTORY,
+
+#ifdef HAVE_LCD_BITMAP
+ /* Image */
+ WPS_TOKEN_IMAGE_BACKDROP,
+ WPS_TOKEN_IMAGE_PROGRESS_BAR,
+ WPS_TOKEN_IMAGE_PRELOAD,
+ WPS_TOKEN_IMAGE_PRELOAD_DISPLAY,
+ WPS_TOKEN_IMAGE_DISPLAY,
+#endif
+
+#ifdef HAVE_ALBUMART
+ /* Albumart */
+ WPS_TOKEN_ALBUMART_DISPLAY,
+ WPS_TOKEN_ALBUMART_FOUND,
+#endif
+
+ /* Metadata */
+ WPS_TOKEN_METADATA_ARTIST,
+ WPS_TOKEN_METADATA_COMPOSER,
+ WPS_TOKEN_METADATA_ALBUM_ARTIST,
+ WPS_TOKEN_METADATA_GROUPING,
+ WPS_TOKEN_METADATA_ALBUM,
+ WPS_TOKEN_METADATA_GENRE,
+ WPS_TOKEN_METADATA_DISC_NUMBER,
+ WPS_TOKEN_METADATA_TRACK_NUMBER,
+ WPS_TOKEN_METADATA_TRACK_TITLE,
+ WPS_TOKEN_METADATA_VERSION,
+ WPS_TOKEN_METADATA_YEAR,
+ WPS_TOKEN_METADATA_COMMENT,
+
+ /* Mode */
+ WPS_TOKEN_REPEAT_MODE,
+ WPS_TOKEN_PLAYBACK_STATUS,
+
+ WPS_TOKEN_MAIN_HOLD,
+
+#ifdef HAS_REMOTE_BUTTON_HOLD
+ WPS_TOKEN_REMOTE_HOLD,
+#endif
+
+ /* Progressbar */
+ WPS_TOKEN_PROGRESSBAR,
+#ifdef HAVE_LCD_CHARCELLS
+ WPS_TOKEN_PLAYER_PROGRESSBAR,
+#endif
+
+#ifdef HAVE_LCD_BITMAP
+ /* Peakmeter */
+ WPS_TOKEN_PEAKMETER,
+#endif
+
+ /* Volume level */
+ WPS_TOKEN_VOLUME,
+
+ /* Current track */
+ WPS_TOKEN_TRACK_ELAPSED_PERCENT,
+ WPS_TOKEN_TRACK_TIME_ELAPSED,
+ WPS_TOKEN_TRACK_TIME_REMAINING,
+ WPS_TOKEN_TRACK_LENGTH,
+
+ /* Playlist */
+ WPS_TOKEN_PLAYLIST_ENTRIES,
+ WPS_TOKEN_PLAYLIST_NAME,
+ WPS_TOKEN_PLAYLIST_POSITION,
+ WPS_TOKEN_PLAYLIST_SHUFFLE,
+
+#if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
+ /* Virtual LED */
+ WPS_TOKEN_VLED_HDD,
+#endif
+
+ /* Viewport display */
+ WPS_VIEWPORT_ENABLE,
+
+ /* buttons */
+ WPS_TOKEN_BUTTON_VOLUME,
+ WPS_TOKEN_LASTTOUCH,
+
+ /* Setting option */
+ WPS_TOKEN_SETTING,
+};
+
+struct wps_token {
+ unsigned char 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;
+
+ union {
+ char c;
+ unsigned short i;
+ void* data;
+ } value;
+};
+
+struct skin_token_list {
+ struct wps_token *token;
+ struct skin_token_list *next;
+};
+
+
+#endif
+
diff --git a/apps/gui/skin_engine/wps_debug.c b/apps/gui/skin_engine/wps_debug.c
index 02a2cc3de9..c4a73a7cfb 100644
--- a/apps/gui/skin_engine/wps_debug.c
+++ b/apps/gui/skin_engine/wps_debug.c
@@ -23,6 +23,7 @@
#include <stdio.h>
#include <string.h>
+#include "wps.h"
#include "wps_internals.h"
#ifdef __PCTOOL__
#ifdef WPSEDITOR
@@ -548,15 +549,18 @@ static void print_line_info(struct wps_data *data)
DEBUGF("\n");
}
}
-
+#if 0
+/* NOTE: this is probaly not even needed anymore */
static void print_wps_strings(struct wps_data *data)
{
int i, len, total_len = 0, buf_used = 0;
if (wps_verbose_level > 1) DEBUGF("Strings:\n");
- for (i = 0; i < data->num_strings; i++)
+ struct skin_token_list *strings = data->strings;
+ while (strings)
{
- len = strlen(data->strings[i]);
+ char* str = (char*)strings->token->value.data;
+ len = strlen(str);
total_len += len;
buf_used += len + 1;
if (wps_verbose_level > 1)
@@ -575,6 +579,7 @@ static void print_wps_strings(struct wps_data *data)
}
}
#endif
+#endif
void print_debug_info(struct wps_data *data, enum wps_parse_error fail, int line)
{
@@ -582,7 +587,7 @@ void print_debug_info(struct wps_data *data, enum wps_parse_error fail, int line
if (debug_wps && wps_verbose_level)
{
dump_wps_tokens(data);
- print_wps_strings(data);
+ /* print_wps_strings(data); */
print_line_info(data);
}
#endif /* SIMULATOR */
diff --git a/apps/gui/skin_engine/wps_internals.h b/apps/gui/skin_engine/wps_internals.h
index ffebed7bad..bb68e578ab 100644
--- a/apps/gui/skin_engine/wps_internals.h
+++ b/apps/gui/skin_engine/wps_internals.h
@@ -31,7 +31,7 @@
#define TIMEOUT_UNIT (HZ/10) /* I.e. 0.1 sec */
#define DEFAULT_SUBLINE_TIME_MULTIPLIER 20 /* In TIMEOUT_UNIT's */
-
+#include "skin_tokens.h"
/* TODO: sort this mess out */
@@ -77,6 +77,7 @@
#ifdef HAVE_LCD_BITMAP
struct gui_img {
+ short int id;
struct bitmap bm;
struct viewport* vp; /* The viewport to display this image in */
short int x; /* x-pos */
@@ -88,6 +89,7 @@ struct gui_img {
bool always_display; /* not using the preload/display mechanism */
};
+
struct progressbar {
/* regular pb */
short x;
@@ -153,187 +155,6 @@ enum wps_parse_error {
PARSE_FAIL_LIMITS_EXCEEDED,
};
-enum wps_token_type {
- WPS_NO_TOKEN, /* for WPS tags we don't want to save as tokens */
- WPS_TOKEN_UNKNOWN,
-
- /* Markers */
- WPS_TOKEN_CHARACTER,
- WPS_TOKEN_STRING,
-
- /* Alignment */
- WPS_TOKEN_ALIGN_LEFT,
- WPS_TOKEN_ALIGN_CENTER,
- WPS_TOKEN_ALIGN_RIGHT,
-
- /* Sublines */
- WPS_TOKEN_SUBLINE_TIMEOUT,
-
- /* Battery */
- WPS_TOKEN_BATTERY_PERCENT,
- WPS_TOKEN_BATTERY_VOLTS,
- WPS_TOKEN_BATTERY_TIME,
- WPS_TOKEN_BATTERY_CHARGER_CONNECTED,
- WPS_TOKEN_BATTERY_CHARGING,
- WPS_TOKEN_BATTERY_SLEEPTIME,
-
- /* Sound */
-#if (CONFIG_CODEC != MAS3507D)
- WPS_TOKEN_SOUND_PITCH,
-#endif
-#if (CONFIG_CODEC == SWCODEC)
- WPS_TOKEN_REPLAYGAIN,
- WPS_TOKEN_CROSSFADE,
-#endif
-
- /* Time */
-
- WPS_TOKEN_RTC_PRESENT,
-
- /* The begin/end values allow us to know if a token is an RTC one.
- New RTC tokens should be added between the markers. */
-
- WPS_TOKENS_RTC_BEGIN, /* just the start marker, not an actual token */
-
- WPS_TOKEN_RTC_DAY_OF_MONTH,
- WPS_TOKEN_RTC_DAY_OF_MONTH_BLANK_PADDED,
- WPS_TOKEN_RTC_12HOUR_CFG,
- WPS_TOKEN_RTC_HOUR_24_ZERO_PADDED,
- WPS_TOKEN_RTC_HOUR_24,
- WPS_TOKEN_RTC_HOUR_12_ZERO_PADDED,
- WPS_TOKEN_RTC_HOUR_12,
- WPS_TOKEN_RTC_MONTH,
- WPS_TOKEN_RTC_MINUTE,
- WPS_TOKEN_RTC_SECOND,
- WPS_TOKEN_RTC_YEAR_2_DIGITS,
- WPS_TOKEN_RTC_YEAR_4_DIGITS,
- WPS_TOKEN_RTC_AM_PM_UPPER,
- WPS_TOKEN_RTC_AM_PM_LOWER,
- WPS_TOKEN_RTC_WEEKDAY_NAME,
- WPS_TOKEN_RTC_MONTH_NAME,
- WPS_TOKEN_RTC_DAY_OF_WEEK_START_MON,
- WPS_TOKEN_RTC_DAY_OF_WEEK_START_SUN,
-
- WPS_TOKENS_RTC_END, /* just the end marker, not an actual token */
-
- /* Conditional */
- WPS_TOKEN_CONDITIONAL,
- WPS_TOKEN_CONDITIONAL_START,
- WPS_TOKEN_CONDITIONAL_OPTION,
- WPS_TOKEN_CONDITIONAL_END,
-
- /* Database */
-#ifdef HAVE_TAGCACHE
- WPS_TOKEN_DATABASE_PLAYCOUNT,
- WPS_TOKEN_DATABASE_RATING,
- WPS_TOKEN_DATABASE_AUTOSCORE,
-#endif
-
- /* File */
- WPS_TOKEN_FILE_BITRATE,
- WPS_TOKEN_FILE_CODEC,
- WPS_TOKEN_FILE_FREQUENCY,
- WPS_TOKEN_FILE_FREQUENCY_KHZ,
- WPS_TOKEN_FILE_NAME,
- WPS_TOKEN_FILE_NAME_WITH_EXTENSION,
- WPS_TOKEN_FILE_PATH,
- WPS_TOKEN_FILE_SIZE,
- WPS_TOKEN_FILE_VBR,
- WPS_TOKEN_FILE_DIRECTORY,
-
-#ifdef HAVE_LCD_BITMAP
- /* Image */
- WPS_TOKEN_IMAGE_BACKDROP,
- WPS_TOKEN_IMAGE_PROGRESS_BAR,
- WPS_TOKEN_IMAGE_PRELOAD,
- WPS_TOKEN_IMAGE_PRELOAD_DISPLAY,
- WPS_TOKEN_IMAGE_DISPLAY,
-#endif
-
-#ifdef HAVE_ALBUMART
- /* Albumart */
- WPS_TOKEN_ALBUMART_DISPLAY,
- WPS_TOKEN_ALBUMART_FOUND,
-#endif
-
- /* Metadata */
- WPS_TOKEN_METADATA_ARTIST,
- WPS_TOKEN_METADATA_COMPOSER,
- WPS_TOKEN_METADATA_ALBUM_ARTIST,
- WPS_TOKEN_METADATA_GROUPING,
- WPS_TOKEN_METADATA_ALBUM,
- WPS_TOKEN_METADATA_GENRE,
- WPS_TOKEN_METADATA_DISC_NUMBER,
- WPS_TOKEN_METADATA_TRACK_NUMBER,
- WPS_TOKEN_METADATA_TRACK_TITLE,
- WPS_TOKEN_METADATA_VERSION,
- WPS_TOKEN_METADATA_YEAR,
- WPS_TOKEN_METADATA_COMMENT,
-
- /* Mode */
- WPS_TOKEN_REPEAT_MODE,
- WPS_TOKEN_PLAYBACK_STATUS,
-
- WPS_TOKEN_MAIN_HOLD,
-
-#ifdef HAS_REMOTE_BUTTON_HOLD
- WPS_TOKEN_REMOTE_HOLD,
-#endif
-
- /* Progressbar */
- WPS_TOKEN_PROGRESSBAR,
-#ifdef HAVE_LCD_CHARCELLS
- WPS_TOKEN_PLAYER_PROGRESSBAR,
-#endif
-
-#ifdef HAVE_LCD_BITMAP
- /* Peakmeter */
- WPS_TOKEN_PEAKMETER,
-#endif
-
- /* Volume level */
- WPS_TOKEN_VOLUME,
-
- /* Current track */
- WPS_TOKEN_TRACK_ELAPSED_PERCENT,
- WPS_TOKEN_TRACK_TIME_ELAPSED,
- WPS_TOKEN_TRACK_TIME_REMAINING,
- WPS_TOKEN_TRACK_LENGTH,
-
- /* Playlist */
- WPS_TOKEN_PLAYLIST_ENTRIES,
- WPS_TOKEN_PLAYLIST_NAME,
- WPS_TOKEN_PLAYLIST_POSITION,
- WPS_TOKEN_PLAYLIST_SHUFFLE,
-
-#if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
- /* Virtual LED */
- WPS_TOKEN_VLED_HDD,
-#endif
-
- /* Viewport display */
- WPS_VIEWPORT_ENABLE,
-
- /* buttons */
- WPS_TOKEN_BUTTON_VOLUME,
- WPS_TOKEN_LASTTOUCH,
-
- /* Setting option */
- WPS_TOKEN_SETTING,
-};
-
-struct wps_token {
- unsigned char 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;
-
- union {
- char c;
- unsigned short i;
- } value;
-};
/* Description of a subline on the WPS */
struct wps_subline {
@@ -406,15 +227,11 @@ struct touchregion {
struct wps_data
{
#ifdef HAVE_LCD_BITMAP
- struct gui_img img[MAX_IMAGES];
- unsigned char img_buf[IMG_BUFSIZE];
- unsigned char* img_buf_ptr;
- int img_buf_free;
bool wps_sb_tag;
bool show_sb_on_wps;
- struct progressbar progressbar[MAX_PROGRESSBARS];
- short progressbar_count;
+ struct skin_token_list *images;
+ struct skin_token_list *progressbars;
bool peak_meter_enabled;
@@ -465,9 +282,7 @@ struct wps_data
int num_tokens;
struct wps_token tokens[WPS_MAX_TOKENS];
- char string_buffer[STRING_BUFFER_SIZE];
- char *strings[WPS_MAX_STRINGS];
- int num_strings;
+ struct skin_token_list *strings;
bool wps_loaded;
@@ -533,4 +348,8 @@ const char *get_token_value(struct gui_wps *gwps,
char *buf, int buf_size,
int *intval);
+
+
+struct gui_img* find_image(int n, struct wps_data *data);
+
#endif
diff --git a/apps/settings.c b/apps/settings.c
index bd2958e4e2..72e5a012e4 100644
--- a/apps/settings.c
+++ b/apps/settings.c
@@ -70,6 +70,7 @@
#include "radio.h"
#endif
#include "wps.h"
+#include "skin_engine/skin_engine.h"
#if CONFIG_CODEC == MAS3507D
void dac_line_in(bool enable);
@@ -818,6 +819,8 @@ void settings_apply(bool read_disk)
if (read_disk)
{
+ /* re-initialize the skin buffer before we start reloading skins */
+ skin_buffer_init();
#ifdef HAVE_LCD_BITMAP
/* fonts need to be loaded before the WPS */