summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
Diffstat (limited to 'apps')
-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
84gui/yesno.c 84gui/yesno.c
85gui/viewport.c 85gui/viewport.c
86 86
87gui/skin_engine/skin_buffer.c
87gui/skin_engine/wps_debug.c 88gui/skin_engine/wps_debug.c
88gui/skin_engine/skin_display.c 89gui/skin_engine/skin_display.c
89gui/skin_engine/wps_parser.c 90gui/skin_engine/skin_parser.c
90gui/skin_engine/skin_tokens.c 91gui/skin_engine/skin_tokens.c
91 92
92#if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)) 93#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 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: wps_parser.c 19880 2009-01-29 20:49:43Z mcuelenaere $
9 *
10 * Copyright (C) 2002 by Linus Nielsen Feltzing
11 * Copyright (C) 2009 Jonathan Gordon
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 ****************************************************************************/
22
23#include <stdio.h>
24#include <string.h>
25#include <stdlib.h>
26#include "config.h"
27#include "buffer.h"
28#include "settings.h"
29#include "screen_access.h"
30
31/* skin buffer management.
32 * This module is used to allocate space in a single global skin buffer for
33 * tokens for both/all screens.
34 *
35 * This is mostly just copy/paste from firmware/buffer.c
36 */
37
38#define IMG_BUFSIZE (((LCD_HEIGHT*LCD_WIDTH*LCD_DEPTH/8) \
39 + (2*LCD_HEIGHT*LCD_WIDTH/8)) * NB_SCREENS)
40
41static unsigned char buffer_start[IMG_BUFSIZE], *buffer_pos = NULL;
42static size_t buf_size = IMG_BUFSIZE;
43
44void skin_buffer_init(void)
45{
46#if 0 /* this will go in again later probably */
47 if (buffer_start == NULL)
48 {
49 buf_size = IMG_BUFSIZE;/* global_settings.skin_buf_size */
50
51 buffer_start = buffer_alloc(buf_size);
52 buffer_pos = buffer_start;
53 }
54 else
55#endif
56 {
57 /* reset the buffer.... */
58 buffer_pos = buffer_start;
59 }
60}
61
62/* get the number of bytes currently being used */
63size_t skin_buffer_usage(void)
64{
65 return buffer_pos-buffer_start;
66}
67
68/* Allocate size bytes from the buffer */
69void* skin_buffer_alloc(size_t size)
70{
71 void* retval = buffer_pos;
72 if (skin_buffer_usage()+size >= buf_size)
73 {
74 return NULL;
75 }
76 buffer_pos += size;
77 /* 32-bit aligned */
78 buffer_pos = (void *)(((unsigned long)buffer_pos + 3) & ~3);
79 return retval;
80}
81
82/* Get a pointer to the skin buffer and the count of how much is free
83 * used to do your own buffer management.
84 * Any memory used will be overwritten next time wps_buffer_alloc()
85 * is called unless skin_buffer_increment() is called first
86 */
87void* skin_buffer_grab(size_t *freespace)
88{
89 *freespace = buf_size - skin_buffer_usage();
90 return buffer_pos;
91}
92
93/* Use after skin_buffer_grab() to specify how much buffer was used */
94void skin_buffer_increment(size_t used)
95{
96 buffer_pos += used;
97 /* 32-bit aligned */
98 buffer_pos = (void *)(((unsigned long)buffer_pos + 3) & ~3);
99}
100
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 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: wps_parser.c 19880 2009-01-29 20:49:43Z mcuelenaere $
9 *
10 * Copyright (C) 2002 by Linus Nielsen Feltzing
11 * Copyright (C) 2009 Jonathan Gordon
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 ****************************************************************************/
22
23#ifndef _SKIN_BUFFER_H_
24#define _SKIN_BUFFER_H_
25
26
27#include <stdio.h>
28#include <string.h>
29#include <stdlib.h>
30
31/* int the global buffer */
32void skin_buffer_init(void);
33
34/* get the number of bytes currently being used */
35size_t skin_buffer_usage(void);
36
37/* Allocate size bytes from the buffer */
38void* skin_buffer_alloc(size_t size);
39
40
41/* Get a pointer to the skin buffer and the count of how much is free
42 * used to do your own buffer management.
43 * Any memory used will be overwritten next time wps_buffer_alloc()
44 * is called unless skin_buffer_increment() is called first
45 */
46void* skin_buffer_grab(size_t *freespace);
47
48/* Use after skin_buffer_grab() to specify how much buffer was used */
49void skin_buffer_increment(size_t used);
50
51#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 @@
68static bool skin_redraw(struct gui_wps *gwps, unsigned refresh_mode); 68static bool skin_redraw(struct gui_wps *gwps, unsigned refresh_mode);
69 69
70 70
71#ifdef HAVE_LCD_BITMAP
72/* Clear the WPS image cache */
73static void wps_images_clear(struct wps_data *data)
74{
75 int i;
76 /* set images to unloaded and not displayed */
77 for (i = 0; i < MAX_IMAGES; i++)
78 {
79 data->img[i].loaded = false;
80 data->img[i].display = -1;
81 data->img[i].always_display = false;
82 data->img[i].num_subimages = 1;
83 }
84}
85#endif
86
87/* initial setup of wps_data */ 71/* initial setup of wps_data */
88void skin_data_init(struct wps_data *wps_data) 72void skin_data_init(struct wps_data *wps_data)
89{ 73{
90#ifdef HAVE_LCD_BITMAP 74#ifdef HAVE_LCD_BITMAP
91 wps_images_clear(wps_data);
92 wps_data->wps_sb_tag = false; 75 wps_data->wps_sb_tag = false;
93 wps_data->show_sb_on_wps = false; 76 wps_data->show_sb_on_wps = false;
94 wps_data->img_buf_ptr = wps_data->img_buf; /* where in image buffer */
95 wps_data->img_buf_free = IMG_BUFSIZE; /* free space in image buffer */
96 wps_data->peak_meter_enabled = false; 77 wps_data->peak_meter_enabled = false;
78 wps_data->images = NULL;
79 wps_data->progressbars = NULL;
97 /* progress bars */ 80 /* progress bars */
98 wps_data->progressbar_count = 0;
99#else /* HAVE_LCD_CHARCELLS */ 81#else /* HAVE_LCD_CHARCELLS */
100 int i; 82 int i;
101 for (i = 0; i < 8; i++) 83 for (i = 0; i < 8; i++)
@@ -191,41 +173,38 @@ static void draw_progressbar(struct gui_wps *gwps,
191} 173}
192 174
193/* clears the area where the image was shown */ 175/* clears the area where the image was shown */
194static void clear_image_pos(struct gui_wps *gwps, int n) 176static void clear_image_pos(struct gui_wps *gwps, struct gui_img *img)
195{ 177{
196 if(!gwps) 178 if(!gwps)
197 return; 179 return;
198 struct wps_data *data = gwps->data;
199 gwps->display->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); 180 gwps->display->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
200 gwps->display->fillrect(data->img[n].x, data->img[n].y, 181 gwps->display->fillrect(img->x, img->y, img->bm.width, img->subimage_height);
201 data->img[n].bm.width, data->img[n].subimage_height);
202 gwps->display->set_drawmode(DRMODE_SOLID); 182 gwps->display->set_drawmode(DRMODE_SOLID);
203} 183}
204 184
205static void wps_draw_image(struct gui_wps *gwps, int n, int subimage) 185static void wps_draw_image(struct gui_wps *gwps, struct gui_img *img, int subimage)
206{ 186{
207 struct screen *display = gwps->display; 187 struct screen *display = gwps->display;
208 struct wps_data *data = gwps->data; 188 if(img->always_display)
209 if(data->img[n].always_display)
210 display->set_drawmode(DRMODE_FG); 189 display->set_drawmode(DRMODE_FG);
211 else 190 else
212 display->set_drawmode(DRMODE_SOLID); 191 display->set_drawmode(DRMODE_SOLID);
213 192
214#if LCD_DEPTH > 1 193#if LCD_DEPTH > 1
215 if(data->img[n].bm.format == FORMAT_MONO) { 194 if(img->bm.format == FORMAT_MONO) {
216#endif 195#endif
217 display->mono_bitmap_part(data->img[n].bm.data, 196 display->mono_bitmap_part(img->bm.data,
218 0, data->img[n].subimage_height * subimage, 197 0, img->subimage_height * subimage,
219 data->img[n].bm.width, data->img[n].x, 198 img->bm.width, img->x,
220 data->img[n].y, data->img[n].bm.width, 199 img->y, img->bm.width,
221 data->img[n].subimage_height); 200 img->subimage_height);
222#if LCD_DEPTH > 1 201#if LCD_DEPTH > 1
223 } else { 202 } else {
224 display->transparent_bitmap_part((fb_data *)data->img[n].bm.data, 203 display->transparent_bitmap_part((fb_data *)img->bm.data,
225 0, data->img[n].subimage_height * subimage, 204 0, img->subimage_height * subimage,
226 data->img[n].bm.width, data->img[n].x, 205 img->bm.width, img->x,
227 data->img[n].y, data->img[n].bm.width, 206 img->y, img->bm.width,
228 data->img[n].subimage_height); 207 img->subimage_height);
229 } 208 }
230#endif 209#endif
231} 210}
@@ -235,22 +214,25 @@ static void wps_display_images(struct gui_wps *gwps, struct viewport* vp)
235 if(!gwps || !gwps->data || !gwps->display) 214 if(!gwps || !gwps->data || !gwps->display)
236 return; 215 return;
237 216
238 int n;
239 struct wps_data *data = gwps->data; 217 struct wps_data *data = gwps->data;
240 struct screen *display = gwps->display; 218 struct screen *display = gwps->display;
219 struct skin_token_list *list = data->images;
241 220
242 for (n = 0; n < MAX_IMAGES; n++) 221 while (list)
243 { 222 {
244 if (data->img[n].loaded) 223 struct gui_img *img = (struct gui_img*)list->token->value.data;
224 if (img->loaded)
245 { 225 {
246 if (data->img[n].display >= 0) 226 if (img->display >= 0)
247 { 227 {
248 wps_draw_image(gwps, n, data->img[n].display); 228 wps_draw_image(gwps, img, img->display);
249 } else if (data->img[n].always_display && data->img[n].vp == vp) 229 }
230 else if (img->always_display && img->vp == vp)
250 { 231 {
251 wps_draw_image(gwps, n, 0); 232 wps_draw_image(gwps, img, 0);
252 } 233 }
253 } 234 }
235 list = list->next;
254 } 236 }
255 display->set_drawmode(DRMODE_SOLID); 237 display->set_drawmode(DRMODE_SOLID);
256} 238}
@@ -484,7 +466,7 @@ static bool evaluate_conditional(struct gui_wps *gwps, int *token_index)
484#ifdef HAVE_LCD_BITMAP 466#ifdef HAVE_LCD_BITMAP
485 /* clear all pictures in the conditional and nested ones */ 467 /* clear all pictures in the conditional and nested ones */
486 if (data->tokens[i].type == WPS_TOKEN_IMAGE_PRELOAD_DISPLAY) 468 if (data->tokens[i].type == WPS_TOKEN_IMAGE_PRELOAD_DISPLAY)
487 clear_image_pos(gwps, data->tokens[i].value.i & 0xFF); 469 clear_image_pos(gwps, find_image(data->tokens[i].value.i&0xFF, gwps->data));
488#endif 470#endif
489#ifdef HAVE_ALBUMART 471#ifdef HAVE_ALBUMART
490 if (data->tokens[i].type == WPS_TOKEN_ALBUMART_DISPLAY) 472 if (data->tokens[i].type == WPS_TOKEN_ALBUMART_DISPLAY)
@@ -494,7 +476,20 @@ static bool evaluate_conditional(struct gui_wps *gwps, int *token_index)
494 476
495 return true; 477 return true;
496} 478}
497 479struct gui_img* find_image(int n, struct wps_data *data)
480{
481 struct skin_token_list *list = data->images;
482 while (list)
483 {
484 struct gui_img *img = (struct gui_img *)list->token->value.data;
485 if (img->id == n)
486 return img;
487 list = list->next;
488 }
489 return NULL;
490}
491
492
498/* Read a (sub)line to the given alignment format buffer. 493/* Read a (sub)line to the given alignment format buffer.
499 linebuf is the buffer where the data is actually stored. 494 linebuf is the buffer where the data is actually stored.
500 align is the alignment format that'll be used to display the text. 495 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,
544#ifdef HAVE_LCD_BITMAP 539#ifdef HAVE_LCD_BITMAP
545 case WPS_TOKEN_IMAGE_PRELOAD_DISPLAY: 540 case WPS_TOKEN_IMAGE_PRELOAD_DISPLAY:
546 { 541 {
547 struct gui_img *img = data->img;
548 int n = data->tokens[i].value.i & 0xFF; 542 int n = data->tokens[i].value.i & 0xFF;
549 int subimage = data->tokens[i].value.i >> 8; 543 int subimage = data->tokens[i].value.i >> 8;
544 struct gui_img *img = find_image(n, data);
550 545
551 if (n >= 0 && n < MAX_IMAGES && img[n].loaded) 546 if (img && img->loaded)
552 img[n].display = subimage; 547 img->display = subimage;
553 break; 548 break;
554 } 549 }
555#endif 550#endif
@@ -992,9 +987,12 @@ static bool skin_redraw(struct gui_wps *gwps, unsigned refresh_mode)
992 987
993#ifdef HAVE_LCD_BITMAP 988#ifdef HAVE_LCD_BITMAP
994 /* Set images to not to be displayed */ 989 /* Set images to not to be displayed */
995 for (i = 0; i < MAX_IMAGES; i++) 990 struct skin_token_list *imglist = data->images;
991 while (imglist)
996 { 992 {
997 data->img[i].display = -1; 993 struct gui_img *img = (struct gui_img *)imglist->token->value.data;
994 img->display = -1;
995 imglist = imglist->next;
998 } 996 }
999#endif 997#endif
1000 /* dont redraw the viewport if its disabled */ 998 /* 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 @@
23#ifndef _SKIN_ENGINE_H 23#ifndef _SKIN_ENGINE_H
24#define _SKIN_ENGINE_H 24#define _SKIN_ENGINE_H
25 25
26#include "skin_buffer.h"
27
26#include "wps_internals.h" /* TODO: remove this line.. shoudlnt be needed */ 28#include "wps_internals.h" /* TODO: remove this line.. shoudlnt be needed */
27 29
28 30
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[] = {
355 /* the array MUST end with an empty string (first char is \0) */ 355 /* the array MUST end with an empty string (first char is \0) */
356}; 356};
357 357
358
359/* add a wpsll item to the list chain. ALWAYS appended because some of the
360 * chains require the order to be kept.
361 */
362static void add_to_ll_chain(struct skin_token_list **list, struct skin_token_list *item)
363{
364 if (*list == NULL)
365 *list = item;
366 else
367 {
368 struct skin_token_list *t = *list;
369 while (t->next)
370 t = t->next;
371 t->next = item;
372 }
373}
374/* create and init a new wpsll item.
375 * passing NULL to token will alloc a new one.
376 */
377static struct skin_token_list *new_skin_token_list_item(struct wps_token *token,
378 void* token_data)
379{
380 struct skin_token_list *llitem = skin_buffer_alloc(sizeof(struct skin_token_list));
381 if (!token)
382 token = skin_buffer_alloc(sizeof(struct wps_token));
383 if (!llitem || !token)
384 return NULL;
385 llitem->next = NULL;
386 llitem->token = token;
387 if (token_data)
388 llitem->token->value.data = token_data;
389 return llitem;
390}
391
358/* Returns the number of chars that should be skipped to jump 392/* Returns the number of chars that should be skipped to jump
359 immediately after the first eol, i.e. to the start of the next line */ 393 immediately after the first eol, i.e. to the start of the next line */
360static int skip_end_of_line(const char *wps_bufptr) 394static int skip_end_of_line(const char *wps_bufptr)
@@ -406,37 +440,6 @@ static int parse_statusbar_disable(const char *wps_bufptr,
406 return skip_end_of_line(wps_bufptr); 440 return skip_end_of_line(wps_bufptr);
407} 441}
408 442
409static bool load_bitmap(struct wps_data *wps_data,
410 char* filename,
411 struct bitmap *bm)
412{
413 int format;
414#ifdef HAVE_REMOTE_LCD
415 if (wps_data->remote_wps)
416 format = FORMAT_ANY|FORMAT_REMOTE;
417 else
418#endif
419 format = FORMAT_ANY|FORMAT_TRANSPARENT;
420
421 int ret = read_bmp_file(filename, bm,
422 wps_data->img_buf_free,
423 format,NULL);
424
425 if (ret > 0)
426 {
427#if LCD_DEPTH == 16
428 if (ret % 2) ret++;
429 /* Always consume an even number of bytes */
430#endif
431 wps_data->img_buf_ptr += ret;
432 wps_data->img_buf_free -= ret;
433
434 return true;
435 }
436 else
437 return false;
438}
439
440static int get_image_id(int c) 443static int get_image_id(int c)
441{ 444{
442 if(c >= 'a' && c <= 'z') 445 if(c >= 'a' && c <= 'z')
@@ -472,9 +475,9 @@ static int parse_image_display(const char *wps_bufptr,
472 struct wps_token *token, 475 struct wps_token *token,
473 struct wps_data *wps_data) 476 struct wps_data *wps_data)
474{ 477{
475 (void)wps_data;
476 int n = get_image_id(wps_bufptr[0]); 478 int n = get_image_id(wps_bufptr[0]);
477 int subimage; 479 int subimage;
480 struct gui_img *img;;
478 481
479 if (n == -1) 482 if (n == -1)
480 { 483 {
@@ -484,8 +487,9 @@ static int parse_image_display(const char *wps_bufptr,
484 487
485 if ((subimage = get_image_id(wps_bufptr[1])) != -1) 488 if ((subimage = get_image_id(wps_bufptr[1])) != -1)
486 { 489 {
490 img = find_image(n, wps_data);
487 /* Sanity check */ 491 /* Sanity check */
488 if (subimage >= wps_data->img[n].num_subimages) 492 if (!img || subimage >= img->num_subimages)
489 return WPS_ERROR_INVALID_PARAM; 493 return WPS_ERROR_INVALID_PARAM;
490 494
491 /* Store sub-image number to display in high bits */ 495 /* Store sub-image number to display in high bits */
@@ -508,6 +512,7 @@ static int parse_image_load(const char *wps_bufptr,
508 const char* id; 512 const char* id;
509 const char *newline; 513 const char *newline;
510 int x,y; 514 int x,y;
515 struct gui_img *img;
511 516
512 /* format: %x|n|filename.bmp|x|y| 517 /* format: %x|n|filename.bmp|x|y|
513 or %xl|n|filename.bmp|x|y| 518 or %xl|n|filename.bmp|x|y|
@@ -530,24 +535,28 @@ static int parse_image_load(const char *wps_bufptr,
530 n = get_image_id(*id); 535 n = get_image_id(*id);
531 536
532 /* check the image number and load state */ 537 /* check the image number and load state */
533 if(n < 0 || n >= MAX_IMAGES || wps_data->img[n].loaded) 538 if(n < 0 || find_image(n, wps_data))
534 { 539 {
535 /* Invalid image ID */ 540 /* Invalid image ID */
536 return WPS_ERROR_INVALID_PARAM; 541 return WPS_ERROR_INVALID_PARAM;
537 } 542 }
538 543 img = skin_buffer_alloc(sizeof(struct gui_img));
544 if (!img)
545 return WPS_ERROR_INVALID_PARAM;
539 /* save a pointer to the filename */ 546 /* save a pointer to the filename */
540 bmp_names[n] = filename; 547 img->bm.data = (char*)filename;
541 548 img->id = n;
542 wps_data->img[n].x = x; 549 img->x = x;
543 wps_data->img[n].y = y; 550 img->y = y;
551 img->num_subimages = 1;
552 img->always_display = false;
544 553
545 /* save current viewport */ 554 /* save current viewport */
546 wps_data->img[n].vp = &wps_data->viewports[wps_data->num_viewports].vp; 555 img->vp = &wps_data->viewports[wps_data->num_viewports].vp;
547 556
548 if (token->type == WPS_TOKEN_IMAGE_DISPLAY) 557 if (token->type == WPS_TOKEN_IMAGE_DISPLAY)
549 { 558 {
550 wps_data->img[n].always_display = true; 559 img->always_display = true;
551 } 560 }
552 else 561 else
553 { 562 {
@@ -556,11 +565,15 @@ static int parse_image_load(const char *wps_bufptr,
556 newline = strchr(ptr, '\n'); 565 newline = strchr(ptr, '\n');
557 pos = strchr(ptr, '|'); 566 pos = strchr(ptr, '|');
558 if (pos && pos < newline) 567 if (pos && pos < newline)
559 wps_data->img[n].num_subimages = atoi(ptr); 568 img->num_subimages = atoi(ptr);
560 569
561 if (wps_data->img[n].num_subimages <= 0) 570 if (img->num_subimages <= 0)
562 return WPS_ERROR_INVALID_PARAM; 571 return WPS_ERROR_INVALID_PARAM;
563 } 572 }
573 struct skin_token_list *item = new_skin_token_list_item(NULL, img);
574 if (!item)
575 return WPS_ERROR_INVALID_PARAM;
576 add_to_ll_chain(&wps_data->images, item);
564 577
565 /* Skip the rest of the line */ 578 /* Skip the rest of the line */
566 return skip_end_of_line(wps_bufptr); 579 return skip_end_of_line(wps_bufptr);
@@ -781,7 +794,6 @@ static int parse_progressbar(const char *wps_bufptr,
781 struct wps_token *token, 794 struct wps_token *token,
782 struct wps_data *wps_data) 795 struct wps_data *wps_data)
783{ 796{
784 (void)token; /* Kill warnings */
785 /* %pb or %pb|filename|x|y|width|height| 797 /* %pb or %pb|filename|x|y|width|height|
786 using - for any of the params uses "sane" values */ 798 using - for any of the params uses "sane" values */
787#ifdef HAVE_LCD_BITMAP 799#ifdef HAVE_LCD_BITMAP
@@ -796,7 +808,12 @@ static int parse_progressbar(const char *wps_bufptr,
796 int x, y, height, width; 808 int x, y, height, width;
797 uint32_t set = 0; 809 uint32_t set = 0;
798 const char *ptr = wps_bufptr; 810 const char *ptr = wps_bufptr;
799 struct progressbar *pb; 811 struct progressbar *pb = skin_buffer_alloc(sizeof(struct progressbar));
812 struct skin_token_list *item = new_skin_token_list_item(token, pb);
813
814 if (!pb || !item)
815 return WPS_ERROR_INVALID_PARAM;
816
800 struct viewport *vp = &wps_data->viewports[wps_data->num_viewports].vp; 817 struct viewport *vp = &wps_data->viewports[wps_data->num_viewports].vp;
801#ifndef __PCTOOL__ 818#ifndef __PCTOOL__
802 int font_height = font_get(vp->font)->height; 819 int font_height = font_get(vp->font)->height;
@@ -806,11 +823,8 @@ static int parse_progressbar(const char *wps_bufptr,
806 int line_num = wps_data->num_lines - 823 int line_num = wps_data->num_lines -
807 wps_data->viewports[wps_data->num_viewports].first_line; 824 wps_data->viewports[wps_data->num_viewports].first_line;
808 825
809 if (wps_data->progressbar_count >= MAX_PROGRESSBARS)
810 return WPS_ERROR_INVALID_PARAM;
811
812 pb = &wps_data->progressbar[wps_data->progressbar_count];
813 pb->have_bitmap_pb = false; 826 pb->have_bitmap_pb = false;
827 pb->bm.data = NULL; /* no bitmap specified */
814 828
815 if (*wps_bufptr != '|') /* regular old style */ 829 if (*wps_bufptr != '|') /* regular old style */
816 { 830 {
@@ -820,7 +834,7 @@ static int parse_progressbar(const char *wps_bufptr,
820 pb->y = -line_num - 1; /* Will be computed during the rendering */ 834 pb->y = -line_num - 1; /* Will be computed during the rendering */
821 835
822 wps_data->viewports[wps_data->num_viewports].pb = pb; 836 wps_data->viewports[wps_data->num_viewports].pb = pb;
823 wps_data->progressbar_count++; 837 add_to_ll_chain(&wps_data->progressbars, item);
824 return 0; 838 return 0;
825 } 839 }
826 ptr = wps_bufptr + 1; 840 ptr = wps_bufptr + 1;
@@ -830,7 +844,7 @@ static int parse_progressbar(const char *wps_bufptr,
830 return WPS_ERROR_INVALID_PARAM; 844 return WPS_ERROR_INVALID_PARAM;
831 845
832 if (LIST_VALUE_PARSED(set, PB_FILENAME)) /* filename */ 846 if (LIST_VALUE_PARSED(set, PB_FILENAME)) /* filename */
833 bmp_names[PROGRESSBAR_BMP+wps_data->progressbar_count] = filename; 847 pb->bm.data = (char*)filename;
834 848
835 if (LIST_VALUE_PARSED(set, PB_X)) /* x */ 849 if (LIST_VALUE_PARSED(set, PB_X)) /* x */
836 pb->x = x; 850 pb->x = x;
@@ -865,7 +879,7 @@ static int parse_progressbar(const char *wps_bufptr,
865 pb->y = -line_num - 1; /* Will be computed during the rendering */ 879 pb->y = -line_num - 1; /* Will be computed during the rendering */
866 880
867 wps_data->viewports[wps_data->num_viewports].pb = pb; 881 wps_data->viewports[wps_data->num_viewports].pb = pb;
868 wps_data->progressbar_count++; 882 add_to_ll_chain(&wps_data->progressbars, item);
869 883
870 /* Skip the rest of the line */ 884 /* Skip the rest of the line */
871 return skip_end_of_line(wps_bufptr)-1; 885 return skip_end_of_line(wps_bufptr)-1;
@@ -1250,9 +1264,6 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr)
1250{ 1264{
1251 if (!data || !wps_bufptr || !*wps_bufptr) 1265 if (!data || !wps_bufptr || !*wps_bufptr)
1252 return false; 1266 return false;
1253
1254 char *stringbuf = data->string_buffer;
1255 int stringbuf_used = 0;
1256 enum wps_parse_error fail = PARSE_OK; 1267 enum wps_parse_error fail = PARSE_OK;
1257 int ret; 1268 int ret;
1258 line = 1; 1269 line = 1;
@@ -1404,42 +1415,45 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr)
1404 } 1415 }
1405 1416
1406 /* look if we already have that string */ 1417 /* look if we already have that string */
1407 char **str; 1418 char *str;
1408 int i; 1419 bool found = false;
1409 bool found; 1420 struct skin_token_list *list = data->strings;
1410 for (i = 0, str = data->strings, found = false; 1421 while (list)
1411 i < data->num_strings && 1422 {
1412 !(found = (strlen(*str) == len && 1423 str = (char*)list->token->value.data;
1413 strncmp(string_start, *str, len) == 0)); 1424 found = (strlen(str) == len &&
1414 i++, str++); 1425 strncmp(string_start, str, len) == 0);
1426 if (found)
1427 break; /* break here because the list item is
1428 used if its found */
1429 list = list->next;
1430 }
1415 /* If a matching string is found, found is true and i is 1431 /* If a matching string is found, found is true and i is
1416 the index of the string. If not, found is false */ 1432 the index of the string. If not, found is false */
1417 1433
1418 if (!found) 1434 if (!found)
1419 { 1435 {
1420 /* new string */ 1436 /* new string */
1421 1437 str = (char*)skin_buffer_alloc(len+1);
1422 if (stringbuf_used + len > STRING_BUFFER_SIZE - 1 1438 if (!str)
1423 || data->num_strings >= WPS_MAX_STRINGS) 1439 {
1424 { 1440 fail = PARSE_FAIL_LIMITS_EXCEEDED;
1425 /* too many strings or characters */ 1441 break;
1426 fail = PARSE_FAIL_LIMITS_EXCEEDED;
1427 break;
1428 } 1442 }
1429 1443 strlcpy(str, string_start, len+1);
1430 strlcpy(stringbuf, string_start, len+1); 1444 struct skin_token_list *item =
1431 1445 new_skin_token_list_item(&data->tokens[data->num_tokens], str);
1432 data->strings[data->num_strings] = stringbuf; 1446 if(!item)
1433 stringbuf += len + 1; 1447 {
1434 stringbuf_used += len + 1; 1448 fail = PARSE_FAIL_LIMITS_EXCEEDED;
1435 data->tokens[data->num_tokens].value.i = 1449 break;
1436 data->num_strings; 1450 }
1437 data->num_strings++; 1451 add_to_ll_chain(&data->strings, item);
1438 } 1452 }
1439 else 1453 else
1440 { 1454 {
1441 /* another occurrence of an existing string */ 1455 /* another occurrence of an existing string */
1442 data->tokens[data->num_tokens].value.i = i; 1456 data->tokens[data->num_tokens].value.data = list->token->value.data;
1443 } 1457 }
1444 data->tokens[data->num_tokens].type = WPS_TOKEN_STRING; 1458 data->tokens[data->num_tokens].type = WPS_TOKEN_STRING;
1445 data->num_tokens++; 1459 data->num_tokens++;
@@ -1480,54 +1494,75 @@ static void wps_reset(struct wps_data *data)
1480} 1494}
1481 1495
1482#ifdef HAVE_LCD_BITMAP 1496#ifdef HAVE_LCD_BITMAP
1497static bool load_skin_bmp(struct wps_data *wps_data, struct bitmap *bitmap, char* bmpdir)
1498{
1499 (void)wps_data; /* only needed for remote targets */
1500 bool loaded = false;
1501 char img_path[MAX_PATH];
1502 get_image_filename(bitmap->data, bmpdir,
1503 img_path, sizeof(img_path));
1504
1505 /* load the image */
1506 int format;
1507#ifdef HAVE_REMOTE_LCD
1508 if (wps_data->remote_wps)
1509 format = FORMAT_ANY|FORMAT_REMOTE;
1510 else
1511#endif
1512 format = FORMAT_ANY|FORMAT_TRANSPARENT;
1513
1514 size_t max_buf;
1515 char* imgbuf = (char*)skin_buffer_grab(&max_buf);
1516 bitmap->data = imgbuf;
1517 int ret = read_bmp_file(img_path, bitmap, max_buf, format, NULL);
1518
1519 if (ret > 0)
1520 {
1521 skin_buffer_increment(ret);
1522 loaded = true;
1523 }
1524 else
1525 {
1526 /* Abort if we can't load an image */
1527 DEBUGF("ERR: Failed to load image - %s\n",img_path);
1528 loaded = false;
1529 }
1530 return loaded;
1531}
1483 1532
1484static bool load_skin_bitmaps(struct wps_data *wps_data, char *bmpdir) 1533static bool load_skin_bitmaps(struct wps_data *wps_data, char *bmpdir)
1485{ 1534{
1486 char img_path[MAX_PATH]; 1535 struct skin_token_list *list;
1487 struct bitmap *bitmap; 1536 /* do the progressbars */
1488 bool *loaded; 1537 list = wps_data->progressbars;
1489 int n; 1538 while (list)
1490 for (n = 0; n < BACKDROP_BMP; n++)
1491 { 1539 {
1492 if (bmp_names[n]) 1540 struct progressbar *pb = (struct progressbar*)list->token->value.data;
1541 if (pb->bm.data)
1493 { 1542 {
1494 get_image_filename(bmp_names[n], bmpdir, 1543 pb->have_bitmap_pb = load_skin_bmp(wps_data, &pb->bm, bmpdir);
1495 img_path, sizeof(img_path)); 1544 }
1496 1545 list = list->next;
1497 if (n >= PROGRESSBAR_BMP ) { 1546 }
1498 /* progressbar bitmap */ 1547 /* regular images */
1499 bitmap = &wps_data->progressbar[n-PROGRESSBAR_BMP].bm; 1548 list = wps_data->images;
1500 loaded = &wps_data->progressbar[n-PROGRESSBAR_BMP].have_bitmap_pb; 1549 while (list)
1501 } else { 1550 {
1502 /* regular bitmap */ 1551 struct gui_img *img = (struct gui_img*)list->token->value.data;
1503 bitmap = &wps_data->img[n].bm; 1552 if (img->bm.data)
1504 loaded = &wps_data->img[n].loaded; 1553 {
1505 } 1554 img->loaded = load_skin_bmp(wps_data, &img->bm, bmpdir);
1506 1555 if (img->loaded)
1507 /* load the image */ 1556 img->subimage_height = img->bm.height / img->num_subimages;
1508 bitmap->data = wps_data->img_buf_ptr;
1509 if (load_bitmap(wps_data, img_path, bitmap))
1510 {
1511 *loaded = true;
1512
1513 /* Calculate and store height if this image has sub-images */
1514 if (n < MAX_IMAGES)
1515 wps_data->img[n].subimage_height = wps_data->img[n].bm.height /
1516 wps_data->img[n].num_subimages;
1517 }
1518 else
1519 {
1520 /* Abort if we can't load an image */
1521 DEBUGF("ERR: Failed to load image %d - %s\n",n,img_path);
1522 return false;
1523 }
1524 } 1557 }
1558 list = list->next;
1525 } 1559 }
1526 1560
1527#if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)) 1561#if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1))
1528 if (bmp_names[BACKDROP_BMP]) 1562 if (bmp_names[BACKDROP_BMP])
1529 { 1563 {
1530 int screen = SCREEN_MAIN; 1564 int screen = SCREEN_MAIN;
1565 char img_path[MAX_PATH];
1531 get_image_filename(bmp_names[BACKDROP_BMP], bmpdir, 1566 get_image_filename(bmp_names[BACKDROP_BMP], bmpdir,
1532 img_path, sizeof(img_path)); 1567 img_path, sizeof(img_path));
1533#if defined(HAVE_REMOTE_LCD) 1568#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,
167 return &(token->value.c); 167 return &(token->value.c);
168 168
169 case WPS_TOKEN_STRING: 169 case WPS_TOKEN_STRING:
170 return data->strings[token->value.i]; 170 return (char*)token->value.data;
171 171
172 case WPS_TOKEN_TRACK_TIME_ELAPSED: 172 case WPS_TOKEN_TRACK_TIME_ELAPSED:
173 format_time(buf, buf_size, 173 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 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: wps_internals.h 22223 2009-08-09 17:30:05Z jdgordon $
9 *
10 * Copyright (C) 2007 Nicolas Pennequin
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#ifndef _SKIN_TOKENS_H_
23#define _SKIN_TOKENS_H_
24
25#include <stdbool.h>
26
27
28enum wps_token_type {
29 WPS_NO_TOKEN, /* for WPS tags we don't want to save as tokens */
30 WPS_TOKEN_UNKNOWN,
31
32 /* Markers */
33 WPS_TOKEN_CHARACTER,
34 WPS_TOKEN_STRING,
35
36 /* Alignment */
37 WPS_TOKEN_ALIGN_LEFT,
38 WPS_TOKEN_ALIGN_CENTER,
39 WPS_TOKEN_ALIGN_RIGHT,
40
41 /* Sublines */
42 WPS_TOKEN_SUBLINE_TIMEOUT,
43
44 /* Battery */
45 WPS_TOKEN_BATTERY_PERCENT,
46 WPS_TOKEN_BATTERY_VOLTS,
47 WPS_TOKEN_BATTERY_TIME,
48 WPS_TOKEN_BATTERY_CHARGER_CONNECTED,
49 WPS_TOKEN_BATTERY_CHARGING,
50 WPS_TOKEN_BATTERY_SLEEPTIME,
51
52 /* Sound */
53#if (CONFIG_CODEC != MAS3507D)
54 WPS_TOKEN_SOUND_PITCH,
55#endif
56#if (CONFIG_CODEC == SWCODEC)
57 WPS_TOKEN_REPLAYGAIN,
58 WPS_TOKEN_CROSSFADE,
59#endif
60
61 /* Time */
62
63 WPS_TOKEN_RTC_PRESENT,
64
65 /* The begin/end values allow us to know if a token is an RTC one.
66 New RTC tokens should be added between the markers. */
67
68 WPS_TOKENS_RTC_BEGIN, /* just the start marker, not an actual token */
69
70 WPS_TOKEN_RTC_DAY_OF_MONTH,
71 WPS_TOKEN_RTC_DAY_OF_MONTH_BLANK_PADDED,
72 WPS_TOKEN_RTC_12HOUR_CFG,
73 WPS_TOKEN_RTC_HOUR_24_ZERO_PADDED,
74 WPS_TOKEN_RTC_HOUR_24,
75 WPS_TOKEN_RTC_HOUR_12_ZERO_PADDED,
76 WPS_TOKEN_RTC_HOUR_12,
77 WPS_TOKEN_RTC_MONTH,
78 WPS_TOKEN_RTC_MINUTE,
79 WPS_TOKEN_RTC_SECOND,
80 WPS_TOKEN_RTC_YEAR_2_DIGITS,
81 WPS_TOKEN_RTC_YEAR_4_DIGITS,
82 WPS_TOKEN_RTC_AM_PM_UPPER,
83 WPS_TOKEN_RTC_AM_PM_LOWER,
84 WPS_TOKEN_RTC_WEEKDAY_NAME,
85 WPS_TOKEN_RTC_MONTH_NAME,
86 WPS_TOKEN_RTC_DAY_OF_WEEK_START_MON,
87 WPS_TOKEN_RTC_DAY_OF_WEEK_START_SUN,
88
89 WPS_TOKENS_RTC_END, /* just the end marker, not an actual token */
90
91 /* Conditional */
92 WPS_TOKEN_CONDITIONAL,
93 WPS_TOKEN_CONDITIONAL_START,
94 WPS_TOKEN_CONDITIONAL_OPTION,
95 WPS_TOKEN_CONDITIONAL_END,
96
97 /* Database */
98#ifdef HAVE_TAGCACHE
99 WPS_TOKEN_DATABASE_PLAYCOUNT,
100 WPS_TOKEN_DATABASE_RATING,
101 WPS_TOKEN_DATABASE_AUTOSCORE,
102#endif
103
104 /* File */
105 WPS_TOKEN_FILE_BITRATE,
106 WPS_TOKEN_FILE_CODEC,
107 WPS_TOKEN_FILE_FREQUENCY,
108 WPS_TOKEN_FILE_FREQUENCY_KHZ,
109 WPS_TOKEN_FILE_NAME,
110 WPS_TOKEN_FILE_NAME_WITH_EXTENSION,
111 WPS_TOKEN_FILE_PATH,
112 WPS_TOKEN_FILE_SIZE,
113 WPS_TOKEN_FILE_VBR,
114 WPS_TOKEN_FILE_DIRECTORY,
115
116#ifdef HAVE_LCD_BITMAP
117 /* Image */
118 WPS_TOKEN_IMAGE_BACKDROP,
119 WPS_TOKEN_IMAGE_PROGRESS_BAR,
120 WPS_TOKEN_IMAGE_PRELOAD,
121 WPS_TOKEN_IMAGE_PRELOAD_DISPLAY,
122 WPS_TOKEN_IMAGE_DISPLAY,
123#endif
124
125#ifdef HAVE_ALBUMART
126 /* Albumart */
127 WPS_TOKEN_ALBUMART_DISPLAY,
128 WPS_TOKEN_ALBUMART_FOUND,
129#endif
130
131 /* Metadata */
132 WPS_TOKEN_METADATA_ARTIST,
133 WPS_TOKEN_METADATA_COMPOSER,
134 WPS_TOKEN_METADATA_ALBUM_ARTIST,
135 WPS_TOKEN_METADATA_GROUPING,
136 WPS_TOKEN_METADATA_ALBUM,
137 WPS_TOKEN_METADATA_GENRE,
138 WPS_TOKEN_METADATA_DISC_NUMBER,
139 WPS_TOKEN_METADATA_TRACK_NUMBER,
140 WPS_TOKEN_METADATA_TRACK_TITLE,
141 WPS_TOKEN_METADATA_VERSION,
142 WPS_TOKEN_METADATA_YEAR,
143 WPS_TOKEN_METADATA_COMMENT,
144
145 /* Mode */
146 WPS_TOKEN_REPEAT_MODE,
147 WPS_TOKEN_PLAYBACK_STATUS,
148
149 WPS_TOKEN_MAIN_HOLD,
150
151#ifdef HAS_REMOTE_BUTTON_HOLD
152 WPS_TOKEN_REMOTE_HOLD,
153#endif
154
155 /* Progressbar */
156 WPS_TOKEN_PROGRESSBAR,
157#ifdef HAVE_LCD_CHARCELLS
158 WPS_TOKEN_PLAYER_PROGRESSBAR,
159#endif
160
161#ifdef HAVE_LCD_BITMAP
162 /* Peakmeter */
163 WPS_TOKEN_PEAKMETER,
164#endif
165
166 /* Volume level */
167 WPS_TOKEN_VOLUME,
168
169 /* Current track */
170 WPS_TOKEN_TRACK_ELAPSED_PERCENT,
171 WPS_TOKEN_TRACK_TIME_ELAPSED,
172 WPS_TOKEN_TRACK_TIME_REMAINING,
173 WPS_TOKEN_TRACK_LENGTH,
174
175 /* Playlist */
176 WPS_TOKEN_PLAYLIST_ENTRIES,
177 WPS_TOKEN_PLAYLIST_NAME,
178 WPS_TOKEN_PLAYLIST_POSITION,
179 WPS_TOKEN_PLAYLIST_SHUFFLE,
180
181#if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
182 /* Virtual LED */
183 WPS_TOKEN_VLED_HDD,
184#endif
185
186 /* Viewport display */
187 WPS_VIEWPORT_ENABLE,
188
189 /* buttons */
190 WPS_TOKEN_BUTTON_VOLUME,
191 WPS_TOKEN_LASTTOUCH,
192
193 /* Setting option */
194 WPS_TOKEN_SETTING,
195};
196
197struct wps_token {
198 unsigned char type; /* enough to store the token type */
199
200 /* Whether the tag (e.g. track name or the album) refers the
201 current or the next song (false=current, true=next) */
202 bool next;
203
204 union {
205 char c;
206 unsigned short i;
207 void* data;
208 } value;
209};
210
211struct skin_token_list {
212 struct wps_token *token;
213 struct skin_token_list *next;
214};
215
216
217#endif
218
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 @@
23 23
24#include <stdio.h> 24#include <stdio.h>
25#include <string.h> 25#include <string.h>
26#include "wps.h"
26#include "wps_internals.h" 27#include "wps_internals.h"
27#ifdef __PCTOOL__ 28#ifdef __PCTOOL__
28#ifdef WPSEDITOR 29#ifdef WPSEDITOR
@@ -548,15 +549,18 @@ static void print_line_info(struct wps_data *data)
548 DEBUGF("\n"); 549 DEBUGF("\n");
549 } 550 }
550} 551}
551 552#if 0
553/* NOTE: this is probaly not even needed anymore */
552static void print_wps_strings(struct wps_data *data) 554static void print_wps_strings(struct wps_data *data)
553{ 555{
554 int i, len, total_len = 0, buf_used = 0; 556 int i, len, total_len = 0, buf_used = 0;
555 557
556 if (wps_verbose_level > 1) DEBUGF("Strings:\n"); 558 if (wps_verbose_level > 1) DEBUGF("Strings:\n");
557 for (i = 0; i < data->num_strings; i++) 559 struct skin_token_list *strings = data->strings;
560 while (strings)
558 { 561 {
559 len = strlen(data->strings[i]); 562 char* str = (char*)strings->token->value.data;
563 len = strlen(str);
560 total_len += len; 564 total_len += len;
561 buf_used += len + 1; 565 buf_used += len + 1;
562 if (wps_verbose_level > 1) 566 if (wps_verbose_level > 1)
@@ -575,6 +579,7 @@ static void print_wps_strings(struct wps_data *data)
575 } 579 }
576} 580}
577#endif 581#endif
582#endif
578 583
579void print_debug_info(struct wps_data *data, enum wps_parse_error fail, int line) 584void print_debug_info(struct wps_data *data, enum wps_parse_error fail, int line)
580{ 585{
@@ -582,7 +587,7 @@ void print_debug_info(struct wps_data *data, enum wps_parse_error fail, int line
582 if (debug_wps && wps_verbose_level) 587 if (debug_wps && wps_verbose_level)
583 { 588 {
584 dump_wps_tokens(data); 589 dump_wps_tokens(data);
585 print_wps_strings(data); 590 /* print_wps_strings(data); */
586 print_line_info(data); 591 print_line_info(data);
587 } 592 }
588#endif /* SIMULATOR */ 593#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 @@
31#define TIMEOUT_UNIT (HZ/10) /* I.e. 0.1 sec */ 31#define TIMEOUT_UNIT (HZ/10) /* I.e. 0.1 sec */
32#define DEFAULT_SUBLINE_TIME_MULTIPLIER 20 /* In TIMEOUT_UNIT's */ 32#define DEFAULT_SUBLINE_TIME_MULTIPLIER 20 /* In TIMEOUT_UNIT's */
33 33
34 34#include "skin_tokens.h"
35 35
36 36
37/* TODO: sort this mess out */ 37/* TODO: sort this mess out */
@@ -77,6 +77,7 @@
77 77
78#ifdef HAVE_LCD_BITMAP 78#ifdef HAVE_LCD_BITMAP
79struct gui_img { 79struct gui_img {
80 short int id;
80 struct bitmap bm; 81 struct bitmap bm;
81 struct viewport* vp; /* The viewport to display this image in */ 82 struct viewport* vp; /* The viewport to display this image in */
82 short int x; /* x-pos */ 83 short int x; /* x-pos */
@@ -88,6 +89,7 @@ struct gui_img {
88 bool always_display; /* not using the preload/display mechanism */ 89 bool always_display; /* not using the preload/display mechanism */
89}; 90};
90 91
92
91struct progressbar { 93struct progressbar {
92 /* regular pb */ 94 /* regular pb */
93 short x; 95 short x;
@@ -153,187 +155,6 @@ enum wps_parse_error {
153 PARSE_FAIL_LIMITS_EXCEEDED, 155 PARSE_FAIL_LIMITS_EXCEEDED,
154}; 156};
155 157
156enum wps_token_type {
157 WPS_NO_TOKEN, /* for WPS tags we don't want to save as tokens */
158 WPS_TOKEN_UNKNOWN,
159
160 /* Markers */
161 WPS_TOKEN_CHARACTER,
162 WPS_TOKEN_STRING,
163
164 /* Alignment */
165 WPS_TOKEN_ALIGN_LEFT,
166 WPS_TOKEN_ALIGN_CENTER,
167 WPS_TOKEN_ALIGN_RIGHT,
168
169 /* Sublines */
170 WPS_TOKEN_SUBLINE_TIMEOUT,
171
172 /* Battery */
173 WPS_TOKEN_BATTERY_PERCENT,
174 WPS_TOKEN_BATTERY_VOLTS,
175 WPS_TOKEN_BATTERY_TIME,
176 WPS_TOKEN_BATTERY_CHARGER_CONNECTED,
177 WPS_TOKEN_BATTERY_CHARGING,
178 WPS_TOKEN_BATTERY_SLEEPTIME,
179
180 /* Sound */
181#if (CONFIG_CODEC != MAS3507D)
182 WPS_TOKEN_SOUND_PITCH,
183#endif
184#if (CONFIG_CODEC == SWCODEC)
185 WPS_TOKEN_REPLAYGAIN,
186 WPS_TOKEN_CROSSFADE,
187#endif
188
189 /* Time */
190
191 WPS_TOKEN_RTC_PRESENT,
192
193 /* The begin/end values allow us to know if a token is an RTC one.
194 New RTC tokens should be added between the markers. */
195
196 WPS_TOKENS_RTC_BEGIN, /* just the start marker, not an actual token */
197
198 WPS_TOKEN_RTC_DAY_OF_MONTH,
199 WPS_TOKEN_RTC_DAY_OF_MONTH_BLANK_PADDED,
200 WPS_TOKEN_RTC_12HOUR_CFG,
201 WPS_TOKEN_RTC_HOUR_24_ZERO_PADDED,
202 WPS_TOKEN_RTC_HOUR_24,
203 WPS_TOKEN_RTC_HOUR_12_ZERO_PADDED,
204 WPS_TOKEN_RTC_HOUR_12,
205 WPS_TOKEN_RTC_MONTH,
206 WPS_TOKEN_RTC_MINUTE,
207 WPS_TOKEN_RTC_SECOND,
208 WPS_TOKEN_RTC_YEAR_2_DIGITS,
209 WPS_TOKEN_RTC_YEAR_4_DIGITS,
210 WPS_TOKEN_RTC_AM_PM_UPPER,
211 WPS_TOKEN_RTC_AM_PM_LOWER,
212 WPS_TOKEN_RTC_WEEKDAY_NAME,
213 WPS_TOKEN_RTC_MONTH_NAME,
214 WPS_TOKEN_RTC_DAY_OF_WEEK_START_MON,
215 WPS_TOKEN_RTC_DAY_OF_WEEK_START_SUN,
216
217 WPS_TOKENS_RTC_END, /* just the end marker, not an actual token */
218
219 /* Conditional */
220 WPS_TOKEN_CONDITIONAL,
221 WPS_TOKEN_CONDITIONAL_START,
222 WPS_TOKEN_CONDITIONAL_OPTION,
223 WPS_TOKEN_CONDITIONAL_END,
224
225 /* Database */
226#ifdef HAVE_TAGCACHE
227 WPS_TOKEN_DATABASE_PLAYCOUNT,
228 WPS_TOKEN_DATABASE_RATING,
229 WPS_TOKEN_DATABASE_AUTOSCORE,
230#endif
231
232 /* File */
233 WPS_TOKEN_FILE_BITRATE,
234 WPS_TOKEN_FILE_CODEC,
235 WPS_TOKEN_FILE_FREQUENCY,
236 WPS_TOKEN_FILE_FREQUENCY_KHZ,
237 WPS_TOKEN_FILE_NAME,
238 WPS_TOKEN_FILE_NAME_WITH_EXTENSION,
239 WPS_TOKEN_FILE_PATH,
240 WPS_TOKEN_FILE_SIZE,
241 WPS_TOKEN_FILE_VBR,
242 WPS_TOKEN_FILE_DIRECTORY,
243
244#ifdef HAVE_LCD_BITMAP
245 /* Image */
246 WPS_TOKEN_IMAGE_BACKDROP,
247 WPS_TOKEN_IMAGE_PROGRESS_BAR,
248 WPS_TOKEN_IMAGE_PRELOAD,
249 WPS_TOKEN_IMAGE_PRELOAD_DISPLAY,
250 WPS_TOKEN_IMAGE_DISPLAY,
251#endif
252
253#ifdef HAVE_ALBUMART
254 /* Albumart */
255 WPS_TOKEN_ALBUMART_DISPLAY,
256 WPS_TOKEN_ALBUMART_FOUND,
257#endif
258
259 /* Metadata */
260 WPS_TOKEN_METADATA_ARTIST,
261 WPS_TOKEN_METADATA_COMPOSER,
262 WPS_TOKEN_METADATA_ALBUM_ARTIST,
263 WPS_TOKEN_METADATA_GROUPING,
264 WPS_TOKEN_METADATA_ALBUM,
265 WPS_TOKEN_METADATA_GENRE,
266 WPS_TOKEN_METADATA_DISC_NUMBER,
267 WPS_TOKEN_METADATA_TRACK_NUMBER,
268 WPS_TOKEN_METADATA_TRACK_TITLE,
269 WPS_TOKEN_METADATA_VERSION,
270 WPS_TOKEN_METADATA_YEAR,
271 WPS_TOKEN_METADATA_COMMENT,
272
273 /* Mode */
274 WPS_TOKEN_REPEAT_MODE,
275 WPS_TOKEN_PLAYBACK_STATUS,
276
277 WPS_TOKEN_MAIN_HOLD,
278
279#ifdef HAS_REMOTE_BUTTON_HOLD
280 WPS_TOKEN_REMOTE_HOLD,
281#endif
282
283 /* Progressbar */
284 WPS_TOKEN_PROGRESSBAR,
285#ifdef HAVE_LCD_CHARCELLS
286 WPS_TOKEN_PLAYER_PROGRESSBAR,
287#endif
288
289#ifdef HAVE_LCD_BITMAP
290 /* Peakmeter */
291 WPS_TOKEN_PEAKMETER,
292#endif
293
294 /* Volume level */
295 WPS_TOKEN_VOLUME,
296
297 /* Current track */
298 WPS_TOKEN_TRACK_ELAPSED_PERCENT,
299 WPS_TOKEN_TRACK_TIME_ELAPSED,
300 WPS_TOKEN_TRACK_TIME_REMAINING,
301 WPS_TOKEN_TRACK_LENGTH,
302
303 /* Playlist */
304 WPS_TOKEN_PLAYLIST_ENTRIES,
305 WPS_TOKEN_PLAYLIST_NAME,
306 WPS_TOKEN_PLAYLIST_POSITION,
307 WPS_TOKEN_PLAYLIST_SHUFFLE,
308
309#if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
310 /* Virtual LED */
311 WPS_TOKEN_VLED_HDD,
312#endif
313
314 /* Viewport display */
315 WPS_VIEWPORT_ENABLE,
316
317 /* buttons */
318 WPS_TOKEN_BUTTON_VOLUME,
319 WPS_TOKEN_LASTTOUCH,
320
321 /* Setting option */
322 WPS_TOKEN_SETTING,
323};
324
325struct wps_token {
326 unsigned char type; /* enough to store the token type */
327
328 /* Whether the tag (e.g. track name or the album) refers the
329 current or the next song (false=current, true=next) */
330 bool next;
331
332 union {
333 char c;
334 unsigned short i;
335 } value;
336};
337 158
338/* Description of a subline on the WPS */ 159/* Description of a subline on the WPS */
339struct wps_subline { 160struct wps_subline {
@@ -406,15 +227,11 @@ struct touchregion {
406struct wps_data 227struct wps_data
407{ 228{
408#ifdef HAVE_LCD_BITMAP 229#ifdef HAVE_LCD_BITMAP
409 struct gui_img img[MAX_IMAGES];
410 unsigned char img_buf[IMG_BUFSIZE];
411 unsigned char* img_buf_ptr;
412 int img_buf_free;
413 bool wps_sb_tag; 230 bool wps_sb_tag;
414 bool show_sb_on_wps; 231 bool show_sb_on_wps;
415 232
416 struct progressbar progressbar[MAX_PROGRESSBARS]; 233 struct skin_token_list *images;
417 short progressbar_count; 234 struct skin_token_list *progressbars;
418 235
419 bool peak_meter_enabled; 236 bool peak_meter_enabled;
420 237
@@ -465,9 +282,7 @@ struct wps_data
465 int num_tokens; 282 int num_tokens;
466 struct wps_token tokens[WPS_MAX_TOKENS]; 283 struct wps_token tokens[WPS_MAX_TOKENS];
467 284
468 char string_buffer[STRING_BUFFER_SIZE]; 285 struct skin_token_list *strings;
469 char *strings[WPS_MAX_STRINGS];
470 int num_strings;
471 286
472 bool wps_loaded; 287 bool wps_loaded;
473 288
@@ -533,4 +348,8 @@ const char *get_token_value(struct gui_wps *gwps,
533 char *buf, int buf_size, 348 char *buf, int buf_size,
534 int *intval); 349 int *intval);
535 350
351
352
353struct gui_img* find_image(int n, struct wps_data *data);
354
536#endif 355#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 @@
70#include "radio.h" 70#include "radio.h"
71#endif 71#endif
72#include "wps.h" 72#include "wps.h"
73#include "skin_engine/skin_engine.h"
73 74
74#if CONFIG_CODEC == MAS3507D 75#if CONFIG_CODEC == MAS3507D
75void dac_line_in(bool enable); 76void dac_line_in(bool enable);
@@ -818,6 +819,8 @@ void settings_apply(bool read_disk)
818 819
819 if (read_disk) 820 if (read_disk)
820 { 821 {
822 /* re-initialize the skin buffer before we start reloading skins */
823 skin_buffer_init();
821 824
822#ifdef HAVE_LCD_BITMAP 825#ifdef HAVE_LCD_BITMAP
823 /* fonts need to be loaded before the WPS */ 826 /* fonts need to be loaded before the WPS */