diff options
author | Jonathan Gordon <rockbox@jdgordon.info> | 2010-07-29 12:37:48 +0000 |
---|---|---|
committer | Jonathan Gordon <rockbox@jdgordon.info> | 2010-07-29 12:37:48 +0000 |
commit | 2d31d77a8ba231cb03ec35863c4c4ce2024f6509 (patch) | |
tree | b85ca1bede3e83695619064ee9a323f0a8da1865 /apps/gui | |
parent | e436483b66a931fef6436e9cd3e69eb2b3ff1f7b (diff) | |
download | rockbox-2d31d77a8ba231cb03ec35863c4c4ce2024f6509.tar.gz rockbox-2d31d77a8ba231cb03ec35863c4c4ce2024f6509.zip |
FS#11470 - new skin code, finally svn uses the new parser from the theme editor. This means that a skin that passes the editor WILL pass svn and checkwps (unless the target runs out of skin buffer or something.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@27613 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/gui')
-rw-r--r-- | apps/gui/skin_engine/skin_backdrops.c | 4 | ||||
-rw-r--r-- | apps/gui/skin_engine/skin_buffer.c | 170 | ||||
-rw-r--r-- | apps/gui/skin_engine/skin_buffer.h | 64 | ||||
-rw-r--r-- | apps/gui/skin_engine/skin_display.c | 728 | ||||
-rw-r--r-- | apps/gui/skin_engine/skin_display.h | 59 | ||||
-rw-r--r-- | apps/gui/skin_engine/skin_engine.h | 33 | ||||
-rw-r--r-- | apps/gui/skin_engine/skin_fonts.c | 2 | ||||
-rw-r--r-- | apps/gui/skin_engine/skin_fonts.h | 1 | ||||
-rw-r--r-- | apps/gui/skin_engine/skin_parser.c | 2057 | ||||
-rw-r--r-- | apps/gui/skin_engine/skin_render.c | 614 | ||||
-rw-r--r-- | apps/gui/skin_engine/skin_tokens.c | 279 | ||||
-rw-r--r-- | apps/gui/skin_engine/skin_tokens.h | 238 | ||||
-rw-r--r-- | apps/gui/skin_engine/wps_debug.c | 1 | ||||
-rw-r--r-- | apps/gui/skin_engine/wps_internals.h | 102 | ||||
-rw-r--r-- | apps/gui/statusbar-skinned.c | 103 | ||||
-rw-r--r-- | apps/gui/theme_settings.c | 12 | ||||
-rw-r--r-- | apps/gui/viewport.c | 84 | ||||
-rw-r--r-- | apps/gui/viewport.h | 21 | ||||
-rw-r--r-- | apps/gui/wps.c | 16 |
19 files changed, 1622 insertions, 2966 deletions
diff --git a/apps/gui/skin_engine/skin_backdrops.c b/apps/gui/skin_engine/skin_backdrops.c index a32bfbe589..4288e0a7b4 100644 --- a/apps/gui/skin_engine/skin_backdrops.c +++ b/apps/gui/skin_engine/skin_backdrops.c | |||
@@ -24,9 +24,9 @@ | |||
24 | #include <stdlib.h> | 24 | #include <stdlib.h> |
25 | #include "string-extra.h" | 25 | #include "string-extra.h" |
26 | #include "settings.h" | 26 | #include "settings.h" |
27 | #include "skin_buffer.h" | ||
28 | #include "wps_internals.h" | 27 | #include "wps_internals.h" |
29 | #include "skin_engine.h" | 28 | #include "skin_engine.h" |
29 | #include "skin_buffer.h" | ||
30 | 30 | ||
31 | #if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)) | 31 | #if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)) |
32 | 32 | ||
@@ -100,7 +100,7 @@ char* skin_backdrop_load(char* backdrop, char *bmpdir, enum screen_type screen) | |||
100 | if (!bdrop) | 100 | if (!bdrop) |
101 | return NULL; /* too many backdrops loaded */ | 101 | return NULL; /* too many backdrops loaded */ |
102 | 102 | ||
103 | bdrop->buffer = skin_buffer_alloc(buf_size); | 103 | bdrop->buffer = (char*)skin_buffer_alloc(buf_size); |
104 | if (!bdrop->buffer) | 104 | if (!bdrop->buffer) |
105 | return NULL; | 105 | return NULL; |
106 | loaded = screens[screen].backdrop_load(filename, bdrop->buffer); | 106 | loaded = screens[screen].backdrop_load(filename, bdrop->buffer); |
diff --git a/apps/gui/skin_engine/skin_buffer.c b/apps/gui/skin_engine/skin_buffer.c deleted file mode 100644 index d503b83e42..0000000000 --- a/apps/gui/skin_engine/skin_buffer.c +++ /dev/null | |||
@@ -1,170 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
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 | #include "skin_engine.h" | ||
31 | #include "wps_internals.h" | ||
32 | #include "skin_tokens.h" | ||
33 | #include "skin_buffer.h" | ||
34 | #include "skin_fonts.h" | ||
35 | |||
36 | /* skin buffer management. | ||
37 | * This module is used to allocate space in a single global skin buffer for | ||
38 | * tokens for both/all screens. | ||
39 | * | ||
40 | * This is mostly just copy/paste from firmware/buffer.c | ||
41 | * | ||
42 | * | ||
43 | * MAIN_ and REMOTE_BUFFER are just for reasonable size calibration, | ||
44 | * both screens can use the whole buffer as they need; it's not split | ||
45 | * between screens | ||
46 | * | ||
47 | * Buffer can be allocated from either "end" of the global buffer. | ||
48 | * items with unknown sizes get allocated from the start (0->) (data) | ||
49 | * items with known sizes get allocated from the end (<-buf_size) (tokens) | ||
50 | * After loading 2 skins the buffer will look like this: | ||
51 | * |tokens skin1|images skin1|tokens s2|images s2|---SPACE---|data skin2|data skin1| | ||
52 | * Make sure to never start allocating from the beginning before letting us know | ||
53 | * how much was used. and RESPECT THE buf_free RETURN VALUES! | ||
54 | * | ||
55 | */ | ||
56 | |||
57 | |||
58 | #ifdef HAVE_LCD_BITMAP | ||
59 | #define MAIN_BUFFER ((2*LCD_HEIGHT*LCD_WIDTH*LCD_DEPTH/8) \ | ||
60 | + (SKINNABLE_SCREENS_COUNT * LCD_BACKDROP_BYTES)) | ||
61 | |||
62 | #if (NB_SCREENS > 1) | ||
63 | #define REMOTE_BUFFER (2*(LCD_REMOTE_HEIGHT*LCD_REMOTE_WIDTH*LCD_REMOTE_DEPTH/8) \ | ||
64 | + (SKINNABLE_SCREENS_COUNT * REMOTE_LCD_BACKDROP_BYTES)) | ||
65 | #else | ||
66 | #define REMOTE_BUFFER 0 | ||
67 | #endif | ||
68 | |||
69 | |||
70 | #define SKIN_BUFFER_SIZE (MAIN_BUFFER + REMOTE_BUFFER + SKIN_FONT_SIZE) + \ | ||
71 | (WPS_MAX_TOKENS * sizeof(struct wps_token)) | ||
72 | #endif | ||
73 | |||
74 | #ifdef HAVE_LCD_CHARCELLS | ||
75 | #define SKIN_BUFFER_SIZE (LCD_HEIGHT * LCD_WIDTH) * 64 + \ | ||
76 | (WPS_MAX_TOKENS * sizeof(struct wps_token)) | ||
77 | #endif | ||
78 | |||
79 | static unsigned char buffer[SKIN_BUFFER_SIZE]; | ||
80 | static unsigned char *buffer_front = NULL; /* start of the free space, | ||
81 | increases with allocation*/ | ||
82 | static unsigned char *buffer_back = NULL; /* end of the free space | ||
83 | decreases with allocation */ | ||
84 | static size_t buf_size = SKIN_BUFFER_SIZE; | ||
85 | |||
86 | void skin_buffer_init(void) | ||
87 | { | ||
88 | #if 0 /* this will go in again later probably */ | ||
89 | if (buffer == NULL) | ||
90 | { | ||
91 | buf_size = SKIN_BUFFER_SIZE;/* global_settings.skin_buf_size */ | ||
92 | |||
93 | buffer = buffer_alloc(buf_size); | ||
94 | buffer_front = buffer; | ||
95 | buffer_back = bufer + buf_size; | ||
96 | } | ||
97 | else | ||
98 | #endif | ||
99 | { | ||
100 | /* reset the buffer.... */ | ||
101 | buffer_front = buffer; | ||
102 | buffer_back = buffer + buf_size; | ||
103 | } | ||
104 | } | ||
105 | |||
106 | /* get the number of bytes currently being used */ | ||
107 | size_t skin_buffer_usage(void) | ||
108 | { | ||
109 | return buf_size - (buffer_back-buffer_front); | ||
110 | } | ||
111 | |||
112 | size_t skin_buffer_freespace(void) | ||
113 | { | ||
114 | return buffer_back-buffer_front; | ||
115 | } | ||
116 | |||
117 | /* Allocate size bytes from the buffer | ||
118 | * allocates from the back end (data end) | ||
119 | */ | ||
120 | void* skin_buffer_alloc(size_t size) | ||
121 | { | ||
122 | if (skin_buffer_freespace() <= size) | ||
123 | { | ||
124 | return NULL; | ||
125 | } | ||
126 | buffer_back -= size; | ||
127 | /* 32-bit aligned */ | ||
128 | buffer_back = (void *)(((unsigned long)buffer_back) & ~3); | ||
129 | |||
130 | memset(buffer_back, 0, size); | ||
131 | return buffer_back; | ||
132 | } | ||
133 | |||
134 | /* Get a pointer to the skin buffer and the count of how much is free | ||
135 | * used to do your own buffer management. | ||
136 | * Any memory used will be overwritten next time wps_buffer_alloc() | ||
137 | * is called unless skin_buffer_increment() is called first | ||
138 | * | ||
139 | * This is from the start of the buffer, it is YOUR responsility to make | ||
140 | * sure you dont ever use more then *freespace, and bear in mind this will only | ||
141 | * be valid untill skin_buffer_alloc() is next called... | ||
142 | * so call skin_buffer_increment() and skin_buffer_freespace() regularly | ||
143 | */ | ||
144 | void* skin_buffer_grab(size_t *freespace) | ||
145 | { | ||
146 | *freespace = buf_size - skin_buffer_usage(); | ||
147 | return buffer_front; | ||
148 | } | ||
149 | |||
150 | /* Use after skin_buffer_grab() to specify how much buffer was used */ | ||
151 | void skin_buffer_increment(size_t used, bool align) | ||
152 | { | ||
153 | buffer_front += used; | ||
154 | if (align) | ||
155 | { | ||
156 | /* 32-bit aligned */ | ||
157 | buffer_front = (void *)(((unsigned long)buffer_front + 3) & ~3); | ||
158 | } | ||
159 | } | ||
160 | |||
161 | /* free previously skin_buffer_increment()'ed space. This just moves the pointer | ||
162 | * back 'used' bytes so make sure you actually want to do this */ | ||
163 | void skin_buffer_free_from_front(size_t used) | ||
164 | { | ||
165 | buffer_front -= used; | ||
166 | /* 32-bit aligned */ | ||
167 | buffer_front = (void *)(((unsigned long)buffer_front + 3) & ~3); | ||
168 | } | ||
169 | |||
170 | |||
diff --git a/apps/gui/skin_engine/skin_buffer.h b/apps/gui/skin_engine/skin_buffer.h deleted file mode 100644 index 521631f03b..0000000000 --- a/apps/gui/skin_engine/skin_buffer.h +++ /dev/null | |||
@@ -1,64 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
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 */ | ||
32 | void skin_buffer_init(void); | ||
33 | |||
34 | /* get the number of bytes currently being used */ | ||
35 | size_t skin_buffer_usage(void); | ||
36 | size_t skin_buffer_freespace(void); | ||
37 | |||
38 | /* Allocate size bytes from the buffer */ | ||
39 | void* skin_buffer_alloc(size_t size); | ||
40 | |||
41 | |||
42 | /* Get a pointer to the skin buffer and the count of how much is free | ||
43 | * used to do your own buffer management. | ||
44 | * Any memory used will be overwritten next time wps_buffer_alloc() | ||
45 | * is called unless skin_buffer_increment() is called first | ||
46 | * | ||
47 | * This is from the start of the buffer, it is YOUR responsility to make | ||
48 | * sure you dont ever use more then *freespace, and bear in mind this will only | ||
49 | * be valid untill skin_buffer_alloc() is next called... | ||
50 | * so call skin_buffer_increment() and skin_buffer_freespace() regularly | ||
51 | */ | ||
52 | void* skin_buffer_grab(size_t *freespace); | ||
53 | |||
54 | /* Use after skin_buffer_grab() to specify how much buffer was used. | ||
55 | * align should always be true unless there is a possibility that you will need | ||
56 | * more space *immediatly* after the previous allocation. (i.e in an array). | ||
57 | * NEVER leave the buffer unaligned */ | ||
58 | void skin_buffer_increment(size_t used, bool align); | ||
59 | |||
60 | /* free previously skin_buffer_increment()'ed space. This just moves the pointer | ||
61 | * back 'used' bytes so make sure you actually want to do this */ | ||
62 | void skin_buffer_free_from_front(size_t used); | ||
63 | |||
64 | #endif /* _SKIN_BUFFER_H_ */ | ||
diff --git a/apps/gui/skin_engine/skin_display.c b/apps/gui/skin_engine/skin_display.c index 3d3a654c30..559ae8519f 100644 --- a/apps/gui/skin_engine/skin_display.c +++ b/apps/gui/skin_engine/skin_display.c | |||
@@ -69,25 +69,22 @@ | |||
69 | #include "skin_engine.h" | 69 | #include "skin_engine.h" |
70 | #include "statusbar-skinned.h" | 70 | #include "statusbar-skinned.h" |
71 | 71 | ||
72 | static bool skin_redraw(struct gui_wps *gwps, unsigned refresh_mode); | 72 | void skin_render(struct gui_wps *gwps, unsigned refresh_mode); |
73 | 73 | ||
74 | /* update a skinned screen, update_type is WPS_REFRESH_* values. | 74 | /* update a skinned screen, update_type is WPS_REFRESH_* values. |
75 | * Usually it should only be WPS_REFRESH_NON_STATIC | 75 | * Usually it should only be WPS_REFRESH_NON_STATIC |
76 | * A full update will be done if required (state.do_full_update == true) | 76 | * A full update will be done if required (state.do_full_update == true) |
77 | */ | 77 | */ |
78 | bool skin_update(struct gui_wps *gwps, unsigned int update_type) | 78 | void skin_update(struct gui_wps *gwps, unsigned int update_type) |
79 | { | 79 | { |
80 | bool retval; | 80 | /* This maybe shouldnt be here, |
81 | /* This maybe shouldnt be here, but while the skin is only used to | 81 | * This is also safe for skined screen which dont use the id3 */ |
82 | * display the music screen this is better than whereever we are being | ||
83 | * called from. This is also safe for skined screen which dont use the id3 */ | ||
84 | struct mp3entry *id3 = gwps->state->id3; | 82 | struct mp3entry *id3 = gwps->state->id3; |
85 | bool cuesheet_update = (id3 != NULL ? cuesheet_subtrack_changed(id3) : false); | 83 | bool cuesheet_update = (id3 != NULL ? cuesheet_subtrack_changed(id3) : false); |
86 | gwps->sync_data->do_full_update |= cuesheet_update; | 84 | gwps->sync_data->do_full_update |= cuesheet_update; |
87 | 85 | ||
88 | retval = skin_redraw(gwps, gwps->sync_data->do_full_update ? | 86 | skin_render(gwps, gwps->sync_data->do_full_update ? |
89 | WPS_REFRESH_ALL : update_type); | 87 | SKIN_REFRESH_ALL : update_type); |
90 | return retval; | ||
91 | } | 88 | } |
92 | 89 | ||
93 | #ifdef HAVE_LCD_BITMAP | 90 | #ifdef HAVE_LCD_BITMAP |
@@ -124,8 +121,7 @@ void skin_statusbar_changed(struct gui_wps *skin) | |||
124 | } | 121 | } |
125 | } | 122 | } |
126 | 123 | ||
127 | static void draw_progressbar(struct gui_wps *gwps, | 124 | void draw_progressbar(struct gui_wps *gwps, int line, struct progressbar *pb) |
128 | struct progressbar *pb) | ||
129 | { | 125 | { |
130 | struct screen *display = gwps->display; | 126 | struct screen *display = gwps->display; |
131 | struct viewport *vp = pb->vp; | 127 | struct viewport *vp = pb->vp; |
@@ -143,17 +139,17 @@ static void draw_progressbar(struct gui_wps *gwps, | |||
143 | /* center the pb in the line, but only if the line is higher than the pb */ | 139 | /* center the pb in the line, but only if the line is higher than the pb */ |
144 | int center = (line_height-height)/2; | 140 | int center = (line_height-height)/2; |
145 | /* if Y was not set calculate by font height,Y is -line_number-1 */ | 141 | /* if Y was not set calculate by font height,Y is -line_number-1 */ |
146 | y = (-y -1)*line_height + (0 > center ? 0 : center); | 142 | y = line*line_height + (0 > center ? 0 : center); |
147 | } | 143 | } |
148 | 144 | ||
149 | if (pb->type == WPS_TOKEN_VOLUMEBAR) | 145 | if (pb->type == SKIN_TOKEN_VOLUMEBAR) |
150 | { | 146 | { |
151 | int minvol = sound_min(SOUND_VOLUME); | 147 | int minvol = sound_min(SOUND_VOLUME); |
152 | int maxvol = sound_max(SOUND_VOLUME); | 148 | int maxvol = sound_max(SOUND_VOLUME); |
153 | length = maxvol-minvol; | 149 | length = maxvol-minvol; |
154 | elapsed = global_settings.volume-minvol; | 150 | elapsed = global_settings.volume-minvol; |
155 | } | 151 | } |
156 | else if (pb->type == WPS_TOKEN_BATTERY_PERCENTBAR) | 152 | else if (pb->type == SKIN_TOKEN_BATTERY_PERCENTBAR) |
157 | { | 153 | { |
158 | length = 100; | 154 | length = 100; |
159 | elapsed = battery_level(); | 155 | elapsed = battery_level(); |
@@ -185,7 +181,7 @@ static void draw_progressbar(struct gui_wps *gwps, | |||
185 | gui_scrollbar_draw(display, pb->x, y, pb->width, height, | 181 | gui_scrollbar_draw(display, pb->x, y, pb->width, height, |
186 | length, 0, elapsed, HORIZONTAL); | 182 | length, 0, elapsed, HORIZONTAL); |
187 | 183 | ||
188 | if (pb->type == WPS_TOKEN_PROGRESSBAR) | 184 | if (pb->type == SKIN_TOKEN_PROGRESSBAR) |
189 | { | 185 | { |
190 | if (id3 && id3->length) | 186 | if (id3 && id3->length) |
191 | { | 187 | { |
@@ -208,8 +204,7 @@ static void draw_progressbar(struct gui_wps *gwps, | |||
208 | } | 204 | } |
209 | } | 205 | } |
210 | 206 | ||
211 | static void draw_playlist_viewer_list(struct gui_wps *gwps, | 207 | void draw_playlist_viewer_list(struct gui_wps *gwps, struct playlistviewer *viewer) |
212 | struct playlistviewer *viewer) | ||
213 | { | 208 | { |
214 | struct wps_state *state = gwps->state; | 209 | struct wps_state *state = gwps->state; |
215 | int lines = viewport_get_nb_lines(viewer->vp); | 210 | int lines = viewport_get_nb_lines(viewer->vp); |
@@ -217,8 +212,9 @@ static void draw_playlist_viewer_list(struct gui_wps *gwps, | |||
217 | int cur_pos, max; | 212 | int cur_pos, max; |
218 | int start_item; | 213 | int start_item; |
219 | int i; | 214 | int i; |
220 | struct wps_token token; | 215 | bool scroll = false; |
221 | int x, length, alignment = WPS_TOKEN_ALIGN_LEFT; | 216 | struct wps_token *token; |
217 | int x, length, alignment = SKIN_TOKEN_ALIGN_LEFT; | ||
222 | 218 | ||
223 | struct mp3entry *pid3; | 219 | struct mp3entry *pid3; |
224 | char buf[MAX_PATH*2], tempbuf[MAX_PATH]; | 220 | char buf[MAX_PATH*2], tempbuf[MAX_PATH]; |
@@ -281,51 +277,58 @@ static void draw_playlist_viewer_list(struct gui_wps *gwps, | |||
281 | } | 277 | } |
282 | line = pid3 ? TRACK_HAS_INFO : TRACK_HAS_NO_INFO; | 278 | line = pid3 ? TRACK_HAS_INFO : TRACK_HAS_NO_INFO; |
283 | } | 279 | } |
284 | int j = 0, cur_string = 0; | ||
285 | unsigned int line_len = 0; | 280 | unsigned int line_len = 0; |
281 | if (viewer->lines[line]->children_count == 0) | ||
282 | return; | ||
283 | struct skin_element *element = viewer->lines[line]->children[0]; | ||
286 | buf[0] = '\0'; | 284 | buf[0] = '\0'; |
287 | while (j < viewer->lines[line].count && line_len < sizeof(buf)) | 285 | while (element && line_len < sizeof(buf)) |
288 | { | 286 | { |
289 | const char *out = NULL; | 287 | const char *out = NULL; |
290 | token.type = viewer->lines[line].tokens[j]; | 288 | if (element->type == TEXT) |
291 | token.value.i = 0; | 289 | { |
292 | token.next = false; | 290 | line_len = strlcat(buf, (char*)element->data, sizeof(buf)); |
293 | out = get_id3_token(&token, pid3, tempbuf, sizeof(tempbuf), -1, NULL); | 291 | element = element->next; |
292 | continue; | ||
293 | } | ||
294 | if (element->type != TAG) | ||
295 | { | ||
296 | element = element->next; | ||
297 | continue; | ||
298 | } | ||
299 | if (element->tag->type == SKIN_TOKEN_SUBLINE_SCROLL) | ||
300 | scroll = true; | ||
301 | token = (struct wps_token*)element->data; | ||
302 | out = get_id3_token(token, pid3, tempbuf, sizeof(tempbuf), -1, NULL); | ||
294 | #if CONFIG_TUNER | 303 | #if CONFIG_TUNER |
295 | if (!out) | 304 | if (!out) |
296 | out = get_radio_token(&token, i-cur_pos, | 305 | out = get_radio_token(token, i-cur_pos, |
297 | tempbuf, sizeof(tempbuf), -1, NULL); | 306 | tempbuf, sizeof(tempbuf), -1, NULL); |
298 | #endif | 307 | #endif |
299 | if (out) | 308 | if (out) |
300 | { | 309 | { |
301 | line_len = strlcat(buf, out, sizeof(buf)); | 310 | line_len = strlcat(buf, out, sizeof(buf)); |
302 | j++; | 311 | element = element->next; |
303 | continue; | 312 | continue; |
304 | } | 313 | } |
305 | 314 | ||
306 | switch (viewer->lines[line].tokens[j]) | 315 | switch (token->type) |
307 | { | 316 | { |
308 | case WPS_TOKEN_ALIGN_CENTER: | 317 | case SKIN_TOKEN_ALIGN_CENTER: |
309 | case WPS_TOKEN_ALIGN_LEFT: | 318 | case SKIN_TOKEN_ALIGN_LEFT: |
310 | case WPS_TOKEN_ALIGN_LEFT_RTL: | 319 | case SKIN_TOKEN_ALIGN_LEFT_RTL: |
311 | case WPS_TOKEN_ALIGN_RIGHT: | 320 | case SKIN_TOKEN_ALIGN_RIGHT: |
312 | case WPS_TOKEN_ALIGN_RIGHT_RTL: | 321 | case SKIN_TOKEN_ALIGN_RIGHT_RTL: |
313 | alignment = viewer->lines[line].tokens[j]; | 322 | alignment = token->type; |
314 | tempbuf[0] = '\0'; | 323 | tempbuf[0] = '\0'; |
315 | break; | 324 | break; |
316 | case WPS_TOKEN_STRING: | 325 | case SKIN_TOKEN_PLAYLIST_POSITION: |
317 | case WPS_TOKEN_CHARACTER: | ||
318 | snprintf(tempbuf, sizeof(tempbuf), "%s", | ||
319 | viewer->lines[line].strings[cur_string]); | ||
320 | cur_string++; | ||
321 | break; | ||
322 | case WPS_TOKEN_PLAYLIST_POSITION: | ||
323 | snprintf(tempbuf, sizeof(tempbuf), "%d", i); | 326 | snprintf(tempbuf, sizeof(tempbuf), "%d", i); |
324 | break; | 327 | break; |
325 | case WPS_TOKEN_FILE_NAME: | 328 | case SKIN_TOKEN_FILE_NAME: |
326 | get_dir(tempbuf, sizeof(tempbuf), filename, 0); | 329 | get_dir(tempbuf, sizeof(tempbuf), filename, 0); |
327 | break; | 330 | break; |
328 | case WPS_TOKEN_FILE_PATH: | 331 | case SKIN_TOKEN_FILE_PATH: |
329 | snprintf(tempbuf, sizeof(tempbuf), "%s", filename); | 332 | snprintf(tempbuf, sizeof(tempbuf), "%s", filename); |
330 | break; | 333 | break; |
331 | default: | 334 | default: |
@@ -336,12 +339,12 @@ static void draw_playlist_viewer_list(struct gui_wps *gwps, | |||
336 | { | 339 | { |
337 | line_len = strlcat(buf, tempbuf, sizeof(buf)); | 340 | line_len = strlcat(buf, tempbuf, sizeof(buf)); |
338 | } | 341 | } |
339 | j++; | 342 | element = element->next; |
340 | } | 343 | } |
341 | 344 | ||
342 | int vpwidth = viewer->vp->width; | 345 | int vpwidth = viewer->vp->width; |
343 | length = gwps->display->getstringsize(buf, NULL, NULL); | 346 | length = gwps->display->getstringsize(buf, NULL, NULL); |
344 | if (viewer->lines[line].scroll && length >= vpwidth) | 347 | if (scroll && length >= vpwidth) |
345 | { | 348 | { |
346 | gwps->display->puts_scroll(0, (i-start_item), buf ); | 349 | gwps->display->puts_scroll(0, (i-start_item), buf ); |
347 | } | 350 | } |
@@ -353,25 +356,25 @@ static void draw_playlist_viewer_list(struct gui_wps *gwps, | |||
353 | { | 356 | { |
354 | switch (alignment) | 357 | switch (alignment) |
355 | { | 358 | { |
356 | case WPS_TOKEN_ALIGN_CENTER: | 359 | case SKIN_TOKEN_ALIGN_CENTER: |
357 | x = (vpwidth-length)/2; | 360 | x = (vpwidth-length)/2; |
358 | break; | 361 | break; |
359 | case WPS_TOKEN_ALIGN_LEFT_RTL: | 362 | case SKIN_TOKEN_ALIGN_LEFT_RTL: |
360 | if (lang_is_rtl() && VP_IS_RTL(viewer->vp)) | 363 | if (lang_is_rtl() && VP_IS_RTL(viewer->vp)) |
361 | { | 364 | { |
362 | x = vpwidth - length; | 365 | x = vpwidth - length; |
363 | break; | 366 | break; |
364 | } | 367 | } |
365 | case WPS_TOKEN_ALIGN_LEFT: | 368 | case SKIN_TOKEN_ALIGN_LEFT: |
366 | x = 0; | 369 | x = 0; |
367 | break; | 370 | break; |
368 | case WPS_TOKEN_ALIGN_RIGHT_RTL: | 371 | case SKIN_TOKEN_ALIGN_RIGHT_RTL: |
369 | if (lang_is_rtl() && VP_IS_RTL(viewer->vp)) | 372 | if (lang_is_rtl() && VP_IS_RTL(viewer->vp)) |
370 | { | 373 | { |
371 | x = 0; | 374 | x = 0; |
372 | break; | 375 | break; |
373 | } | 376 | } |
374 | case WPS_TOKEN_ALIGN_RIGHT: | 377 | case SKIN_TOKEN_ALIGN_RIGHT: |
375 | x = vpwidth - length; | 378 | x = vpwidth - length; |
376 | break; | 379 | break; |
377 | default: | 380 | default: |
@@ -386,7 +389,7 @@ static void draw_playlist_viewer_list(struct gui_wps *gwps, | |||
386 | 389 | ||
387 | 390 | ||
388 | /* clears the area where the image was shown */ | 391 | /* clears the area where the image was shown */ |
389 | static void clear_image_pos(struct gui_wps *gwps, struct gui_img *img) | 392 | void clear_image_pos(struct gui_wps *gwps, struct gui_img *img) |
390 | { | 393 | { |
391 | if(!gwps) | 394 | if(!gwps) |
392 | return; | 395 | return; |
@@ -395,7 +398,7 @@ static void clear_image_pos(struct gui_wps *gwps, struct gui_img *img) | |||
395 | gwps->display->set_drawmode(DRMODE_SOLID); | 398 | gwps->display->set_drawmode(DRMODE_SOLID); |
396 | } | 399 | } |
397 | 400 | ||
398 | static void wps_draw_image(struct gui_wps *gwps, struct gui_img *img, int subimage) | 401 | void wps_draw_image(struct gui_wps *gwps, struct gui_img *img, int subimage) |
399 | { | 402 | { |
400 | struct screen *display = gwps->display; | 403 | struct screen *display = gwps->display; |
401 | if(img->always_display) | 404 | if(img->always_display) |
@@ -423,7 +426,8 @@ static void wps_draw_image(struct gui_wps *gwps, struct gui_img *img, int subima | |||
423 | #endif | 426 | #endif |
424 | } | 427 | } |
425 | 428 | ||
426 | static void wps_display_images(struct gui_wps *gwps, struct viewport* vp) | 429 | |
430 | void wps_display_images(struct gui_wps *gwps, struct viewport* vp) | ||
427 | { | 431 | { |
428 | if(!gwps || !gwps->data || !gwps->display) | 432 | if(!gwps || !gwps->data || !gwps->display) |
429 | return; | 433 | return; |
@@ -451,18 +455,10 @@ static void wps_display_images(struct gui_wps *gwps, struct viewport* vp) | |||
451 | #ifdef HAVE_ALBUMART | 455 | #ifdef HAVE_ALBUMART |
452 | /* now draw the AA */ | 456 | /* now draw the AA */ |
453 | if (data->albumart && data->albumart->vp == vp | 457 | if (data->albumart && data->albumart->vp == vp |
454 | && data->albumart->draw) | 458 | && data->albumart->draw_handle >= 0) |
455 | { | 459 | { |
456 | int handle = playback_current_aa_hid(data->playback_aa_slot); | 460 | draw_album_art(gwps, data->albumart->draw_handle, false); |
457 | #if CONFIG_TUNER | 461 | data->albumart->draw_handle = -1; |
458 | if (in_radio_screen() || (get_radio_status() != FMRADIO_OFF)) | ||
459 | { | ||
460 | struct dim dim = {data->albumart->width, data->albumart->height}; | ||
461 | handle = radio_get_art_hid(&dim); | ||
462 | } | ||
463 | #endif | ||
464 | draw_album_art(gwps, handle, false); | ||
465 | data->albumart->draw = false; | ||
466 | } | 462 | } |
467 | #endif | 463 | #endif |
468 | 464 | ||
@@ -471,7 +467,7 @@ static void wps_display_images(struct gui_wps *gwps, struct viewport* vp) | |||
471 | 467 | ||
472 | #else /* HAVE_LCD_CHARCELL */ | 468 | #else /* HAVE_LCD_CHARCELL */ |
473 | 469 | ||
474 | static bool draw_player_progress(struct gui_wps *gwps) | 470 | bool draw_player_progress(struct gui_wps *gwps) |
475 | { | 471 | { |
476 | struct wps_state *state = gwps->state; | 472 | struct wps_state *state = gwps->state; |
477 | struct screen *display = gwps->display; | 473 | struct screen *display = gwps->display; |
@@ -508,7 +504,7 @@ static bool draw_player_progress(struct gui_wps *gwps) | |||
508 | return true; | 504 | return true; |
509 | } | 505 | } |
510 | 506 | ||
511 | static void draw_player_fullbar(struct gui_wps *gwps, char* buf, int buf_size) | 507 | void draw_player_fullbar(struct gui_wps *gwps, char* buf, int buf_size) |
512 | { | 508 | { |
513 | static const unsigned char numbers[10][4] = { | 509 | static const unsigned char numbers[10][4] = { |
514 | {0x0e, 0x0a, 0x0a, 0x0e}, /* 0 */ | 510 | {0x0e, 0x0a, 0x0a, 0x0e}, /* 0 */ |
@@ -613,44 +609,25 @@ static void draw_player_fullbar(struct gui_wps *gwps, char* buf, int buf_size) | |||
613 | 609 | ||
614 | #endif /* HAVE_LCD_CHARCELL */ | 610 | #endif /* HAVE_LCD_CHARCELL */ |
615 | 611 | ||
616 | /* Return the index to the end token for the conditional token at index. | ||
617 | The conditional token can be either a start token or a separator | ||
618 | (i.e. option) token. | ||
619 | */ | ||
620 | static int find_conditional_end(struct wps_data *data, int index) | ||
621 | { | ||
622 | int ret = index; | ||
623 | while (data->tokens[ret].type != WPS_TOKEN_CONDITIONAL_END) | ||
624 | ret = data->tokens[ret].value.i; | ||
625 | |||
626 | /* ret now is the index to the end token for the conditional. */ | ||
627 | return ret; | ||
628 | } | ||
629 | |||
630 | /* Evaluate the conditional that is at *token_index and return whether a skip | 612 | /* Evaluate the conditional that is at *token_index and return whether a skip |
631 | has ocurred. *token_index is updated with the new position. | 613 | has ocurred. *token_index is updated with the new position. |
632 | */ | 614 | */ |
633 | static bool evaluate_conditional(struct gui_wps *gwps, int *token_index) | 615 | int evaluate_conditional(struct gui_wps *gwps, struct conditional *conditional, int num_options) |
634 | { | 616 | { |
635 | if (!gwps) | 617 | if (!gwps) |
636 | return false; | 618 | return false; |
637 | 619 | ||
638 | struct wps_data *data = gwps->data; | ||
639 | |||
640 | int i, cond_end; | ||
641 | int cond_index = *token_index; | ||
642 | char result[128]; | 620 | char result[128]; |
643 | const char *value; | 621 | const char *value; |
644 | unsigned char num_options = data->tokens[cond_index].value.i & 0xFF; | ||
645 | unsigned char prev_val = (data->tokens[cond_index].value.i & 0xFF00) >> 8; | ||
646 | 622 | ||
647 | /* treat ?xx<true> constructs as if they had 2 options. */ | 623 | /* treat ?xx<true> constructs as if they had 2 options. |
624 | * (i.e ?xx<true|false>) */ | ||
648 | if (num_options < 2) | 625 | if (num_options < 2) |
649 | num_options = 2; | 626 | num_options = 2; |
650 | 627 | ||
651 | int intval = num_options; | 628 | int intval = num_options; |
652 | /* get_token_value needs to know the number of options in the enum */ | 629 | /* get_token_value needs to know the number of options in the enum */ |
653 | value = get_token_value(gwps, &data->tokens[cond_index + 1], | 630 | value = get_token_value(gwps, conditional->token, |
654 | result, sizeof(result), &intval); | 631 | result, sizeof(result), &intval); |
655 | 632 | ||
656 | /* intval is now the number of the enum option we want to read, | 633 | /* intval is now the number of the enum option we want to read, |
@@ -659,334 +636,18 @@ static bool evaluate_conditional(struct gui_wps *gwps, int *token_index) | |||
659 | intval = (value && *value) ? 1 : num_options; | 636 | intval = (value && *value) ? 1 : num_options; |
660 | else if (intval > num_options || intval < 1) | 637 | else if (intval > num_options || intval < 1) |
661 | intval = num_options; | 638 | intval = num_options; |
662 | 639 | ||
663 | data->tokens[cond_index].value.i = (intval << 8) + num_options; | 640 | conditional->last_value = intval -1; |
664 | 641 | return intval -1; | |
665 | /* skip to the appropriate enum case */ | ||
666 | int next = cond_index + 2; | ||
667 | for (i = 1; i < intval; i++) | ||
668 | { | ||
669 | next = data->tokens[next].value.i; | ||
670 | } | ||
671 | *token_index = next; | ||
672 | |||
673 | if (prev_val == intval) | ||
674 | { | ||
675 | /* Same conditional case as previously. Return without clearing the | ||
676 | pictures */ | ||
677 | return false; | ||
678 | } | ||
679 | |||
680 | cond_end = find_conditional_end(data, cond_index + 2); | ||
681 | for (i = cond_index + 3; i < cond_end; i++) | ||
682 | { | ||
683 | #ifdef HAVE_LCD_BITMAP | ||
684 | /* clear all pictures in the conditional and nested ones */ | ||
685 | if (data->tokens[i].type == WPS_TOKEN_IMAGE_PRELOAD_DISPLAY) | ||
686 | clear_image_pos(gwps, find_image(data->tokens[i].value.i&0xFF, data)); | ||
687 | else if (data->tokens[i].type == WPS_TOKEN_VOLUMEBAR || | ||
688 | data->tokens[i].type == WPS_TOKEN_PROGRESSBAR || | ||
689 | data->tokens[i].type == WPS_TOKEN_BATTERY_PERCENTBAR ) | ||
690 | { | ||
691 | struct progressbar *bar = (struct progressbar*)data->tokens[i].value.data; | ||
692 | bar->draw = false; | ||
693 | } | ||
694 | else if (data->tokens[i].type == WPS_TOKEN_PEAKMETER) | ||
695 | { | ||
696 | data->peak_meter_enabled = false; | ||
697 | } | ||
698 | #endif | ||
699 | #ifdef HAVE_ALBUMART | ||
700 | if (data->albumart && data->tokens[i].type == WPS_TOKEN_ALBUMART_DISPLAY) | ||
701 | { | ||
702 | draw_album_art(gwps, | ||
703 | playback_current_aa_hid(data->playback_aa_slot), true); | ||
704 | data->albumart->draw = false; | ||
705 | } | ||
706 | #endif | ||
707 | } | ||
708 | |||
709 | return true; | ||
710 | } | ||
711 | |||
712 | |||
713 | /* Read a (sub)line to the given alignment format buffer. | ||
714 | linebuf is the buffer where the data is actually stored. | ||
715 | align is the alignment format that'll be used to display the text. | ||
716 | The return value indicates whether the line needs to be updated. | ||
717 | */ | ||
718 | static bool get_line(struct gui_wps *gwps, | ||
719 | struct skin_subline *subline, | ||
720 | struct align_pos *align, | ||
721 | char *linebuf, | ||
722 | int linebuf_size, | ||
723 | unsigned refresh_mode) | ||
724 | { | ||
725 | struct wps_data *data = gwps->data; | ||
726 | |||
727 | char temp_buf[128]; | ||
728 | char *buf = linebuf; /* will always point to the writing position */ | ||
729 | char *linebuf_end = linebuf + linebuf_size - 1; | ||
730 | bool update = false; | ||
731 | int i; | ||
732 | (void)refresh_mode; /* silence warning on charcell */ | ||
733 | |||
734 | /* alignment-related variables */ | ||
735 | int cur_align; | ||
736 | char* cur_align_start; | ||
737 | cur_align_start = buf; | ||
738 | cur_align = WPS_ALIGN_LEFT; | ||
739 | align->left = NULL; | ||
740 | align->center = NULL; | ||
741 | align->right = NULL; | ||
742 | /* Process all tokens of the desired subline */ | ||
743 | for (i = subline->first_token_idx; | ||
744 | i <= subline->last_token_idx; i++) | ||
745 | { | ||
746 | switch(data->tokens[i].type) | ||
747 | { | ||
748 | case WPS_TOKEN_CONDITIONAL: | ||
749 | /* place ourselves in the right conditional case */ | ||
750 | update |= evaluate_conditional(gwps, &i); | ||
751 | break; | ||
752 | |||
753 | case WPS_TOKEN_CONDITIONAL_OPTION: | ||
754 | /* we've finished in the curent conditional case, | ||
755 | skip to the end of the conditional structure */ | ||
756 | i = find_conditional_end(data, i); | ||
757 | break; | ||
758 | #if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)) | ||
759 | case WPS_TOKEN_VIEWPORT_FGCOLOUR: | ||
760 | { | ||
761 | struct viewport_colour *col = data->tokens[i].value.data; | ||
762 | col->vp->fg_pattern = col->colour; | ||
763 | } | ||
764 | break; | ||
765 | case WPS_TOKEN_VIEWPORT_BGCOLOUR: | ||
766 | { | ||
767 | struct viewport_colour *col = data->tokens[i].value.data; | ||
768 | col->vp->bg_pattern = col->colour; | ||
769 | } | ||
770 | break; | ||
771 | #endif | ||
772 | #ifdef HAVE_LCD_BITMAP | ||
773 | case WPS_TOKEN_PEAKMETER: | ||
774 | data->peak_meter_enabled = true; | ||
775 | break; | ||
776 | case WPS_TOKEN_VOLUMEBAR: | ||
777 | case WPS_TOKEN_BATTERY_PERCENTBAR: | ||
778 | case WPS_TOKEN_PROGRESSBAR: | ||
779 | { | ||
780 | struct progressbar *bar = (struct progressbar*)data->tokens[i].value.data; | ||
781 | bar->draw = true; | ||
782 | } | ||
783 | break; | ||
784 | case WPS_TOKEN_IMAGE_PRELOAD_DISPLAY: | ||
785 | { | ||
786 | char n = data->tokens[i].value.i & 0xFF; | ||
787 | int subimage = data->tokens[i].value.i >> 8; | ||
788 | struct gui_img *img = find_image(n, data); | ||
789 | |||
790 | if (img && img->loaded) | ||
791 | img->display = subimage; | ||
792 | break; | ||
793 | } | ||
794 | case WPS_TOKEN_DRAW_INBUILTBAR: | ||
795 | gui_statusbar_draw(&(statusbars.statusbars[gwps->display->screen_type]), | ||
796 | refresh_mode == WPS_REFRESH_ALL, | ||
797 | data->tokens[i].value.data); | ||
798 | break; | ||
799 | #endif | ||
800 | |||
801 | case WPS_TOKEN_ALIGN_LEFT: | ||
802 | case WPS_TOKEN_ALIGN_LEFT_RTL: | ||
803 | case WPS_TOKEN_ALIGN_CENTER: | ||
804 | case WPS_TOKEN_ALIGN_RIGHT: | ||
805 | case WPS_TOKEN_ALIGN_RIGHT_RTL: | ||
806 | /* remember where the current aligned text started */ | ||
807 | switch (cur_align) | ||
808 | { | ||
809 | case WPS_ALIGN_LEFT: | ||
810 | align->left = cur_align_start; | ||
811 | break; | ||
812 | |||
813 | case WPS_ALIGN_CENTER: | ||
814 | align->center = cur_align_start; | ||
815 | break; | ||
816 | |||
817 | case WPS_ALIGN_RIGHT: | ||
818 | align->right = cur_align_start; | ||
819 | break; | ||
820 | } | ||
821 | /* start a new alignment */ | ||
822 | switch (data->tokens[i].type) | ||
823 | { | ||
824 | case WPS_TOKEN_ALIGN_LEFT: | ||
825 | cur_align = WPS_ALIGN_LEFT; | ||
826 | break; | ||
827 | case WPS_TOKEN_ALIGN_LEFT_RTL: | ||
828 | cur_align = lang_is_rtl() ? WPS_ALIGN_RIGHT : | ||
829 | WPS_ALIGN_LEFT; | ||
830 | break; | ||
831 | case WPS_TOKEN_ALIGN_CENTER: | ||
832 | cur_align = WPS_ALIGN_CENTER; | ||
833 | break; | ||
834 | case WPS_TOKEN_ALIGN_RIGHT: | ||
835 | cur_align = WPS_ALIGN_RIGHT; | ||
836 | break; | ||
837 | case WPS_TOKEN_ALIGN_RIGHT_RTL: | ||
838 | cur_align = lang_is_rtl() ? WPS_ALIGN_LEFT : | ||
839 | WPS_ALIGN_RIGHT; | ||
840 | break; | ||
841 | default: | ||
842 | break; | ||
843 | } | ||
844 | *buf++ = 0; | ||
845 | cur_align_start = buf; | ||
846 | break; | ||
847 | case WPS_VIEWPORT_ENABLE: | ||
848 | { | ||
849 | char label = data->tokens[i].value.i; | ||
850 | char temp = VP_DRAW_HIDEABLE; | ||
851 | /* viewports are allowed to share id's so find and enable | ||
852 | * all of them */ | ||
853 | struct skin_token_list *list = data->viewports; | ||
854 | while (list) | ||
855 | { | ||
856 | struct skin_viewport *vp = | ||
857 | (struct skin_viewport *)list->token->value.data; | ||
858 | if (vp->label == label) | ||
859 | { | ||
860 | if (vp->hidden_flags&VP_DRAW_WASHIDDEN) | ||
861 | temp |= VP_DRAW_WASHIDDEN; | ||
862 | vp->hidden_flags = temp; | ||
863 | } | ||
864 | list = list->next; | ||
865 | } | ||
866 | } | ||
867 | break; | ||
868 | #ifdef HAVE_LCD_BITMAP | ||
869 | case WPS_TOKEN_UIVIEWPORT_ENABLE: | ||
870 | sb_set_info_vp(gwps->display->screen_type, | ||
871 | data->tokens[i].value.i|VP_INFO_LABEL); | ||
872 | break; | ||
873 | case WPS_VIEWPORT_CUSTOMLIST: | ||
874 | draw_playlist_viewer_list(gwps, data->tokens[i].value.data); | ||
875 | break; | ||
876 | #endif | ||
877 | default: | ||
878 | { | ||
879 | /* get the value of the tag and copy it to the buffer */ | ||
880 | const char *value = get_token_value(gwps, &data->tokens[i], | ||
881 | temp_buf, sizeof(temp_buf), NULL); | ||
882 | if (value) | ||
883 | { | ||
884 | update = true; | ||
885 | while (*value && (buf < linebuf_end)) | ||
886 | *buf++ = *value++; | ||
887 | } | ||
888 | break; | ||
889 | } | ||
890 | } | ||
891 | } | ||
892 | |||
893 | /* close the current alignment */ | ||
894 | switch (cur_align) | ||
895 | { | ||
896 | case WPS_ALIGN_LEFT: | ||
897 | align->left = cur_align_start; | ||
898 | break; | ||
899 | |||
900 | case WPS_ALIGN_CENTER: | ||
901 | align->center = cur_align_start; | ||
902 | break; | ||
903 | |||
904 | case WPS_ALIGN_RIGHT: | ||
905 | align->right = cur_align_start; | ||
906 | break; | ||
907 | } | ||
908 | |||
909 | return update; | ||
910 | } | ||
911 | static void get_subline_timeout(struct gui_wps *gwps, struct skin_subline *subline) | ||
912 | { | ||
913 | struct wps_data *data = gwps->data; | ||
914 | int i; | ||
915 | subline->time_mult = DEFAULT_SUBLINE_TIME_MULTIPLIER; | ||
916 | |||
917 | for (i = subline->first_token_idx; | ||
918 | i <= subline->last_token_idx; i++) | ||
919 | { | ||
920 | switch(data->tokens[i].type) | ||
921 | { | ||
922 | case WPS_TOKEN_CONDITIONAL: | ||
923 | /* place ourselves in the right conditional case */ | ||
924 | evaluate_conditional(gwps, &i); | ||
925 | break; | ||
926 | |||
927 | case WPS_TOKEN_CONDITIONAL_OPTION: | ||
928 | /* we've finished in the curent conditional case, | ||
929 | skip to the end of the conditional structure */ | ||
930 | i = find_conditional_end(data, i); | ||
931 | break; | ||
932 | |||
933 | case WPS_TOKEN_SUBLINE_TIMEOUT: | ||
934 | subline->time_mult = data->tokens[i].value.i; | ||
935 | break; | ||
936 | |||
937 | default: | ||
938 | break; | ||
939 | } | ||
940 | } | ||
941 | } | 642 | } |
942 | 643 | ||
943 | /* Calculates which subline should be displayed for the specified line | ||
944 | Returns true iff the subline must be refreshed */ | ||
945 | static bool update_curr_subline(struct gui_wps *gwps, struct skin_line *line) | ||
946 | { | ||
947 | /* shortcut this whole thing if we need to reset the line completly */ | ||
948 | if (line->curr_subline == NULL) | ||
949 | { | ||
950 | line->subline_expire_time = current_tick; | ||
951 | line->curr_subline = &line->sublines; | ||
952 | if (!line->curr_subline->next) | ||
953 | { | ||
954 | line->subline_expire_time += 100*HZ; | ||
955 | } | ||
956 | else | ||
957 | { | ||
958 | get_subline_timeout(gwps, line->curr_subline); | ||
959 | line->subline_expire_time += TIMEOUT_UNIT*line->curr_subline->time_mult; | ||
960 | } | ||
961 | return true; | ||
962 | } | ||
963 | /* if time to advance to next sub-line */ | ||
964 | if (TIME_AFTER(current_tick, line->subline_expire_time - 1)) | ||
965 | { | ||
966 | /* if there is only one subline, there is no need to search for a new one */ | ||
967 | if (&line->sublines == line->curr_subline && | ||
968 | line->curr_subline->next == NULL) | ||
969 | { | ||
970 | line->subline_expire_time += 100 * HZ; | ||
971 | return false; | ||
972 | } | ||
973 | if (line->curr_subline->next) | ||
974 | line->curr_subline = line->curr_subline->next; | ||
975 | else | ||
976 | line->curr_subline = &line->sublines; | ||
977 | get_subline_timeout(gwps, line->curr_subline); | ||
978 | line->subline_expire_time = current_tick + TIMEOUT_UNIT*line->curr_subline->time_mult; | ||
979 | return true; | ||
980 | } | ||
981 | return false; | ||
982 | } | ||
983 | 644 | ||
984 | /* Display a line appropriately according to its alignment format. | 645 | /* Display a line appropriately according to its alignment format. |
985 | format_align contains the text, separated between left, center and right. | 646 | format_align contains the text, separated between left, center and right. |
986 | line is the index of the line on the screen. | 647 | line is the index of the line on the screen. |
987 | scroll indicates whether the line is a scrolling one or not. | 648 | scroll indicates whether the line is a scrolling one or not. |
988 | */ | 649 | */ |
989 | static void write_line(struct screen *display, | 650 | void write_line(struct screen *display, |
990 | struct align_pos *format_align, | 651 | struct align_pos *format_align, |
991 | int line, | 652 | int line, |
992 | bool scroll) | 653 | bool scroll) |
@@ -1143,244 +804,30 @@ static void write_line(struct screen *display, | |||
1143 | } | 804 | } |
1144 | } | 805 | } |
1145 | 806 | ||
1146 | static bool skin_redraw(struct gui_wps *gwps, unsigned refresh_mode) | 807 | #ifdef HAVE_LCD_BITMAP |
808 | void draw_peakmeters(struct gui_wps *gwps, int line_number, | ||
809 | struct viewport *viewport) | ||
1147 | { | 810 | { |
1148 | struct wps_data *data = gwps->data; | 811 | struct wps_data *data = gwps->data; |
1149 | struct screen *display = gwps->display; | 812 | if (!data->peak_meter_enabled) |
1150 | |||
1151 | if (!data || !display || !gwps->state) | ||
1152 | return false; | ||
1153 | |||
1154 | unsigned flags; | ||
1155 | char linebuf[MAX_PATH]; | ||
1156 | |||
1157 | struct align_pos align; | ||
1158 | align.left = NULL; | ||
1159 | align.center = NULL; | ||
1160 | align.right = NULL; | ||
1161 | |||
1162 | |||
1163 | struct skin_token_list *viewport_list; | ||
1164 | |||
1165 | bool update_line, new_subline_refresh; | ||
1166 | |||
1167 | /* reset to first subline if refresh all flag is set */ | ||
1168 | if (refresh_mode == WPS_REFRESH_ALL) | ||
1169 | { | 813 | { |
1170 | struct skin_line *line; | 814 | peak_meter_enable(false); |
1171 | struct skin_viewport *skin_viewport = find_viewport(VP_DEFAULT_LABEL, data); | ||
1172 | |||
1173 | if (!(skin_viewport->hidden_flags & VP_NEVER_VISIBLE)) | ||
1174 | { | ||
1175 | display->set_viewport(&skin_viewport->vp); | ||
1176 | display->clear_viewport(); | ||
1177 | } | ||
1178 | |||
1179 | for (viewport_list = data->viewports; | ||
1180 | viewport_list; viewport_list = viewport_list->next) | ||
1181 | { | ||
1182 | skin_viewport = | ||
1183 | (struct skin_viewport *)viewport_list->token->value.data; | ||
1184 | for(line = skin_viewport->lines; line; line = line->next) | ||
1185 | { | ||
1186 | line->curr_subline = NULL; | ||
1187 | } | ||
1188 | } | ||
1189 | } | 815 | } |
1190 | 816 | else | |
1191 | #ifdef HAVE_LCD_CHARCELLS | ||
1192 | int i; | ||
1193 | for (i = 0; i < 8; i++) | ||
1194 | { | ||
1195 | if (data->wps_progress_pat[i] == 0) | ||
1196 | data->wps_progress_pat[i] = display->get_locked_pattern(); | ||
1197 | } | ||
1198 | #endif | ||
1199 | |||
1200 | /* disable any viewports which are conditionally displayed. | ||
1201 | * If we are only refreshing the peak meter then don't change the viewport | ||
1202 | * enabled flags as this will stop scrolling. viewports cant be | ||
1203 | * toggled in this refresh mode anyway (FS#10215)*/ | ||
1204 | if (refresh_mode != WPS_REFRESH_PEAK_METER) | ||
1205 | { | ||
1206 | for (viewport_list = data->viewports; | ||
1207 | viewport_list; viewport_list = viewport_list->next) | ||
1208 | { | ||
1209 | struct skin_viewport *skin_viewport = | ||
1210 | (struct skin_viewport *)viewport_list->token->value.data; | ||
1211 | if (skin_viewport->hidden_flags&VP_NEVER_VISIBLE) | ||
1212 | { | ||
1213 | continue; | ||
1214 | } | ||
1215 | if (skin_viewport->hidden_flags&VP_DRAW_HIDEABLE) | ||
1216 | { | ||
1217 | if (skin_viewport->hidden_flags&VP_DRAW_HIDDEN) | ||
1218 | skin_viewport->hidden_flags |= VP_DRAW_WASHIDDEN; | ||
1219 | else | ||
1220 | skin_viewport->hidden_flags |= VP_DRAW_HIDDEN; | ||
1221 | } | ||
1222 | } | ||
1223 | } | ||
1224 | for (viewport_list = data->viewports; | ||
1225 | viewport_list; viewport_list = viewport_list->next) | ||
1226 | { | 817 | { |
1227 | struct skin_viewport *skin_viewport = | 818 | int h = font_get(viewport->font)->height; |
1228 | (struct skin_viewport *)viewport_list->token->value.data; | 819 | int peak_meter_y = line_number * h; |
1229 | unsigned vp_refresh_mode = refresh_mode; | ||
1230 | #if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1) | ||
1231 | skin_viewport->vp.fg_pattern = skin_viewport->start_fgcolour; | ||
1232 | skin_viewport->vp.bg_pattern = skin_viewport->start_bgcolour; | ||
1233 | #endif | ||
1234 | display->set_viewport(&skin_viewport->vp); | ||
1235 | |||
1236 | int hidden_vp = 0; | ||
1237 | 820 | ||
1238 | #ifdef HAVE_LCD_BITMAP | 821 | /* The user might decide to have the peak meter in the last |
1239 | /* Set images to not to be displayed */ | 822 | line so that it is only displayed if no status bar is |
1240 | struct skin_token_list *imglist = data->images; | 823 | visible. If so we neither want do draw nor enable the |
1241 | while (imglist) | 824 | peak meter. */ |
1242 | { | 825 | if (peak_meter_y + h <= viewport->y+viewport->height) { |
1243 | struct gui_img *img = (struct gui_img *)imglist->token->value.data; | 826 | peak_meter_enable(true); |
1244 | img->display = -1; | 827 | peak_meter_screen(gwps->display, 0, peak_meter_y, |
1245 | imglist = imglist->next; | 828 | MIN(h, viewport->y+viewport->height - peak_meter_y)); |
1246 | } | ||
1247 | #endif | ||
1248 | /* dont redraw the viewport if its disabled */ | ||
1249 | if (skin_viewport->hidden_flags&VP_NEVER_VISIBLE) | ||
1250 | { /* don't draw anything into this one */ | ||
1251 | vp_refresh_mode = 0; hidden_vp = true; | ||
1252 | } | ||
1253 | else if ((skin_viewport->hidden_flags&VP_DRAW_HIDDEN)) | ||
1254 | { | ||
1255 | if (!(skin_viewport->hidden_flags&VP_DRAW_WASHIDDEN)) | ||
1256 | display->scroll_stop(&skin_viewport->vp); | ||
1257 | skin_viewport->hidden_flags |= VP_DRAW_WASHIDDEN; | ||
1258 | continue; | ||
1259 | } | ||
1260 | else if (((skin_viewport->hidden_flags& | ||
1261 | (VP_DRAW_WASHIDDEN|VP_DRAW_HIDEABLE)) | ||
1262 | == (VP_DRAW_WASHIDDEN|VP_DRAW_HIDEABLE))) | ||
1263 | { | ||
1264 | vp_refresh_mode = WPS_REFRESH_ALL; | ||
1265 | skin_viewport->hidden_flags = VP_DRAW_HIDEABLE; | ||
1266 | } | ||
1267 | |||
1268 | if (vp_refresh_mode == WPS_REFRESH_ALL) | ||
1269 | { | ||
1270 | display->clear_viewport(); | ||
1271 | } | 829 | } |
1272 | |||
1273 | /* loop over the lines for this viewport */ | ||
1274 | struct skin_line *line; | ||
1275 | /* %V() doesnt eat the \n which means the first line of text | ||
1276 | * is actually going to be one line down. so set line_count to -1 | ||
1277 | * unless we are using the default viewport which doesnt have this problem */ | ||
1278 | int line_count = skin_viewport->label==VP_DEFAULT_LABEL?0:-1; | ||
1279 | |||
1280 | for (line = skin_viewport->lines; line; line = line->next, line_count++) | ||
1281 | { | ||
1282 | struct skin_subline *subline; | ||
1283 | memset(linebuf, 0, sizeof(linebuf)); | ||
1284 | update_line = false; | ||
1285 | |||
1286 | /* get current subline for the line */ | ||
1287 | new_subline_refresh = update_curr_subline(gwps, line); | ||
1288 | subline = line->curr_subline; | ||
1289 | flags = line->curr_subline->line_type; | ||
1290 | |||
1291 | if (vp_refresh_mode == WPS_REFRESH_ALL || (flags & vp_refresh_mode) | ||
1292 | || new_subline_refresh || hidden_vp) | ||
1293 | { | ||
1294 | /* get_line tells us if we need to update the line */ | ||
1295 | update_line = get_line(gwps, subline, &align, | ||
1296 | linebuf, sizeof(linebuf), vp_refresh_mode); | ||
1297 | } | ||
1298 | #ifdef HAVE_LCD_BITMAP | ||
1299 | /* peakmeter */ | ||
1300 | if (flags & vp_refresh_mode & WPS_REFRESH_PEAK_METER) | ||
1301 | { | ||
1302 | if (!data->peak_meter_enabled) | ||
1303 | { | ||
1304 | peak_meter_enable(false); | ||
1305 | } | ||
1306 | else | ||
1307 | { | ||
1308 | /* the peakmeter should be alone on its line */ | ||
1309 | update_line = false; | ||
1310 | |||
1311 | int h = font_get(skin_viewport->vp.font)->height; | ||
1312 | int peak_meter_y = line_count* h; | ||
1313 | |||
1314 | /* The user might decide to have the peak meter in the last | ||
1315 | line so that it is only displayed if no status bar is | ||
1316 | visible. If so we neither want do draw nor enable the | ||
1317 | peak meter. */ | ||
1318 | if (peak_meter_y + h <= skin_viewport->vp.y+skin_viewport->vp.height) { | ||
1319 | peak_meter_enable(true); | ||
1320 | peak_meter_screen(gwps->display, 0, peak_meter_y, | ||
1321 | MIN(h, skin_viewport->vp.y+skin_viewport->vp.height - peak_meter_y)); | ||
1322 | } | ||
1323 | } | ||
1324 | } | ||
1325 | |||
1326 | #else /* HAVE_LCD_CHARCELL */ | ||
1327 | |||
1328 | /* progressbar */ | ||
1329 | if (flags & vp_refresh_mode & WPS_REFRESH_PLAYER_PROGRESS) | ||
1330 | { | ||
1331 | if (data->full_line_progressbar) | ||
1332 | draw_player_fullbar(gwps, linebuf, sizeof(linebuf)); | ||
1333 | else | ||
1334 | draw_player_progress(gwps); | ||
1335 | } | ||
1336 | #endif | ||
1337 | |||
1338 | if (line_count>= 0 && update_line && !hidden_vp && | ||
1339 | /* conditionals clear the line which means if the %Vd is put into the default | ||
1340 | viewport there will be a blank line. | ||
1341 | To get around this we dont allow any actual drawing to happen in the | ||
1342 | deault vp if other vp's are defined */ | ||
1343 | ((skin_viewport->label != VP_DEFAULT_LABEL && viewport_list->next) || | ||
1344 | !viewport_list->next)) | ||
1345 | { | ||
1346 | if (flags & WPS_REFRESH_SCROLL) | ||
1347 | { | ||
1348 | /* if the line is a scrolling one we don't want to update | ||
1349 | too often, so that it has the time to scroll */ | ||
1350 | if ((vp_refresh_mode & WPS_REFRESH_SCROLL) || new_subline_refresh) | ||
1351 | write_line(display, &align, line_count, true); | ||
1352 | } | ||
1353 | else | ||
1354 | write_line(display, &align, line_count, false); | ||
1355 | } | ||
1356 | } | ||
1357 | #ifdef HAVE_LCD_BITMAP | ||
1358 | /* progressbar */ | ||
1359 | if (vp_refresh_mode & WPS_REFRESH_PLAYER_PROGRESS) | ||
1360 | { | ||
1361 | struct skin_token_list *bar = gwps->data->progressbars; | ||
1362 | while (bar) | ||
1363 | { | ||
1364 | struct progressbar *thisbar = (struct progressbar*)bar->token->value.data; | ||
1365 | if (thisbar->vp == &skin_viewport->vp && thisbar->draw) | ||
1366 | { | ||
1367 | draw_progressbar(gwps, thisbar); | ||
1368 | } | ||
1369 | bar = bar->next; | ||
1370 | } | ||
1371 | } | ||
1372 | /* Now display any images in this viewport */ | ||
1373 | if (!hidden_vp) | ||
1374 | wps_display_images(gwps, &skin_viewport->vp); | ||
1375 | #endif | ||
1376 | } | 830 | } |
1377 | |||
1378 | /* Restore the default viewport */ | ||
1379 | display->set_viewport(NULL); | ||
1380 | |||
1381 | display->update(); | ||
1382 | |||
1383 | return true; | ||
1384 | } | 831 | } |
1385 | 832 | ||
1386 | bool skin_has_sbs(enum screen_type screen, struct wps_data *data) | 833 | bool skin_has_sbs(enum screen_type screen, struct wps_data *data) |
@@ -1396,6 +843,7 @@ bool skin_has_sbs(enum screen_type screen, struct wps_data *data) | |||
1396 | #endif | 843 | #endif |
1397 | return draw; | 844 | return draw; |
1398 | } | 845 | } |
846 | #endif | ||
1399 | 847 | ||
1400 | /* do the button loop as often as required for the peak meters to update | 848 | /* do the button loop as often as required for the peak meters to update |
1401 | * with a good refresh rate. | 849 | * with a good refresh rate. |
@@ -1434,7 +882,7 @@ int skin_wait_for_action(struct gui_wps *gwps, int context, int timeout) | |||
1434 | FOR_NB_SCREENS(i) | 882 | FOR_NB_SCREENS(i) |
1435 | { | 883 | { |
1436 | if(gwps[i].data->peak_meter_enabled) | 884 | if(gwps[i].data->peak_meter_enabled) |
1437 | skin_update(&gwps[i], WPS_REFRESH_PEAK_METER); | 885 | skin_update(&gwps[i], SKIN_REFRESH_PEAK_METER); |
1438 | next_refresh += HZ / PEAK_METER_FPS; | 886 | next_refresh += HZ / PEAK_METER_FPS; |
1439 | } | 887 | } |
1440 | } | 888 | } |
diff --git a/apps/gui/skin_engine/skin_display.h b/apps/gui/skin_engine/skin_display.h new file mode 100644 index 0000000000..81274a7391 --- /dev/null +++ b/apps/gui/skin_engine/skin_display.h | |||
@@ -0,0 +1,59 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2002-2007 Björn Stenberg | ||
11 | * Copyright (C) 2007-2008 Nicolas Pennequin | ||
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 | #include "config.h" | ||
23 | #include <stdio.h> | ||
24 | #include "wps_internals.h" | ||
25 | #include "skin_engine.h" | ||
26 | #include "statusbar-skinned.h" | ||
27 | |||
28 | #ifndef _SKIN_DISPLAY_H_ | ||
29 | #define _SKIN_DISPLAY_H_ | ||
30 | |||
31 | |||
32 | #ifdef HAVE_LCD_BITMAP | ||
33 | void draw_progressbar(struct gui_wps *gwps, int line, struct progressbar *pb); | ||
34 | void draw_playlist_viewer_list(struct gui_wps *gwps, struct playlistviewer *viewer); | ||
35 | /* clears the area where the image was shown */ | ||
36 | void clear_image_pos(struct gui_wps *gwps, struct gui_img *img); | ||
37 | void wps_draw_image(struct gui_wps *gwps, struct gui_img *img, int subimage); | ||
38 | void wps_display_images(struct gui_wps *gwps, struct viewport* vp); | ||
39 | #else | ||
40 | bool draw_player_progress(struct gui_wps *gwps); | ||
41 | void draw_player_fullbar(struct gui_wps *gwps, char* buf, int buf_size); | ||
42 | #endif | ||
43 | |||
44 | /* Evaluate the conditional that is at *token_index and return whether a skip | ||
45 | has ocurred. *token_index is updated with the new position. | ||
46 | */ | ||
47 | int evaluate_conditional(struct gui_wps *gwps, struct conditional *conditional, int num_options); | ||
48 | /* Display a line appropriately according to its alignment format. | ||
49 | format_align contains the text, separated between left, center and right. | ||
50 | line is the index of the line on the screen. | ||
51 | scroll indicates whether the line is a scrolling one or not. | ||
52 | */ | ||
53 | void write_line(struct screen *display, | ||
54 | struct align_pos *format_align, | ||
55 | int line, | ||
56 | bool scroll); | ||
57 | void draw_peakmeters(struct gui_wps *gwps, int line_number, | ||
58 | struct viewport *viewport); | ||
59 | #endif | ||
diff --git a/apps/gui/skin_engine/skin_engine.h b/apps/gui/skin_engine/skin_engine.h index 69991ab587..9845d8ca8a 100644 --- a/apps/gui/skin_engine/skin_engine.h +++ b/apps/gui/skin_engine/skin_engine.h | |||
@@ -23,7 +23,10 @@ | |||
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" | 26 | #ifndef PLUGIN |
27 | |||
28 | #include "skin_fonts.h" | ||
29 | #include "tag_table.h" | ||
27 | 30 | ||
28 | #include "wps_internals.h" /* TODO: remove this line.. shoudlnt be needed */ | 31 | #include "wps_internals.h" /* TODO: remove this line.. shoudlnt be needed */ |
29 | 32 | ||
@@ -39,13 +42,37 @@ enum skinnable_screens { | |||
39 | }; | 42 | }; |
40 | 43 | ||
41 | 44 | ||
45 | #ifdef HAVE_LCD_BITMAP | ||
46 | #define MAIN_BUFFER ((2*LCD_HEIGHT*LCD_WIDTH*LCD_DEPTH/8) \ | ||
47 | + (SKINNABLE_SCREENS_COUNT * LCD_BACKDROP_BYTES)) | ||
48 | |||
49 | #if (NB_SCREENS > 1) | ||
50 | #define REMOTE_BUFFER (2*(LCD_REMOTE_HEIGHT*LCD_REMOTE_WIDTH*LCD_REMOTE_DEPTH/8) \ | ||
51 | + (SKINNABLE_SCREENS_COUNT * REMOTE_LCD_BACKDROP_BYTES)) | ||
52 | #else | ||
53 | #define REMOTE_BUFFER 0 | ||
54 | #endif | ||
55 | |||
56 | |||
57 | #define SKIN_BUFFER_SIZE (MAIN_BUFFER + REMOTE_BUFFER + SKIN_FONT_SIZE) + \ | ||
58 | (WPS_MAX_TOKENS * \ | ||
59 | (sizeof(struct wps_token) + (sizeof(struct skin_element)))) | ||
60 | #endif | ||
61 | |||
62 | #ifdef HAVE_LCD_CHARCELLS | ||
63 | #define SKIN_BUFFER_SIZE (LCD_HEIGHT * LCD_WIDTH) * 64 + \ | ||
64 | (WPS_MAX_TOKENS * \ | ||
65 | (sizeof(struct wps_token) + (sizeof(struct skin_element)))) | ||
66 | #endif | ||
67 | |||
68 | |||
42 | #ifdef HAVE_TOUCHSCREEN | 69 | #ifdef HAVE_TOUCHSCREEN |
43 | int skin_get_touchaction(struct wps_data *data, int* edge_offset); | 70 | int skin_get_touchaction(struct wps_data *data, int* edge_offset); |
44 | void skin_disarm_touchregions(struct wps_data *data); | 71 | void skin_disarm_touchregions(struct wps_data *data); |
45 | #endif | 72 | #endif |
46 | 73 | ||
47 | /* Do a update_type update of the skinned screen */ | 74 | /* Do a update_type update of the skinned screen */ |
48 | bool skin_update(struct gui_wps *gwps, unsigned int update_type); | 75 | void skin_update(struct gui_wps *gwps, unsigned int update_type); |
49 | 76 | ||
50 | /* | 77 | /* |
51 | * setup up the skin-data from a format-buffer (isfile = false) | 78 | * setup up the skin-data from a format-buffer (isfile = false) |
@@ -72,3 +99,5 @@ void skin_backdrop_init(void); | |||
72 | */ | 99 | */ |
73 | int skin_wait_for_action(struct gui_wps *gwps, int context, int timeout); | 100 | int skin_wait_for_action(struct gui_wps *gwps, int context, int timeout); |
74 | #endif | 101 | #endif |
102 | |||
103 | #endif | ||
diff --git a/apps/gui/skin_engine/skin_fonts.c b/apps/gui/skin_engine/skin_fonts.c index f446a9948b..92a6a22ccf 100644 --- a/apps/gui/skin_engine/skin_fonts.c +++ b/apps/gui/skin_engine/skin_fonts.c | |||
@@ -88,7 +88,7 @@ int skin_font_load(char* font_name) | |||
88 | pf = &font->font; | 88 | pf = &font->font; |
89 | if (!font->buffer) | 89 | if (!font->buffer) |
90 | { | 90 | { |
91 | pf->buffer_start = skin_buffer_alloc(SKIN_FONT_SIZE); | 91 | pf->buffer_start = (char*)skin_buffer_alloc(SKIN_FONT_SIZE); |
92 | if (!pf->buffer_start) | 92 | if (!pf->buffer_start) |
93 | return -1; | 93 | return -1; |
94 | font->buffer = pf->buffer_start; | 94 | font->buffer = pf->buffer_start; |
diff --git a/apps/gui/skin_engine/skin_fonts.h b/apps/gui/skin_engine/skin_fonts.h index 6e3634e740..2988b43415 100644 --- a/apps/gui/skin_engine/skin_fonts.h +++ b/apps/gui/skin_engine/skin_fonts.h | |||
@@ -27,7 +27,6 @@ | |||
27 | #include "file.h" | 27 | #include "file.h" |
28 | #include "settings.h" | 28 | #include "settings.h" |
29 | #include "font.h" | 29 | #include "font.h" |
30 | #include "skin_buffer.h" | ||
31 | 30 | ||
32 | #ifndef _SKINFONTS_H_ | 31 | #ifndef _SKINFONTS_H_ |
33 | #define _SKINFONTS_H_ | 32 | #define _SKINFONTS_H_ |
diff --git a/apps/gui/skin_engine/skin_parser.c b/apps/gui/skin_engine/skin_parser.c index a62791e397..52e7e1155c 100644 --- a/apps/gui/skin_engine/skin_parser.c +++ b/apps/gui/skin_engine/skin_parser.c | |||
@@ -8,6 +8,7 @@ | |||
8 | * $Id$ | 8 | * $Id$ |
9 | * | 9 | * |
10 | * Copyright (C) 2007 Nicolas Pennequin, Dan Everton, Matthias Mohr | 10 | * Copyright (C) 2007 Nicolas Pennequin, Dan Everton, Matthias Mohr |
11 | * 2010 Jonathan Gordon | ||
11 | * | 12 | * |
12 | * This program is free software; you can redistribute it and/or | 13 | * This program is free software; you can redistribute it and/or |
13 | * modify it under the terms of the GNU General Public License | 14 | * modify it under the terms of the GNU General Public License |
@@ -28,6 +29,10 @@ | |||
28 | #include "plugin.h" | 29 | #include "plugin.h" |
29 | #include "viewport.h" | 30 | #include "viewport.h" |
30 | 31 | ||
32 | #include "skin_buffer.h" | ||
33 | #include "skin_parser.h" | ||
34 | #include "tag_table.h" | ||
35 | |||
31 | #ifdef __PCTOOL__ | 36 | #ifdef __PCTOOL__ |
32 | #ifdef WPSEDITOR | 37 | #ifdef WPSEDITOR |
33 | #include "proxy.h" | 38 | #include "proxy.h" |
@@ -71,377 +76,29 @@ | |||
71 | 76 | ||
72 | #define WPS_ERROR_INVALID_PARAM -1 | 77 | #define WPS_ERROR_INVALID_PARAM -1 |
73 | 78 | ||
74 | /* which screen are we parsing for? */ | ||
75 | static enum screen_type curr_screen; | ||
76 | |||
77 | /* level of current conditional. | ||
78 | -1 means we're not in a conditional. */ | ||
79 | static int level = -1; | ||
80 | |||
81 | /* index of the last WPS_TOKEN_CONDITIONAL_OPTION | ||
82 | or WPS_TOKEN_CONDITIONAL_START in current level */ | ||
83 | static int lastcond[WPS_MAX_COND_LEVEL]; | ||
84 | |||
85 | /* index of the WPS_TOKEN_CONDITIONAL in current level */ | ||
86 | static int condindex[WPS_MAX_COND_LEVEL]; | ||
87 | |||
88 | /* number of condtional options in current level */ | ||
89 | static int numoptions[WPS_MAX_COND_LEVEL]; | ||
90 | |||
91 | /* line number, debug only */ | ||
92 | static int line_number; | ||
93 | |||
94 | /* the current viewport */ | ||
95 | static struct skin_viewport *curr_vp; | ||
96 | /* the current line, linked to the above viewport */ | ||
97 | static struct skin_line *curr_line; | ||
98 | |||
99 | static int follow_lang_direction = 0; | ||
100 | |||
101 | #if defined(DEBUG) || defined(SIMULATOR) | ||
102 | /* debugging function */ | ||
103 | extern void print_debug_info(struct wps_data *data, int fail, int line); | ||
104 | extern void debug_skin_usage(void); | ||
105 | #endif | ||
106 | |||
107 | /* Function for parsing of details for a token. At the moment the | ||
108 | function is called, the token type has already been set. The | ||
109 | function must fill in the details and possibly add more tokens | ||
110 | to the token array. It should return the number of chars that | ||
111 | has been consumed. | ||
112 | |||
113 | wps_bufptr points to the char following the tag (i.e. where | ||
114 | details begin). | ||
115 | token is the pointer to the 'main' token being parsed | ||
116 | */ | ||
117 | typedef int (*wps_tag_parse_func)(const char *wps_bufptr, | ||
118 | struct wps_token *token, struct wps_data *wps_data); | ||
119 | |||
120 | struct wps_tag { | ||
121 | enum wps_token_type type; | ||
122 | const char name[3]; | ||
123 | unsigned char refresh_type; | ||
124 | const wps_tag_parse_func parse_func; | ||
125 | }; | ||
126 | static int skip_end_of_line(const char *wps_bufptr); | ||
127 | /* prototypes of all special parse functions : */ | ||
128 | static int parse_timeout(const char *wps_bufptr, | ||
129 | struct wps_token *token, struct wps_data *wps_data); | ||
130 | static int parse_progressbar(const char *wps_bufptr, | ||
131 | struct wps_token *token, struct wps_data *wps_data); | ||
132 | static int parse_dir_level(const char *wps_bufptr, | ||
133 | struct wps_token *token, struct wps_data *wps_data); | ||
134 | static int parse_setting_and_lang(const char *wps_bufptr, | ||
135 | struct wps_token *token, struct wps_data *wps_data); | ||
136 | |||
137 | |||
138 | static int parse_languagedirection(const char *wps_bufptr, | ||
139 | struct wps_token *token, struct wps_data *wps_data) | ||
140 | { | ||
141 | (void)wps_bufptr; | ||
142 | (void)token; | ||
143 | (void)wps_data; | ||
144 | follow_lang_direction = 2; /* 2 because it is decremented immediatly after | ||
145 | this token is parsed, after the next token it | ||
146 | will be 0 again. */ | ||
147 | return 0; | ||
148 | } | ||
149 | 79 | ||
150 | #ifdef HAVE_LCD_BITMAP | 80 | static bool isdefault(struct skin_tag_parameter *param) |
151 | static int parse_viewport_display(const char *wps_bufptr, | ||
152 | struct wps_token *token, struct wps_data *wps_data); | ||
153 | static int parse_playlistview(const char *wps_bufptr, | ||
154 | struct wps_token *token, struct wps_data *wps_data); | ||
155 | static int parse_viewport(const char *wps_bufptr, | ||
156 | struct wps_token *token, struct wps_data *wps_data); | ||
157 | static int parse_statusbar_enable(const char *wps_bufptr, | ||
158 | struct wps_token *token, struct wps_data *wps_data); | ||
159 | static int parse_statusbar_disable(const char *wps_bufptr, | ||
160 | struct wps_token *token, struct wps_data *wps_data); | ||
161 | static int parse_statusbar_inbuilt(const char *wps_bufptr, | ||
162 | struct wps_token *token, struct wps_data *wps_data); | ||
163 | static int parse_image_display(const char *wps_bufptr, | ||
164 | struct wps_token *token, struct wps_data *wps_data); | ||
165 | static int parse_image_load(const char *wps_bufptr, | ||
166 | struct wps_token *token, struct wps_data *wps_data); | ||
167 | static int parse_font_load(const char *wps_bufptr, | ||
168 | struct wps_token *token, struct wps_data *wps_data); | ||
169 | #endif /*HAVE_LCD_BITMAP */ | ||
170 | #if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)) | ||
171 | static int parse_viewportcolour(const char *wps_bufptr, | ||
172 | struct wps_token *token, struct wps_data *wps_data); | ||
173 | static int parse_image_special(const char *wps_bufptr, | ||
174 | struct wps_token *token, struct wps_data *wps_data); | ||
175 | #endif | ||
176 | #ifdef HAVE_ALBUMART | ||
177 | static int parse_albumart_load(const char *wps_bufptr, | ||
178 | struct wps_token *token, struct wps_data *wps_data); | ||
179 | static int parse_albumart_display(const char *wps_bufptr, | ||
180 | struct wps_token *token, struct wps_data *wps_data); | ||
181 | #endif /* HAVE_ALBUMART */ | ||
182 | #ifdef HAVE_TOUCHSCREEN | ||
183 | static int parse_touchregion(const char *wps_bufptr, | ||
184 | struct wps_token *token, struct wps_data *wps_data); | ||
185 | #else | ||
186 | static int fulline_tag_not_supported(const char *wps_bufptr, | ||
187 | struct wps_token *token, struct wps_data *wps_data) | ||
188 | { | 81 | { |
189 | (void)token; (void)wps_data; | 82 | return param->type == DEFAULT; |
190 | return skip_end_of_line(wps_bufptr); | ||
191 | } | 83 | } |
192 | #define parse_touchregion fulline_tag_not_supported | ||
193 | #endif | ||
194 | #ifdef CONFIG_RTC | ||
195 | #define WPS_RTC_REFRESH WPS_REFRESH_DYNAMIC | ||
196 | #else | ||
197 | #define WPS_RTC_REFRESH WPS_REFRESH_STATIC | ||
198 | #endif | ||
199 | 84 | ||
200 | /* array of available tags - those with more characters have to go first | ||
201 | (e.g. "xl" and "xd" before "x"). It needs to end with the unknown token. */ | ||
202 | static const struct wps_tag all_tags[] = { | ||
203 | |||
204 | { WPS_TOKEN_ALIGN_CENTER, "ac", 0, NULL }, | ||
205 | { WPS_TOKEN_ALIGN_LEFT, "al", 0, NULL }, | ||
206 | { WPS_TOKEN_ALIGN_LEFT_RTL, "aL", 0, NULL }, | ||
207 | { WPS_TOKEN_ALIGN_RIGHT, "ar", 0, NULL }, | ||
208 | { WPS_TOKEN_ALIGN_RIGHT_RTL, "aR", 0, NULL }, | ||
209 | { WPS_NO_TOKEN, "ax", 0, parse_languagedirection }, | ||
210 | |||
211 | { WPS_TOKEN_BATTERY_PERCENT, "bl", WPS_REFRESH_DYNAMIC, parse_progressbar }, | ||
212 | { WPS_TOKEN_BATTERY_VOLTS, "bv", WPS_REFRESH_DYNAMIC, NULL }, | ||
213 | { WPS_TOKEN_BATTERY_TIME, "bt", WPS_REFRESH_DYNAMIC, NULL }, | ||
214 | { WPS_TOKEN_BATTERY_SLEEPTIME, "bs", WPS_REFRESH_DYNAMIC, NULL }, | ||
215 | #if CONFIG_CHARGING >= CHARGING_MONITOR | ||
216 | { WPS_TOKEN_BATTERY_CHARGING, "bc", WPS_REFRESH_DYNAMIC, NULL }, | ||
217 | #endif | ||
218 | #if CONFIG_CHARGING | ||
219 | { WPS_TOKEN_BATTERY_CHARGER_CONNECTED,"bp", WPS_REFRESH_DYNAMIC, NULL }, | ||
220 | #endif | ||
221 | #ifdef HAVE_USB_POWER | ||
222 | { WPS_TOKEN_USB_POWERED, "bu", WPS_REFRESH_DYNAMIC, NULL }, | ||
223 | #endif | ||
224 | 85 | ||
225 | { WPS_TOKEN_RTC_PRESENT , "cc", WPS_REFRESH_STATIC, NULL }, | 86 | /* which screen are we parsing for? */ |
226 | { WPS_TOKEN_RTC_DAY_OF_MONTH, "cd", WPS_RTC_REFRESH, NULL }, | 87 | static enum screen_type curr_screen; |
227 | { WPS_TOKEN_RTC_DAY_OF_MONTH_BLANK_PADDED,"ce", WPS_RTC_REFRESH, NULL }, | ||
228 | { WPS_TOKEN_RTC_12HOUR_CFG, "cf", WPS_RTC_REFRESH, NULL }, | ||
229 | { WPS_TOKEN_RTC_HOUR_24_ZERO_PADDED, "cH", WPS_RTC_REFRESH, NULL }, | ||
230 | { WPS_TOKEN_RTC_HOUR_24, "ck", WPS_RTC_REFRESH, NULL }, | ||
231 | { WPS_TOKEN_RTC_HOUR_12_ZERO_PADDED, "cI", WPS_RTC_REFRESH, NULL }, | ||
232 | { WPS_TOKEN_RTC_HOUR_12, "cl", WPS_RTC_REFRESH, NULL }, | ||
233 | { WPS_TOKEN_RTC_MONTH, "cm", WPS_RTC_REFRESH, NULL }, | ||
234 | { WPS_TOKEN_RTC_MINUTE, "cM", WPS_RTC_REFRESH, NULL }, | ||
235 | { WPS_TOKEN_RTC_SECOND, "cS", WPS_RTC_REFRESH, NULL }, | ||
236 | { WPS_TOKEN_RTC_YEAR_2_DIGITS, "cy", WPS_RTC_REFRESH, NULL }, | ||
237 | { WPS_TOKEN_RTC_YEAR_4_DIGITS, "cY", WPS_RTC_REFRESH, NULL }, | ||
238 | { WPS_TOKEN_RTC_AM_PM_UPPER, "cP", WPS_RTC_REFRESH, NULL }, | ||
239 | { WPS_TOKEN_RTC_AM_PM_LOWER, "cp", WPS_RTC_REFRESH, NULL }, | ||
240 | { WPS_TOKEN_RTC_WEEKDAY_NAME, "ca", WPS_RTC_REFRESH, NULL }, | ||
241 | { WPS_TOKEN_RTC_MONTH_NAME, "cb", WPS_RTC_REFRESH, NULL }, | ||
242 | { WPS_TOKEN_RTC_DAY_OF_WEEK_START_MON, "cu", WPS_RTC_REFRESH, NULL }, | ||
243 | { WPS_TOKEN_RTC_DAY_OF_WEEK_START_SUN, "cw", WPS_RTC_REFRESH, NULL }, | ||
244 | |||
245 | /* current file */ | ||
246 | { WPS_TOKEN_FILE_BITRATE, "fb", WPS_REFRESH_STATIC, NULL }, | ||
247 | { WPS_TOKEN_FILE_CODEC, "fc", WPS_REFRESH_STATIC, NULL }, | ||
248 | { WPS_TOKEN_FILE_FREQUENCY, "ff", WPS_REFRESH_STATIC, NULL }, | ||
249 | { WPS_TOKEN_FILE_FREQUENCY_KHZ, "fk", WPS_REFRESH_STATIC, NULL }, | ||
250 | { WPS_TOKEN_FILE_NAME_WITH_EXTENSION, "fm", WPS_REFRESH_STATIC, NULL }, | ||
251 | { WPS_TOKEN_FILE_NAME, "fn", WPS_REFRESH_STATIC, NULL }, | ||
252 | { WPS_TOKEN_FILE_PATH, "fp", WPS_REFRESH_STATIC, NULL }, | ||
253 | { WPS_TOKEN_FILE_SIZE, "fs", WPS_REFRESH_STATIC, NULL }, | ||
254 | { WPS_TOKEN_FILE_VBR, "fv", WPS_REFRESH_STATIC, NULL }, | ||
255 | { WPS_TOKEN_FILE_DIRECTORY, "d", WPS_REFRESH_STATIC, | ||
256 | parse_dir_level }, | ||
257 | |||
258 | /* next file */ | ||
259 | { WPS_TOKEN_FILE_BITRATE, "Fb", WPS_REFRESH_STATIC, NULL }, | ||
260 | { WPS_TOKEN_FILE_CODEC, "Fc", WPS_REFRESH_STATIC, NULL }, | ||
261 | { WPS_TOKEN_FILE_FREQUENCY, "Ff", WPS_REFRESH_STATIC, NULL }, | ||
262 | { WPS_TOKEN_FILE_FREQUENCY_KHZ, "Fk", WPS_REFRESH_STATIC, NULL }, | ||
263 | { WPS_TOKEN_FILE_NAME_WITH_EXTENSION, "Fm", WPS_REFRESH_STATIC, NULL }, | ||
264 | { WPS_TOKEN_FILE_NAME, "Fn", WPS_REFRESH_STATIC, NULL }, | ||
265 | { WPS_TOKEN_FILE_PATH, "Fp", WPS_REFRESH_STATIC, NULL }, | ||
266 | { WPS_TOKEN_FILE_SIZE, "Fs", WPS_REFRESH_STATIC, NULL }, | ||
267 | { WPS_TOKEN_FILE_VBR, "Fv", WPS_REFRESH_STATIC, NULL }, | ||
268 | { WPS_TOKEN_FILE_DIRECTORY, "D", WPS_REFRESH_STATIC, | ||
269 | parse_dir_level }, | ||
270 | |||
271 | /* current metadata */ | ||
272 | { WPS_TOKEN_METADATA_ARTIST, "ia", WPS_REFRESH_STATIC, NULL }, | ||
273 | { WPS_TOKEN_METADATA_COMPOSER, "ic", WPS_REFRESH_STATIC, NULL }, | ||
274 | { WPS_TOKEN_METADATA_ALBUM, "id", WPS_REFRESH_STATIC, NULL }, | ||
275 | { WPS_TOKEN_METADATA_ALBUM_ARTIST, "iA", WPS_REFRESH_STATIC, NULL }, | ||
276 | { WPS_TOKEN_METADATA_GROUPING, "iG", WPS_REFRESH_STATIC, NULL }, | ||
277 | { WPS_TOKEN_METADATA_GENRE, "ig", WPS_REFRESH_STATIC, NULL }, | ||
278 | { WPS_TOKEN_METADATA_DISC_NUMBER, "ik", WPS_REFRESH_STATIC, NULL }, | ||
279 | { WPS_TOKEN_METADATA_TRACK_NUMBER, "in", WPS_REFRESH_STATIC, NULL }, | ||
280 | { WPS_TOKEN_METADATA_TRACK_TITLE, "it", WPS_REFRESH_STATIC, NULL }, | ||
281 | { WPS_TOKEN_METADATA_VERSION, "iv", WPS_REFRESH_STATIC, NULL }, | ||
282 | { WPS_TOKEN_METADATA_YEAR, "iy", WPS_REFRESH_STATIC, NULL }, | ||
283 | { WPS_TOKEN_METADATA_COMMENT, "iC", WPS_REFRESH_STATIC, NULL }, | ||
284 | |||
285 | /* next metadata */ | ||
286 | { WPS_TOKEN_METADATA_ARTIST, "Ia", WPS_REFRESH_STATIC, NULL }, | ||
287 | { WPS_TOKEN_METADATA_COMPOSER, "Ic", WPS_REFRESH_STATIC, NULL }, | ||
288 | { WPS_TOKEN_METADATA_ALBUM, "Id", WPS_REFRESH_STATIC, NULL }, | ||
289 | { WPS_TOKEN_METADATA_ALBUM_ARTIST, "IA", WPS_REFRESH_STATIC, NULL }, | ||
290 | { WPS_TOKEN_METADATA_GROUPING, "IG", WPS_REFRESH_STATIC, NULL }, | ||
291 | { WPS_TOKEN_METADATA_GENRE, "Ig", WPS_REFRESH_STATIC, NULL }, | ||
292 | { WPS_TOKEN_METADATA_DISC_NUMBER, "Ik", WPS_REFRESH_STATIC, NULL }, | ||
293 | { WPS_TOKEN_METADATA_TRACK_NUMBER, "In", WPS_REFRESH_STATIC, NULL }, | ||
294 | { WPS_TOKEN_METADATA_TRACK_TITLE, "It", WPS_REFRESH_STATIC, NULL }, | ||
295 | { WPS_TOKEN_METADATA_VERSION, "Iv", WPS_REFRESH_STATIC, NULL }, | ||
296 | { WPS_TOKEN_METADATA_YEAR, "Iy", WPS_REFRESH_STATIC, NULL }, | ||
297 | { WPS_TOKEN_METADATA_COMMENT, "IC", WPS_REFRESH_STATIC, NULL }, | ||
298 | |||
299 | #if (CONFIG_CODEC != MAS3507D) | ||
300 | { WPS_TOKEN_SOUND_PITCH, "Sp", WPS_REFRESH_DYNAMIC, NULL }, | ||
301 | #endif | ||
302 | #if (CONFIG_CODEC == SWCODEC) | ||
303 | { WPS_TOKEN_SOUND_SPEED, "Ss", WPS_REFRESH_DYNAMIC, NULL }, | ||
304 | #endif | ||
305 | #if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD) | ||
306 | { WPS_TOKEN_VLED_HDD, "lh", WPS_REFRESH_DYNAMIC, NULL }, | ||
307 | #endif | ||
308 | |||
309 | { WPS_TOKEN_MAIN_HOLD, "mh", WPS_REFRESH_DYNAMIC, NULL }, | ||
310 | |||
311 | #ifdef HAS_REMOTE_BUTTON_HOLD | ||
312 | { WPS_TOKEN_REMOTE_HOLD, "mr", WPS_REFRESH_DYNAMIC, NULL }, | ||
313 | #else | ||
314 | { WPS_TOKEN_UNKNOWN, "mr", 0, NULL }, | ||
315 | #endif | ||
316 | |||
317 | { WPS_TOKEN_REPEAT_MODE, "mm", WPS_REFRESH_DYNAMIC, NULL }, | ||
318 | { WPS_TOKEN_PLAYBACK_STATUS, "mp", WPS_REFRESH_DYNAMIC, NULL }, | ||
319 | { WPS_TOKEN_BUTTON_VOLUME, "mv", WPS_REFRESH_DYNAMIC, | ||
320 | parse_timeout }, | ||
321 | |||
322 | #ifdef HAVE_LCD_BITMAP | ||
323 | { WPS_TOKEN_PEAKMETER, "pm", WPS_REFRESH_PEAK_METER, NULL }, | ||
324 | #else | ||
325 | { WPS_TOKEN_PLAYER_PROGRESSBAR, "pf", | ||
326 | WPS_REFRESH_DYNAMIC | WPS_REFRESH_PLAYER_PROGRESS, parse_progressbar }, | ||
327 | #endif | ||
328 | { WPS_TOKEN_PROGRESSBAR, "pb", WPS_REFRESH_PLAYER_PROGRESS, | ||
329 | parse_progressbar }, | ||
330 | |||
331 | { WPS_TOKEN_VOLUME, "pv", WPS_REFRESH_DYNAMIC, | ||
332 | parse_progressbar }, | ||
333 | |||
334 | { WPS_TOKEN_TRACK_ELAPSED_PERCENT, "px", WPS_REFRESH_DYNAMIC, NULL }, | ||
335 | { WPS_TOKEN_TRACK_TIME_ELAPSED, "pc", WPS_REFRESH_DYNAMIC, NULL }, | ||
336 | { WPS_TOKEN_TRACK_TIME_REMAINING, "pr", WPS_REFRESH_DYNAMIC, NULL }, | ||
337 | { WPS_TOKEN_TRACK_LENGTH, "pt", WPS_REFRESH_STATIC, NULL }, | ||
338 | { WPS_TOKEN_TRACK_STARTING, "pS", WPS_REFRESH_DYNAMIC, parse_timeout }, | ||
339 | { WPS_TOKEN_TRACK_ENDING, "pE", WPS_REFRESH_DYNAMIC, parse_timeout }, | ||
340 | |||
341 | { WPS_TOKEN_PLAYLIST_POSITION, "pp", WPS_REFRESH_STATIC, NULL }, | ||
342 | { WPS_TOKEN_PLAYLIST_ENTRIES, "pe", WPS_REFRESH_STATIC, NULL }, | ||
343 | { WPS_TOKEN_PLAYLIST_NAME, "pn", WPS_REFRESH_STATIC, NULL }, | ||
344 | { WPS_TOKEN_PLAYLIST_SHUFFLE, "ps", WPS_REFRESH_DYNAMIC, NULL }, | ||
345 | |||
346 | #ifdef HAVE_TAGCACHE | ||
347 | { WPS_TOKEN_DATABASE_PLAYCOUNT, "rp", WPS_REFRESH_DYNAMIC, NULL }, | ||
348 | { WPS_TOKEN_DATABASE_RATING, "rr", WPS_REFRESH_DYNAMIC, NULL }, | ||
349 | { WPS_TOKEN_DATABASE_AUTOSCORE, "ra", WPS_REFRESH_DYNAMIC, NULL }, | ||
350 | #endif | ||
351 | |||
352 | #if CONFIG_CODEC == SWCODEC | ||
353 | { WPS_TOKEN_REPLAYGAIN, "rg", WPS_REFRESH_STATIC, NULL }, | ||
354 | { WPS_TOKEN_CROSSFADE, "xf", WPS_REFRESH_DYNAMIC, NULL }, | ||
355 | #endif | ||
356 | |||
357 | { WPS_TOKEN_HAVE_TUNER, "tp", WPS_REFRESH_STATIC, NULL }, | ||
358 | #if CONFIG_TUNER /* Re-uses the 't' and 'T' prefixes, be careful about doubleups */ | ||
359 | { WPS_TOKEN_TUNER_TUNED, "tt", WPS_REFRESH_DYNAMIC, NULL }, | ||
360 | { WPS_TOKEN_TUNER_SCANMODE, "tm", WPS_REFRESH_DYNAMIC, NULL }, | ||
361 | { WPS_TOKEN_TUNER_STEREO, "ts", WPS_REFRESH_DYNAMIC, NULL }, | ||
362 | { WPS_TOKEN_TUNER_MINFREQ, "ta", WPS_REFRESH_STATIC, NULL }, | ||
363 | { WPS_TOKEN_TUNER_MAXFREQ, "tb", WPS_REFRESH_STATIC, NULL }, | ||
364 | { WPS_TOKEN_TUNER_CURFREQ, "tf", WPS_REFRESH_DYNAMIC, NULL }, | ||
365 | { WPS_TOKEN_PRESET_ID, "Ti", WPS_REFRESH_STATIC, NULL }, | ||
366 | { WPS_TOKEN_PRESET_NAME, "Tn", WPS_REFRESH_STATIC, NULL }, | ||
367 | { WPS_TOKEN_PRESET_FREQ, "Tf", WPS_REFRESH_STATIC, NULL }, | ||
368 | { WPS_TOKEN_PRESET_COUNT, "Tc", WPS_REFRESH_STATIC, NULL }, | ||
369 | { WPS_TOKEN_HAVE_RDS, "tx", WPS_REFRESH_STATIC, NULL }, | ||
370 | #ifdef HAVE_RDS_CAP | ||
371 | { WPS_TOKEN_RDS_NAME, "ty", WPS_REFRESH_DYNAMIC, NULL }, | ||
372 | { WPS_TOKEN_RDS_TEXT, "tz", WPS_REFRESH_DYNAMIC, NULL }, | ||
373 | #endif | ||
374 | #endif /* CONFIG_TUNER */ | ||
375 | |||
376 | { WPS_NO_TOKEN, "s", WPS_REFRESH_SCROLL, NULL }, | ||
377 | { WPS_TOKEN_SUBLINE_TIMEOUT, "t", 0, parse_timeout }, | ||
378 | 88 | ||
379 | #ifdef HAVE_LCD_BITMAP | 89 | /* the current viewport */ |
380 | { WPS_NO_TOKEN, "we", 0, parse_statusbar_enable }, | 90 | static struct skin_element *curr_viewport_element; |
381 | { WPS_NO_TOKEN, "wd", 0, parse_statusbar_disable }, | 91 | static struct skin_viewport *curr_vp; |
382 | { WPS_TOKEN_DRAW_INBUILTBAR, "wi", WPS_REFRESH_DYNAMIC, parse_statusbar_inbuilt }, | ||
383 | 92 | ||
384 | { WPS_NO_TOKEN, "xl", 0, parse_image_load }, | 93 | struct line *curr_line; |
385 | 94 | ||
386 | { WPS_TOKEN_IMAGE_PRELOAD_DISPLAY, "xd", WPS_REFRESH_STATIC, | 95 | static int follow_lang_direction = 0; |
387 | parse_image_display }, | ||
388 | 96 | ||
389 | { WPS_TOKEN_IMAGE_DISPLAY, "x", 0, parse_image_load }, | 97 | typedef int (*parse_function)(struct skin_element *element, |
390 | { WPS_NO_TOKEN, "Fl", 0, parse_font_load }, | 98 | struct wps_token *token, |
391 | #ifdef HAVE_ALBUMART | 99 | struct wps_data *wps_data); |
392 | { WPS_NO_TOKEN, "Cl", 0, parse_albumart_load }, | ||
393 | { WPS_TOKEN_ALBUMART_DISPLAY, "Cd", WPS_REFRESH_STATIC, parse_albumart_display }, | ||
394 | { WPS_TOKEN_ALBUMART_FOUND, "C", WPS_REFRESH_STATIC, NULL }, | ||
395 | #endif | ||
396 | 100 | ||
397 | { WPS_VIEWPORT_ENABLE, "Vd", WPS_REFRESH_DYNAMIC, | ||
398 | parse_viewport_display }, | ||
399 | { WPS_TOKEN_UIVIEWPORT_ENABLE, "VI", WPS_REFRESH_STATIC, | ||
400 | parse_viewport_display }, | ||
401 | #ifdef HAVE_LCD_BITMAP | 101 | #ifdef HAVE_LCD_BITMAP |
402 | { WPS_VIEWPORT_CUSTOMLIST, "Vp", WPS_REFRESH_STATIC, parse_playlistview }, | ||
403 | { WPS_TOKEN_LIST_TITLE_TEXT, "Lt", WPS_REFRESH_DYNAMIC, NULL }, | ||
404 | { WPS_TOKEN_LIST_TITLE_ICON, "Li", WPS_REFRESH_DYNAMIC, NULL }, | ||
405 | #endif | ||
406 | #if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)) | ||
407 | { WPS_TOKEN_VIEWPORT_FGCOLOUR, "Vf", WPS_REFRESH_STATIC, parse_viewportcolour }, | ||
408 | { WPS_TOKEN_VIEWPORT_BGCOLOUR, "Vb", WPS_REFRESH_STATIC, parse_viewportcolour }, | ||
409 | #endif | ||
410 | { WPS_NO_TOKEN, "V", 0, parse_viewport }, | ||
411 | |||
412 | #if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)) | ||
413 | { WPS_TOKEN_IMAGE_BACKDROP, "X", 0, parse_image_special }, | ||
414 | #endif | ||
415 | #endif | ||
416 | |||
417 | { WPS_TOKEN_SETTING, "St", WPS_REFRESH_DYNAMIC, | ||
418 | parse_setting_and_lang }, | ||
419 | { WPS_TOKEN_TRANSLATEDSTRING, "Sx", WPS_REFRESH_STATIC, | ||
420 | parse_setting_and_lang }, | ||
421 | { WPS_TOKEN_LANG_IS_RTL , "Sr", WPS_REFRESH_STATIC, NULL }, | ||
422 | |||
423 | { WPS_TOKEN_LASTTOUCH, "Tl", WPS_REFRESH_DYNAMIC, parse_timeout }, | ||
424 | { WPS_TOKEN_CURRENT_SCREEN, "cs", WPS_REFRESH_DYNAMIC, NULL }, | ||
425 | { WPS_NO_TOKEN, "T", 0, parse_touchregion }, | ||
426 | |||
427 | |||
428 | /* Recording Tokens */ | ||
429 | { WPS_TOKEN_HAVE_RECORDING, "Rp", WPS_REFRESH_STATIC, NULL }, | ||
430 | #ifdef HAVE_RECORDING | ||
431 | { WPS_TOKEN_IS_RECORDING, "Rr", WPS_REFRESH_DYNAMIC, NULL }, | ||
432 | { WPS_TOKEN_REC_FREQ, "Rf", WPS_REFRESH_DYNAMIC, NULL }, | ||
433 | { WPS_TOKEN_REC_ENCODER, "Re", WPS_REFRESH_DYNAMIC, NULL }, | ||
434 | { WPS_TOKEN_REC_BITRATE, "Rb", WPS_REFRESH_DYNAMIC, NULL }, | ||
435 | { WPS_TOKEN_REC_MONO, "Rm", WPS_REFRESH_DYNAMIC, NULL }, | ||
436 | { WPS_TOKEN_REC_SECONDS, "Rs", WPS_REFRESH_DYNAMIC, NULL }, | ||
437 | { WPS_TOKEN_REC_MINUTES, "Rn", WPS_REFRESH_DYNAMIC, NULL }, | ||
438 | { WPS_TOKEN_REC_HOURS, "Rh", WPS_REFRESH_DYNAMIC, NULL }, | ||
439 | #endif | ||
440 | { WPS_TOKEN_UNKNOWN, "", 0, NULL } | ||
441 | /* the array MUST end with an empty string (first char is \0) */ | ||
442 | }; | ||
443 | |||
444 | |||
445 | /* add a skin_token_list item to the list chain. ALWAYS appended because some of the | 102 | /* add a skin_token_list item to the list chain. ALWAYS appended because some of the |
446 | * chains require the order to be kept. | 103 | * chains require the order to be kept. |
447 | */ | 104 | */ |
@@ -459,7 +116,6 @@ static void add_to_ll_chain(struct skin_token_list **list, struct skin_token_lis | |||
459 | } | 116 | } |
460 | 117 | ||
461 | /* traverse the image linked-list for an image */ | 118 | /* traverse the image linked-list for an image */ |
462 | #ifdef HAVE_LCD_BITMAP | ||
463 | struct gui_img* find_image(char label, struct wps_data *data) | 119 | struct gui_img* find_image(char label, struct wps_data *data) |
464 | { | 120 | { |
465 | struct skin_token_list *list = data->images; | 121 | struct skin_token_list *list = data->images; |
@@ -478,10 +134,10 @@ struct gui_img* find_image(char label, struct wps_data *data) | |||
478 | /* traverse the viewport linked list for a viewport */ | 134 | /* traverse the viewport linked list for a viewport */ |
479 | struct skin_viewport* find_viewport(char label, struct wps_data *data) | 135 | struct skin_viewport* find_viewport(char label, struct wps_data *data) |
480 | { | 136 | { |
481 | struct skin_token_list *list = data->viewports; | 137 | struct skin_element *list = data->tree; |
482 | while (list) | 138 | while (list) |
483 | { | 139 | { |
484 | struct skin_viewport *vp = (struct skin_viewport *)list->token->value.data; | 140 | struct skin_viewport *vp = (struct skin_viewport *)list->data; |
485 | if (vp->label == label) | 141 | if (vp->label == label) |
486 | return vp; | 142 | return vp; |
487 | list = list->next; | 143 | list = list->next; |
@@ -489,6 +145,7 @@ struct skin_viewport* find_viewport(char label, struct wps_data *data) | |||
489 | return NULL; | 145 | return NULL; |
490 | } | 146 | } |
491 | 147 | ||
148 | #ifdef HAVE_LCD_BITMAP | ||
492 | 149 | ||
493 | /* create and init a new wpsll item. | 150 | /* create and init a new wpsll item. |
494 | * passing NULL to token will alloc a new one. | 151 | * passing NULL to token will alloc a new one. |
@@ -498,9 +155,10 @@ struct skin_viewport* find_viewport(char label, struct wps_data *data) | |||
498 | static struct skin_token_list *new_skin_token_list_item(struct wps_token *token, | 155 | static struct skin_token_list *new_skin_token_list_item(struct wps_token *token, |
499 | void* token_data) | 156 | void* token_data) |
500 | { | 157 | { |
501 | struct skin_token_list *llitem = skin_buffer_alloc(sizeof(struct skin_token_list)); | 158 | struct skin_token_list *llitem = |
159 | (struct skin_token_list *)skin_buffer_alloc(sizeof(struct skin_token_list)); | ||
502 | if (!token) | 160 | if (!token) |
503 | token = skin_buffer_alloc(sizeof(struct wps_token)); | 161 | token = (struct wps_token*)skin_buffer_alloc(sizeof(struct wps_token)); |
504 | if (!llitem || !token) | 162 | if (!llitem || !token) |
505 | return NULL; | 163 | return NULL; |
506 | llitem->next = NULL; | 164 | llitem->next = NULL; |
@@ -510,108 +168,36 @@ static struct skin_token_list *new_skin_token_list_item(struct wps_token *token, | |||
510 | return llitem; | 168 | return llitem; |
511 | } | 169 | } |
512 | 170 | ||
513 | /* Returns the number of chars that should be skipped to jump | 171 | static int parse_statusbar_tags(struct skin_element* element, |
514 | immediately after the first eol, i.e. to the start of the next line */ | 172 | struct wps_token *token, |
515 | static int skip_end_of_line(const char *wps_bufptr) | 173 | struct wps_data *wps_data) |
516 | { | ||
517 | line_number++; | ||
518 | int skip = 0; | ||
519 | while(*(wps_bufptr + skip) != '\n') | ||
520 | skip++; | ||
521 | return ++skip; | ||
522 | } | ||
523 | |||
524 | /* Starts a new subline in the current line during parsing */ | ||
525 | static bool skin_start_new_subline(struct skin_line *line, int curr_token) | ||
526 | { | ||
527 | struct skin_subline *subline = skin_buffer_alloc(sizeof(struct skin_subline)); | ||
528 | if (!subline) | ||
529 | return false; | ||
530 | |||
531 | subline->first_token_idx = curr_token; | ||
532 | subline->next = NULL; | ||
533 | |||
534 | subline->line_type = 0; | ||
535 | subline->time_mult = 0; | ||
536 | |||
537 | line->curr_subline->last_token_idx = curr_token-1; | ||
538 | line->curr_subline->next = subline; | ||
539 | line->curr_subline = subline; | ||
540 | return true; | ||
541 | } | ||
542 | |||
543 | static bool skin_start_new_line(struct skin_viewport *vp, int curr_token) | ||
544 | { | 174 | { |
545 | struct skin_line *line = skin_buffer_alloc(sizeof(struct skin_line)); | 175 | (void)element; |
546 | struct skin_subline *subline = NULL; | 176 | if (token->type == SKIN_TOKEN_DRAW_INBUILTBAR) |
547 | if (!line) | ||
548 | return false; | ||
549 | |||
550 | /* init the subline */ | ||
551 | subline = &line->sublines; | ||
552 | subline->first_token_idx = curr_token; | ||
553 | subline->next = NULL; | ||
554 | subline->line_type = 0; | ||
555 | subline->time_mult = 0; | ||
556 | |||
557 | /* init the new line */ | ||
558 | line->curr_subline = &line->sublines; | ||
559 | line->next = NULL; | ||
560 | line->subline_expire_time = 0; | ||
561 | |||
562 | /* connect to curr_line and vp pointers. | ||
563 | * 1) close the previous lines subline | ||
564 | * 2) connect to vp pointer | ||
565 | * 3) connect to curr_line global pointer | ||
566 | */ | ||
567 | if (curr_line) | ||
568 | { | 177 | { |
569 | curr_line->curr_subline->last_token_idx = curr_token - 1; | 178 | token->value.data = (void*)&curr_vp->vp; |
570 | curr_line->next = line; | ||
571 | curr_line->curr_subline = NULL; | ||
572 | } | 179 | } |
573 | curr_line = line; | 180 | else |
574 | if (!vp->lines) | 181 | { |
575 | vp->lines = line; | 182 | struct skin_element *def_vp = wps_data->tree; |
576 | return true; | 183 | struct skin_viewport *default_vp = def_vp->data; |
577 | } | 184 | if (def_vp->params_count == 0) |
578 | 185 | { | |
579 | #ifdef HAVE_LCD_BITMAP | 186 | wps_data->wps_sb_tag = true; |
580 | 187 | wps_data->show_sb_on_wps = (token->type == SKIN_TOKEN_ENABLE_THEME); | |
581 | static int parse_statusbar_enable(const char *wps_bufptr, | 188 | } |
582 | struct wps_token *token, | 189 | if (wps_data->show_sb_on_wps) |
583 | struct wps_data *wps_data) | 190 | { |
584 | { | 191 | viewport_set_defaults(&default_vp->vp, curr_screen); |
585 | (void)token; /* Kill warnings */ | 192 | } |
586 | wps_data->wps_sb_tag = true; | 193 | else |
587 | wps_data->show_sb_on_wps = true; | 194 | { |
588 | struct skin_viewport *default_vp = find_viewport(VP_DEFAULT_LABEL, wps_data); | 195 | viewport_set_fullscreen(&default_vp->vp, curr_screen); |
589 | viewport_set_defaults(&default_vp->vp, curr_screen); | 196 | } |
590 | default_vp->vp.font = FONT_UI; | 197 | } |
591 | return skip_end_of_line(wps_bufptr); | 198 | return 0; |
592 | } | ||
593 | |||
594 | static int parse_statusbar_disable(const char *wps_bufptr, | ||
595 | struct wps_token *token, | ||
596 | struct wps_data *wps_data) | ||
597 | { | ||
598 | (void)token; /* Kill warnings */ | ||
599 | wps_data->wps_sb_tag = true; | ||
600 | wps_data->show_sb_on_wps = false; | ||
601 | struct skin_viewport *default_vp = find_viewport(VP_DEFAULT_LABEL, wps_data); | ||
602 | viewport_set_fullscreen(&default_vp->vp, curr_screen); | ||
603 | default_vp->vp.font = FONT_UI; | ||
604 | return skip_end_of_line(wps_bufptr); | ||
605 | } | ||
606 | |||
607 | static int parse_statusbar_inbuilt(const char *wps_bufptr, | ||
608 | struct wps_token *token, struct wps_data *wps_data) | ||
609 | { | ||
610 | (void)wps_data; | ||
611 | token->value.data = (void*)&curr_vp->vp; | ||
612 | return skip_end_of_line(wps_bufptr); | ||
613 | } | 199 | } |
614 | 200 | ||
615 | static int get_image_id(int c) | 201 | static int get_image_id(int c) |
616 | { | 202 | { |
617 | if(c >= 'a' && c <= 'z') | 203 | if(c >= 'a' && c <= 'z') |
@@ -625,32 +211,20 @@ static int get_image_id(int c) | |||
625 | char *get_image_filename(const char *start, const char* bmpdir, | 211 | char *get_image_filename(const char *start, const char* bmpdir, |
626 | char *buf, int buf_size) | 212 | char *buf, int buf_size) |
627 | { | 213 | { |
628 | const char *end = start; | 214 | snprintf(buf, buf_size, "%s/%s", bmpdir, start); |
629 | int bmpdirlen = strlen(bmpdir); | 215 | |
630 | |||
631 | while (*end && *end != ',' && *end != ')') | ||
632 | end++; | ||
633 | if ( !end || (end - start) >= (buf_size - bmpdirlen - 2) ) | ||
634 | { | ||
635 | buf[0] = '\0'; | ||
636 | return NULL; | ||
637 | } | ||
638 | |||
639 | strcpy(buf, bmpdir); | ||
640 | buf[bmpdirlen] = '/'; | ||
641 | memcpy( &buf[bmpdirlen + 1], start, end - start); | ||
642 | buf[bmpdirlen + 1 + end - start] = 0; | ||
643 | |||
644 | return buf; | 216 | return buf; |
645 | } | 217 | } |
646 | 218 | ||
647 | static int parse_image_display(const char *wps_bufptr, | 219 | static int parse_image_display(struct skin_element *element, |
648 | struct wps_token *token, | 220 | struct wps_token *token, |
649 | struct wps_data *wps_data) | 221 | struct wps_data *wps_data) |
650 | { | 222 | { |
651 | char label = wps_bufptr[1]; | 223 | char *text = element->params[0].data.text; |
224 | char label = text[0]; | ||
225 | char sublabel = text[1]; | ||
652 | int subimage; | 226 | int subimage; |
653 | struct gui_img *img;; | 227 | struct gui_img *img; |
654 | 228 | ||
655 | /* sanity check */ | 229 | /* sanity check */ |
656 | img = find_image(label, wps_data); | 230 | img = find_image(label, wps_data); |
@@ -660,7 +234,7 @@ static int parse_image_display(const char *wps_bufptr, | |||
660 | return WPS_ERROR_INVALID_PARAM; | 234 | return WPS_ERROR_INVALID_PARAM; |
661 | } | 235 | } |
662 | 236 | ||
663 | if ((subimage = get_image_id(wps_bufptr[2])) != -1) | 237 | if ((subimage = get_image_id(sublabel)) != -1) |
664 | { | 238 | { |
665 | if (subimage >= img->num_subimages) | 239 | if (subimage >= img->num_subimages) |
666 | return WPS_ERROR_INVALID_PARAM; | 240 | return WPS_ERROR_INVALID_PARAM; |
@@ -674,32 +248,24 @@ static int parse_image_display(const char *wps_bufptr, | |||
674 | } | 248 | } |
675 | } | 249 | } |
676 | 250 | ||
677 | static int parse_image_load(const char *wps_bufptr, | 251 | static int parse_image_load(struct skin_element *element, |
678 | struct wps_token *token, | 252 | struct wps_token *token, |
679 | struct wps_data *wps_data) | 253 | struct wps_data *wps_data) |
680 | { | 254 | { |
681 | const char *ptr = wps_bufptr; | ||
682 | const char* filename; | 255 | const char* filename; |
683 | const char* id; | 256 | const char* id; |
684 | int x,y; | 257 | int x,y; |
685 | struct gui_img *img; | 258 | struct gui_img *img; |
686 | 259 | ||
687 | /* format: %x|n|filename.bmp|x|y| | 260 | /* format: %x(n,filename.bmp,x,y) |
688 | or %xl|n|filename.bmp|x|y| | 261 | or %xl(n,filename.bmp,x,y) |
689 | or %xl|n|filename.bmp|x|y|num_subimages| | 262 | or %xl(n,filename.bmp,x,y,num_subimages) |
690 | */ | 263 | */ |
691 | 264 | ||
692 | if (*ptr != '(') | 265 | id = element->params[0].data.text; |
693 | return WPS_ERROR_INVALID_PARAM; | 266 | filename = element->params[1].data.text; |
694 | 267 | x = element->params[2].data.number; | |
695 | ptr++; | 268 | y = element->params[3].data.number; |
696 | |||
697 | if (!(ptr = parse_list("ssdd", NULL, ',', ptr, &id, &filename, &x, &y))) | ||
698 | return WPS_ERROR_INVALID_PARAM; | ||
699 | |||
700 | /* Check there is a terminating ) */ | ||
701 | if (*ptr != ')' && *ptr != ',') | ||
702 | return WPS_ERROR_INVALID_PARAM; | ||
703 | 269 | ||
704 | /* check the image number and load state */ | 270 | /* check the image number and load state */ |
705 | if(find_image(*id, wps_data)) | 271 | if(find_image(*id, wps_data)) |
@@ -707,7 +273,7 @@ static int parse_image_load(const char *wps_bufptr, | |||
707 | /* Invalid image ID */ | 273 | /* Invalid image ID */ |
708 | return WPS_ERROR_INVALID_PARAM; | 274 | return WPS_ERROR_INVALID_PARAM; |
709 | } | 275 | } |
710 | img = skin_buffer_alloc(sizeof(struct gui_img)); | 276 | img = (struct gui_img*)skin_buffer_alloc(sizeof(struct gui_img)); |
711 | if (!img) | 277 | if (!img) |
712 | return WPS_ERROR_INVALID_PARAM; | 278 | return WPS_ERROR_INVALID_PARAM; |
713 | /* save a pointer to the filename */ | 279 | /* save a pointer to the filename */ |
@@ -717,62 +283,44 @@ static int parse_image_load(const char *wps_bufptr, | |||
717 | img->y = y; | 283 | img->y = y; |
718 | img->num_subimages = 1; | 284 | img->num_subimages = 1; |
719 | img->always_display = false; | 285 | img->always_display = false; |
286 | // img->just_drawn = false; | ||
287 | img->display = -1; | ||
720 | 288 | ||
721 | /* save current viewport */ | 289 | /* save current viewport */ |
722 | img->vp = &curr_vp->vp; | 290 | img->vp = &curr_vp->vp; |
723 | 291 | ||
724 | if (token->type == WPS_TOKEN_IMAGE_DISPLAY) | 292 | if (token->type == SKIN_TOKEN_IMAGE_DISPLAY) |
725 | { | 293 | { |
726 | img->always_display = true; | 294 | img->always_display = true; |
727 | } | 295 | } |
728 | else if (*ptr == ',') | 296 | else if (element->params_count == 5) |
729 | { | 297 | { |
730 | /* Parse the (optional) number of sub-images */ | 298 | img->num_subimages = element->params[4].data.number; |
731 | ptr++; | ||
732 | img->num_subimages = atoi(ptr); | ||
733 | if (img->num_subimages <= 0) | 299 | if (img->num_subimages <= 0) |
734 | return WPS_ERROR_INVALID_PARAM; | 300 | return WPS_ERROR_INVALID_PARAM; |
735 | /* Check there is a terminating ) */ | ||
736 | while(isdigit(*ptr)) | ||
737 | ptr++; | ||
738 | if (*ptr != ')') | ||
739 | return WPS_ERROR_INVALID_PARAM; | ||
740 | } | 301 | } |
741 | struct skin_token_list *item = new_skin_token_list_item(NULL, img); | 302 | struct skin_token_list *item = |
303 | (struct skin_token_list *)new_skin_token_list_item(NULL, img); | ||
742 | if (!item) | 304 | if (!item) |
743 | return WPS_ERROR_INVALID_PARAM; | 305 | return WPS_ERROR_INVALID_PARAM; |
744 | add_to_ll_chain(&wps_data->images, item); | 306 | add_to_ll_chain(&wps_data->images, item); |
745 | 307 | ||
746 | /* Skip the rest of the line */ | 308 | return 0; |
747 | return skip_end_of_line(wps_bufptr); | ||
748 | } | 309 | } |
749 | struct skin_font { | 310 | struct skin_font { |
750 | int id; /* the id from font_load */ | 311 | int id; /* the id from font_load */ |
751 | char *name; /* filename without path and extension */ | 312 | char *name; /* filename without path and extension */ |
752 | }; | 313 | }; |
753 | static struct skin_font skinfonts[MAXUSERFONTS]; | 314 | static struct skin_font skinfonts[MAXUSERFONTS]; |
754 | static int parse_font_load(const char *wps_bufptr, | 315 | static int parse_font_load(struct skin_element *element, |
755 | struct wps_token *token, struct wps_data *wps_data) | 316 | struct wps_token *token, |
317 | struct wps_data *wps_data) | ||
756 | { | 318 | { |
757 | (void)wps_data; (void)token; | 319 | (void)wps_data; (void)token; |
758 | const char *ptr = wps_bufptr; | 320 | int id = element->params[0].data.number; |
759 | int id; | 321 | char *filename = element->params[1].data.text; |
760 | char *filename; | 322 | char *ptr; |
761 | 323 | ||
762 | if (*ptr != '(') | ||
763 | return WPS_ERROR_INVALID_PARAM; | ||
764 | |||
765 | ptr++; | ||
766 | |||
767 | if (!(ptr = parse_list("ds", NULL, ',', ptr, &id, &filename))) | ||
768 | return WPS_ERROR_INVALID_PARAM; | ||
769 | |||
770 | /* Check there is a terminating ) */ | ||
771 | if (*ptr != ')') | ||
772 | return WPS_ERROR_INVALID_PARAM; | ||
773 | |||
774 | if (id <= FONT_UI || id >= MAXFONTS-1) | ||
775 | return WPS_ERROR_INVALID_PARAM; | ||
776 | #if defined(DEBUG) || defined(SIMULATOR) | 324 | #if defined(DEBUG) || defined(SIMULATOR) |
777 | if (skinfonts[id-FONT_FIRSTUSERFONT].name != NULL) | 325 | if (skinfonts[id-FONT_FIRSTUSERFONT].name != NULL) |
778 | { | 326 | { |
@@ -782,286 +330,65 @@ static int parse_font_load(const char *wps_bufptr, | |||
782 | /* make sure the filename contains .fnt, | 330 | /* make sure the filename contains .fnt, |
783 | * we dont actually use it, but require it anyway */ | 331 | * we dont actually use it, but require it anyway */ |
784 | ptr = strchr(filename, '.'); | 332 | ptr = strchr(filename, '.'); |
785 | if (!ptr || strncmp(ptr, ".fnt)", 5)) | 333 | if (!ptr || strncmp(ptr, ".fnt", 4)) |
786 | return WPS_ERROR_INVALID_PARAM; | 334 | return WPS_ERROR_INVALID_PARAM; |
787 | skinfonts[id-FONT_FIRSTUSERFONT].id = -1; | 335 | skinfonts[id-FONT_FIRSTUSERFONT].id = -1; |
788 | skinfonts[id-FONT_FIRSTUSERFONT].name = filename; | 336 | skinfonts[id-FONT_FIRSTUSERFONT].name = filename; |
789 | 337 | ||
790 | return skip_end_of_line(wps_bufptr); | 338 | return 0; |
791 | } | 339 | } |
792 | 340 | ||
793 | 341 | ||
794 | static int parse_viewport_display(const char *wps_bufptr, | ||
795 | struct wps_token *token, | ||
796 | struct wps_data *wps_data) | ||
797 | { | ||
798 | (void)wps_data; | ||
799 | char letter = wps_bufptr[1]; | ||
800 | |||
801 | if (letter < 'a' || letter > 'z') | ||
802 | { | ||
803 | /* invalid viewport tag */ | ||
804 | return WPS_ERROR_INVALID_PARAM; | ||
805 | } | ||
806 | token->value.i = letter; | ||
807 | return 3; | ||
808 | } | ||
809 | |||
810 | #ifdef HAVE_LCD_BITMAP | 342 | #ifdef HAVE_LCD_BITMAP |
811 | static int parse_playlistview_text(struct playlistviewer *viewer, | ||
812 | enum info_line_type line, char* text) | ||
813 | { | ||
814 | int cur_string = 0; | ||
815 | const struct wps_tag *tag; | ||
816 | int taglen = 0; | ||
817 | const char *start = text; | ||
818 | if (*text != ',') | ||
819 | return -1; | ||
820 | text++; | ||
821 | viewer->lines[line].count = 0; | ||
822 | viewer->lines[line].scroll = false; | ||
823 | while (*text != ',' && *text != ')') | ||
824 | { | ||
825 | if (*text == '%') /* it is a token of some type */ | ||
826 | { | ||
827 | text++; | ||
828 | taglen = 0; | ||
829 | switch(*text) | ||
830 | { | ||
831 | case '%': | ||
832 | case '<': | ||
833 | case '|': | ||
834 | case '>': | ||
835 | case ';': | ||
836 | case '#': | ||
837 | case '(': | ||
838 | case ')': | ||
839 | case ',': | ||
840 | /* escaped characters */ | ||
841 | viewer->lines[line].tokens[viewer->lines[line].count++] = WPS_TOKEN_CHARACTER; | ||
842 | viewer->lines[line].strings[cur_string][0] = *text; | ||
843 | viewer->lines[line].strings[cur_string++][1] = '\0'; | ||
844 | text++; | ||
845 | break; | ||
846 | default: | ||
847 | for (tag = all_tags; | ||
848 | strncmp(text, tag->name, strlen(tag->name)) != 0; | ||
849 | tag++) ; | ||
850 | /* %s isnt stored as a tag so manually check for it */ | ||
851 | if (tag->type == WPS_NO_TOKEN) | ||
852 | { | ||
853 | if (!strncmp(tag->name, "s", 1)) | ||
854 | { | ||
855 | viewer->lines[line].scroll = true; | ||
856 | taglen = 1; | ||
857 | } | ||
858 | } | ||
859 | else if (tag->type == WPS_TOKEN_UNKNOWN) | ||
860 | { | ||
861 | int i = 0; | ||
862 | /* just copy the string */ | ||
863 | viewer->lines[line].tokens[viewer->lines[line].count++] = WPS_TOKEN_STRING; | ||
864 | while (i<(MAX_PLAYLISTLINE_STRLEN-1) && text[i] != ',' && text[i] != ')' && text[i] != '%') | ||
865 | { | ||
866 | viewer->lines[line].strings[cur_string][i] = text[i]; | ||
867 | i++; | ||
868 | } | ||
869 | viewer->lines[line].strings[cur_string][i] = '\0'; | ||
870 | cur_string++; | ||
871 | taglen = i; | ||
872 | } | ||
873 | else | ||
874 | { | ||
875 | if (tag->parse_func) | ||
876 | { | ||
877 | /* unsupported tag, reject */ | ||
878 | return -1; | ||
879 | } | ||
880 | taglen = strlen(tag->name); | ||
881 | viewer->lines[line].tokens[viewer->lines[line].count++] = tag->type; | ||
882 | } | ||
883 | text += taglen; | ||
884 | } | ||
885 | } | ||
886 | else | ||
887 | { | ||
888 | /* regular string */ | ||
889 | int i = 0; | ||
890 | /* just copy the string */ | ||
891 | viewer->lines[line].tokens[viewer->lines[line].count++] = WPS_TOKEN_STRING; | ||
892 | while (i<(MAX_PLAYLISTLINE_STRLEN-1) && text[i] != ',' && text[i] != ')' && text[i] != '%') | ||
893 | { | ||
894 | viewer->lines[line].strings[cur_string][i] = text[i]; | ||
895 | i++; | ||
896 | } | ||
897 | viewer->lines[line].strings[cur_string][i] = '\0'; | ||
898 | cur_string++; | ||
899 | text += i; | ||
900 | } | ||
901 | } | ||
902 | return text - start; | ||
903 | } | ||
904 | 343 | ||
905 | static int parse_playlistview(const char *wps_bufptr, | 344 | static int parse_playlistview(struct skin_element *element, |
906 | struct wps_token *token, struct wps_data *wps_data) | 345 | struct wps_token *token, |
346 | struct wps_data *wps_data) | ||
907 | { | 347 | { |
908 | (void)wps_data; | 348 | (void)wps_data; |
909 | /* %Vp|<use icons>|<start offset>|info line text|no info text| */ | 349 | struct playlistviewer *viewer = |
910 | struct playlistviewer *viewer = skin_buffer_alloc(sizeof(struct playlistviewer)); | 350 | (struct playlistviewer *)skin_buffer_alloc(sizeof(struct playlistviewer)); |
911 | char *ptr = strchr(wps_bufptr, '('); | 351 | if (!viewer) |
912 | int length; | ||
913 | if (!viewer || !ptr) | ||
914 | return WPS_ERROR_INVALID_PARAM; | 352 | return WPS_ERROR_INVALID_PARAM; |
915 | viewer->vp = &curr_vp->vp; | 353 | viewer->vp = &curr_vp->vp; |
916 | viewer->show_icons = true; | 354 | viewer->show_icons = true; |
917 | viewer->start_offset = atoi(ptr+1); | 355 | viewer->start_offset = element->params[0].data.number; |
356 | viewer->lines[0] = element->params[1].data.code; | ||
357 | viewer->lines[1] = element->params[2].data.code; | ||
358 | |||
918 | token->value.data = (void*)viewer; | 359 | token->value.data = (void*)viewer; |
919 | ptr = strchr(ptr+1, ','); | 360 | |
920 | length = parse_playlistview_text(viewer, TRACK_HAS_INFO, ptr); | 361 | return 0; |
921 | if (length < 0) | ||
922 | return WPS_ERROR_INVALID_PARAM; | ||
923 | length = parse_playlistview_text(viewer, TRACK_HAS_NO_INFO, ptr+length); | ||
924 | if (length < 0) | ||
925 | return WPS_ERROR_INVALID_PARAM; | ||
926 | |||
927 | return skip_end_of_line(wps_bufptr); | ||
928 | } | 362 | } |
929 | #endif | 363 | #endif |
930 | 364 | ||
931 | static int parse_viewport(const char *wps_bufptr, | ||
932 | struct wps_token *token, | ||
933 | struct wps_data *wps_data) | ||
934 | { | ||
935 | (void)token; /* Kill warnings */ | ||
936 | const char *ptr = wps_bufptr; | ||
937 | |||
938 | struct skin_viewport *skin_vp = skin_buffer_alloc(sizeof(struct skin_viewport)); | ||
939 | |||
940 | /* check for the optional letter to signify its a hideable viewport */ | ||
941 | /* %Vl|<label>|<rest of tags>| */ | ||
942 | skin_vp->hidden_flags = 0; | ||
943 | skin_vp->label = VP_NO_LABEL; | ||
944 | skin_vp->lines = NULL; | ||
945 | if (curr_line) | ||
946 | { | ||
947 | curr_line->curr_subline->last_token_idx = wps_data->num_tokens | ||
948 | - (wps_data->num_tokens > 0 ? 1 : 0); | ||
949 | } | ||
950 | |||
951 | curr_line = NULL; | ||
952 | if (!skin_start_new_line(skin_vp, wps_data->num_tokens)) | ||
953 | return WPS_ERROR_INVALID_PARAM; | ||
954 | |||
955 | if (*ptr == 'i') | ||
956 | { | ||
957 | if (*(ptr+1) == '(') | ||
958 | { | ||
959 | char label = *(ptr+2); | ||
960 | if (label >= 'a' && label <= 'z') | ||
961 | { | ||
962 | skin_vp->hidden_flags = VP_NEVER_VISIBLE; | ||
963 | skin_vp->label = VP_INFO_LABEL|label; | ||
964 | ptr += 3; | ||
965 | } | ||
966 | else | ||
967 | { | ||
968 | if (label != '-') | ||
969 | return WPS_ERROR_INVALID_PARAM; | ||
970 | skin_vp->label = VP_INFO_LABEL|VP_DEFAULT_LABEL; | ||
971 | skin_vp->hidden_flags = VP_NEVER_VISIBLE; | ||
972 | ptr += 3; | ||
973 | } | ||
974 | } | ||
975 | else | ||
976 | return WPS_ERROR_INVALID_PARAM; /* malformed token: e.g. %Cl7 */ | ||
977 | } | ||
978 | else if (*ptr == 'l') | ||
979 | { | ||
980 | if (*(ptr+1) == '(') | ||
981 | { | ||
982 | char label = *(ptr+2); | ||
983 | if (label >= 'a' && label <= 'z') | ||
984 | { | ||
985 | skin_vp->hidden_flags = VP_DRAW_HIDEABLE; | ||
986 | skin_vp->label = label; | ||
987 | } | ||
988 | else | ||
989 | return WPS_ERROR_INVALID_PARAM; /* malformed token: e.g. %Cl7 */ | ||
990 | ptr += 3; | ||
991 | } | ||
992 | } | ||
993 | if (*ptr != ',' && *ptr != '(') | ||
994 | return WPS_ERROR_INVALID_PARAM; | ||
995 | |||
996 | ptr++; | ||
997 | struct viewport *vp = &skin_vp->vp; | ||
998 | /* format: %V|x|y|width|height|font| */ | ||
999 | if (!(ptr = viewport_parse_viewport(vp, curr_screen, ptr, ','))) | ||
1000 | return WPS_ERROR_INVALID_PARAM; | ||
1001 | |||
1002 | /* Check for trailing ) */ | ||
1003 | if (*ptr != ')') | ||
1004 | return WPS_ERROR_INVALID_PARAM; | ||
1005 | ptr++; | ||
1006 | |||
1007 | if (follow_lang_direction && lang_is_rtl()) | ||
1008 | { | ||
1009 | vp->flags |= VP_FLAG_ALIGN_RIGHT; | ||
1010 | vp->x = screens[curr_screen].lcdwidth - vp->width - vp->x; | ||
1011 | } | ||
1012 | else | ||
1013 | vp->flags &= ~VP_FLAG_ALIGN_RIGHT; /* ignore right-to-left languages */ | ||
1014 | |||
1015 | #if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)) | 365 | #if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)) |
1016 | skin_vp->start_fgcolour = vp->fg_pattern; | ||
1017 | skin_vp->start_bgcolour = vp->bg_pattern; | ||
1018 | #endif | ||
1019 | 366 | ||
1020 | struct skin_token_list *list = new_skin_token_list_item(NULL, skin_vp); | 367 | static int parse_viewportcolour(struct skin_element *element, |
1021 | if (!list) | 368 | struct wps_token *token, |
1022 | return WPS_ERROR_INVALID_PARAM; | 369 | struct wps_data *wps_data) |
1023 | add_to_ll_chain(&wps_data->viewports, list); | ||
1024 | curr_vp = skin_vp; | ||
1025 | /* Skip the rest of the line */ | ||
1026 | return ptr-wps_bufptr; | ||
1027 | } | ||
1028 | #if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)) | ||
1029 | static int parse_viewportcolour(const char *wps_bufptr, | ||
1030 | struct wps_token *token, struct wps_data *wps_data) | ||
1031 | { | 370 | { |
1032 | (void)wps_data; | 371 | (void)wps_data; |
1033 | const char *ptr = wps_bufptr; | 372 | struct skin_tag_parameter *param = element->params; |
1034 | int i; | 373 | struct viewport_colour *colour = |
1035 | bool found_text; | 374 | (struct viewport_colour *)skin_buffer_alloc(sizeof(struct viewport_colour)); |
1036 | struct viewport_colour *colour = skin_buffer_alloc(sizeof(struct viewport_colour)); | 375 | if (!colour) |
1037 | uint32_t set; | ||
1038 | if (*ptr != '(' || !colour) | ||
1039 | return -1; | ||
1040 | ptr++; | ||
1041 | if (!(ptr = parse_list("c", &set, ',', ptr, &colour->colour))) | ||
1042 | return -1; | ||
1043 | if (*ptr != ')') | ||
1044 | return -1; | 376 | return -1; |
1045 | if (!set) | 377 | if (isdefault(param)) |
378 | { | ||
1046 | colour->colour = get_viewport_default_colour(curr_screen, | 379 | colour->colour = get_viewport_default_colour(curr_screen, |
1047 | token->type == WPS_TOKEN_VIEWPORT_FGCOLOUR); | 380 | token->type == SKIN_TOKEN_VIEWPORT_FGCOLOUR); |
1048 | colour->vp = &curr_vp->vp; | 381 | } |
1049 | token->value.data = colour; | 382 | else |
1050 | /* If there havnt been any text tags between the %V() line and here use | ||
1051 | * the colour as the viewport colour. fixes scrolling lines not | ||
1052 | * having the correct colour */ | ||
1053 | i = curr_vp->lines->sublines.first_token_idx; | ||
1054 | found_text = false; | ||
1055 | while (!found_text && i< curr_vp->lines->sublines.last_token_idx) | ||
1056 | { | 383 | { |
1057 | if (wps_data->tokens[i++].type != WPS_TOKEN_CHARACTER && | 384 | if (!parse_color(param->data.text, &colour->colour)) |
1058 | wps_data->tokens[i++].type != WPS_TOKEN_VIEWPORT_FGCOLOUR && | 385 | return -1; |
1059 | wps_data->tokens[i++].type != WPS_TOKEN_VIEWPORT_BGCOLOUR ) | ||
1060 | found_text = true; | ||
1061 | } | 386 | } |
1062 | if (!found_text) | 387 | colour->vp = &curr_vp->vp; |
388 | token->value.data = colour; | ||
389 | if (element->line == curr_viewport_element->line) | ||
1063 | { | 390 | { |
1064 | if (token->type == WPS_TOKEN_VIEWPORT_FGCOLOUR) | 391 | if (token->type == SKIN_TOKEN_VIEWPORT_FGCOLOUR) |
1065 | { | 392 | { |
1066 | curr_vp->start_fgcolour = colour->colour; | 393 | curr_vp->start_fgcolour = colour->colour; |
1067 | curr_vp->vp.fg_pattern = colour->colour; | 394 | curr_vp->vp.fg_pattern = colour->colour; |
@@ -1072,72 +399,54 @@ static int parse_viewportcolour(const char *wps_bufptr, | |||
1072 | curr_vp->vp.bg_pattern = colour->colour; | 399 | curr_vp->vp.bg_pattern = colour->colour; |
1073 | } | 400 | } |
1074 | } | 401 | } |
1075 | ptr++; | 402 | return 0; |
1076 | return ptr - wps_bufptr; | ||
1077 | } | 403 | } |
1078 | 404 | ||
1079 | static int parse_image_special(const char *wps_bufptr, | 405 | static int parse_image_special(struct skin_element *element, |
1080 | struct wps_token *token, | 406 | struct wps_token *token, |
1081 | struct wps_data *wps_data) | 407 | struct wps_data *wps_data) |
1082 | { | 408 | { |
1083 | (void)wps_data; /* kill warning */ | 409 | (void)wps_data; /* kill warning */ |
1084 | (void)token; | 410 | (void)token; |
1085 | const char *pos = NULL; | ||
1086 | const char *newline; | ||
1087 | bool error = false; | 411 | bool error = false; |
1088 | 412 | ||
1089 | pos = strchr(wps_bufptr + 1, ')'); | ||
1090 | newline = strchr(wps_bufptr, '\n'); | ||
1091 | |||
1092 | error = (pos > newline); | ||
1093 | |||
1094 | #if LCD_DEPTH > 1 | 413 | #if LCD_DEPTH > 1 |
1095 | if (token->type == WPS_TOKEN_IMAGE_BACKDROP) | 414 | if (token->type == SKIN_TOKEN_IMAGE_BACKDROP) |
1096 | { | 415 | { |
416 | char *filename = element->params[0].data.text; | ||
1097 | /* format: %X|filename.bmp| or %Xd */ | 417 | /* format: %X|filename.bmp| or %Xd */ |
1098 | if (!strncmp(wps_bufptr, "(d)", 3)) | 418 | if (!strcmp(filename, "d")) |
1099 | { | 419 | { |
1100 | wps_data->backdrop = NULL; | 420 | wps_data->backdrop = NULL; |
1101 | return skip_end_of_line(wps_bufptr); | 421 | return 0; |
1102 | } | 422 | } |
1103 | else if (!error) | 423 | else if (!error) |
1104 | wps_data->backdrop = (char*)wps_bufptr + 1; | 424 | { |
425 | wps_data->backdrop = filename; | ||
426 | } | ||
1105 | } | 427 | } |
1106 | #endif | 428 | #endif |
1107 | if (error) | ||
1108 | return WPS_ERROR_INVALID_PARAM; | ||
1109 | /* Skip the rest of the line */ | 429 | /* Skip the rest of the line */ |
1110 | return skip_end_of_line(wps_bufptr); | 430 | return error ? WPS_ERROR_INVALID_PARAM : 0; |
1111 | } | 431 | } |
1112 | #endif | 432 | #endif |
1113 | 433 | ||
1114 | #endif /* HAVE_LCD_BITMAP */ | 434 | #endif /* HAVE_LCD_BITMAP */ |
1115 | 435 | ||
1116 | static int parse_setting_and_lang(const char *wps_bufptr, | 436 | static int parse_setting_and_lang(struct skin_element *element, |
1117 | struct wps_token *token, | 437 | struct wps_token *token, |
1118 | struct wps_data *wps_data) | 438 | struct wps_data *wps_data) |
1119 | { | 439 | { |
1120 | /* NOTE: both the string validations that happen in here will | 440 | /* NOTE: both the string validations that happen in here will |
1121 | * automatically PASS on checkwps because its too hard to get | 441 | * automatically PASS on checkwps because its too hard to get |
1122 | * settings_list.c and englinsh.lang built for it. | 442 | * settings_list.c and english.lang built for it. |
1123 | * If that ever changes remove the #ifndef __PCTOOL__'s here | 443 | * If that ever changes remove the #ifndef __PCTOOL__'s here |
1124 | */ | 444 | */ |
1125 | (void)wps_data; | 445 | (void)wps_data; |
1126 | const char *ptr = wps_bufptr; | 446 | char *temp = element->params[0].data.text; |
1127 | const char *end; | 447 | int i; |
1128 | int i = 0; | ||
1129 | char temp[64]; | ||
1130 | |||
1131 | /* Find the setting's cfg_name */ | ||
1132 | if (*ptr != '(') | ||
1133 | return WPS_ERROR_INVALID_PARAM; | ||
1134 | ptr++; | ||
1135 | end = strchr(ptr,')'); | ||
1136 | if (!end || (size_t)(end-ptr+1) > sizeof temp) | ||
1137 | return WPS_ERROR_INVALID_PARAM; | ||
1138 | strlcpy(temp, ptr,end-ptr+1); | ||
1139 | 448 | ||
1140 | if (token->type == WPS_TOKEN_TRANSLATEDSTRING) | 449 | if (token->type == SKIN_TOKEN_TRANSLATEDSTRING) |
1141 | { | 450 | { |
1142 | #ifndef __PCTOOL__ | 451 | #ifndef __PCTOOL__ |
1143 | i = lang_english_to_id(temp); | 452 | i = lang_english_to_id(temp); |
@@ -1159,170 +468,104 @@ static int parse_setting_and_lang(const char *wps_bufptr, | |||
1159 | } | 468 | } |
1160 | /* Store the setting number */ | 469 | /* Store the setting number */ |
1161 | token->value.i = i; | 470 | token->value.i = i; |
1162 | 471 | return 0; | |
1163 | /* Skip the rest of the line */ | ||
1164 | return end-ptr+2; | ||
1165 | } | ||
1166 | |||
1167 | |||
1168 | static int parse_dir_level(const char *wps_bufptr, | ||
1169 | struct wps_token *token, | ||
1170 | struct wps_data *wps_data) | ||
1171 | { | ||
1172 | char val[] = { wps_bufptr[1], '\0' }; | ||
1173 | if (wps_bufptr[0] != '(' || wps_bufptr[2] != ')') | ||
1174 | return WPS_ERROR_INVALID_PARAM; | ||
1175 | token->value.i = atoi(val); | ||
1176 | (void)wps_data; /* Kill warnings */ | ||
1177 | return 3; | ||
1178 | } | 472 | } |
1179 | 473 | ||
1180 | static int parse_timeout(const char *wps_bufptr, | 474 | static int parse_timeout_tag(struct skin_element *element, |
1181 | struct wps_token *token, | 475 | struct wps_token *token, |
1182 | struct wps_data *wps_data) | 476 | struct wps_data *wps_data) |
1183 | { | 477 | { |
1184 | int skip = 0; | 478 | (void)wps_data; |
1185 | int val = 0; | 479 | int val = 0; |
1186 | bool have_point = false; | 480 | if (element->params_count == 0) |
1187 | bool have_tenth = false; | ||
1188 | |||
1189 | (void)wps_data; /* Kill the warning */ | ||
1190 | if (*wps_bufptr == '(') | ||
1191 | { | ||
1192 | wps_bufptr++; | ||
1193 | skip++; | ||
1194 | while ( isdigit(*wps_bufptr) || *wps_bufptr == '.' ) | ||
1195 | { | ||
1196 | if (*wps_bufptr != '.') | ||
1197 | { | ||
1198 | val *= 10; | ||
1199 | val += *wps_bufptr - '0'; | ||
1200 | if (have_point) | ||
1201 | { | ||
1202 | have_tenth = true; | ||
1203 | wps_bufptr++; | ||
1204 | skip++; | ||
1205 | break; | ||
1206 | } | ||
1207 | } | ||
1208 | else | ||
1209 | have_point = true; | ||
1210 | |||
1211 | wps_bufptr++; | ||
1212 | skip++; | ||
1213 | } | ||
1214 | if (*wps_bufptr != ')') | ||
1215 | return -1; | ||
1216 | skip++; | ||
1217 | } | ||
1218 | if (have_tenth == false) | ||
1219 | val *= 10; | ||
1220 | |||
1221 | if (val == 0 && skip == 0) | ||
1222 | { | 481 | { |
1223 | /* decide what to do if no value was specified */ | ||
1224 | switch (token->type) | 482 | switch (token->type) |
1225 | { | 483 | { |
1226 | case WPS_TOKEN_SUBLINE_TIMEOUT: | 484 | case SKIN_TOKEN_SUBLINE_TIMEOUT: |
1227 | return -1; | 485 | return -1; |
1228 | case WPS_TOKEN_BUTTON_VOLUME: | 486 | case SKIN_TOKEN_BUTTON_VOLUME: |
1229 | case WPS_TOKEN_TRACK_STARTING: | 487 | case SKIN_TOKEN_TRACK_STARTING: |
1230 | case WPS_TOKEN_TRACK_ENDING: | 488 | case SKIN_TOKEN_TRACK_ENDING: |
489 | case SKIN_TOKEN_LASTTOUCH: | ||
1231 | val = 10; | 490 | val = 10; |
1232 | break; | 491 | break; |
492 | default: | ||
493 | break; | ||
1233 | } | 494 | } |
1234 | } | 495 | } |
496 | else | ||
497 | val = element->params[0].data.number; | ||
1235 | token->value.i = val; | 498 | token->value.i = val; |
1236 | 499 | if (token->type == SKIN_TOKEN_SUBLINE_TIMEOUT) | |
1237 | return skip; | 500 | curr_line->timeout = val * TIMEOUT_UNIT; |
501 | return 0; | ||
1238 | } | 502 | } |
1239 | 503 | ||
1240 | static int parse_progressbar(const char *wps_bufptr, | 504 | static int parse_progressbar_tag(struct skin_element* element, |
1241 | struct wps_token *token, | 505 | struct wps_token *token, |
1242 | struct wps_data *wps_data) | 506 | struct wps_data *wps_data) |
1243 | { | 507 | { |
1244 | /* %pb or %pb|filename|x|y|width|height| | ||
1245 | using - for any of the params uses "sane" values */ | ||
1246 | #ifdef HAVE_LCD_BITMAP | 508 | #ifdef HAVE_LCD_BITMAP |
1247 | enum { | 509 | struct progressbar *pb; |
1248 | PB_X = 0, | 510 | struct skin_token_list *item; |
1249 | PB_Y, | ||
1250 | PB_WIDTH, | ||
1251 | PB_HEIGHT, | ||
1252 | PB_FILENAME, | ||
1253 | }; | ||
1254 | const char *filename; | ||
1255 | int x, y, height, width; | ||
1256 | uint32_t set = 0; | ||
1257 | const char *ptr = wps_bufptr; | ||
1258 | struct progressbar *pb = skin_buffer_alloc(sizeof(struct progressbar)); | ||
1259 | struct skin_token_list *item = new_skin_token_list_item(token, pb); | ||
1260 | |||
1261 | if (!pb || !item) | ||
1262 | return WPS_ERROR_INVALID_PARAM; | ||
1263 | |||
1264 | struct viewport *vp = &curr_vp->vp; | 511 | struct viewport *vp = &curr_vp->vp; |
1265 | /* we need to know what line number (viewport relative) this pb is, | 512 | struct skin_tag_parameter *param = element->params; |
1266 | * so count them... */ | 513 | |
1267 | int line_num = -1; | 514 | if (element->params_count == 0 && |
1268 | struct skin_line *line = curr_vp->lines; | 515 | element->tag->type != SKIN_TOKEN_PROGRESSBAR) |
1269 | while (line) | 516 | return 0; /* nothing to do */ |
1270 | { | 517 | pb = (struct progressbar*)skin_buffer_alloc(sizeof(struct progressbar)); |
1271 | line_num++; | 518 | |
1272 | line = line->next; | 519 | token->value.data = pb; |
1273 | } | 520 | |
1274 | if (curr_vp->label != VP_DEFAULT_LABEL) | 521 | if (!pb) |
1275 | line_num--; | 522 | return WPS_ERROR_INVALID_PARAM; |
1276 | pb->vp = vp; | 523 | pb->vp = vp; |
1277 | pb->have_bitmap_pb = false; | 524 | pb->have_bitmap_pb = false; |
1278 | pb->bm.data = NULL; /* no bitmap specified */ | 525 | pb->bm.data = NULL; /* no bitmap specified */ |
1279 | pb->follow_lang_direction = follow_lang_direction > 0; | 526 | pb->follow_lang_direction = follow_lang_direction > 0; |
1280 | pb->draw = false; | 527 | |
1281 | 528 | if (element->params_count == 0) | |
1282 | if (*wps_bufptr != '(') /* regular old style */ | ||
1283 | { | 529 | { |
1284 | pb->x = 0; | 530 | pb->x = 0; |
1285 | pb->width = vp->width; | 531 | pb->width = vp->width; |
1286 | pb->height = SYSFONT_HEIGHT-2; | 532 | pb->height = SYSFONT_HEIGHT-2; |
1287 | pb->y = -line_num - 1; /* Will be computed during the rendering */ | 533 | pb->y = -1; /* Will be computed during the rendering */ |
1288 | if (token->type == WPS_TOKEN_VOLUME || token->type == WPS_TOKEN_BATTERY_PERCENT) | 534 | pb->type = element->tag->type; |
1289 | return 0; /* dont add it, let the regular token handling do the work */ | ||
1290 | pb->type = token->type; | ||
1291 | add_to_ll_chain(&wps_data->progressbars, item); | ||
1292 | return 0; | 535 | return 0; |
1293 | } | 536 | } |
1294 | ptr = wps_bufptr + 1; | 537 | |
1295 | 538 | item = new_skin_token_list_item(token, pb); | |
1296 | if (!(ptr = parse_list("dddds", &set, ',', ptr, | 539 | if (!item) |
1297 | &x, &y, &width, &height, &filename))) | 540 | return -1; |
1298 | return WPS_ERROR_INVALID_PARAM; | 541 | add_to_ll_chain(&wps_data->progressbars, item); |
1299 | 542 | ||
1300 | if (LIST_VALUE_PARSED(set, PB_FILENAME)) /* filename */ | 543 | /* (x,y,width,height,filename) */ |
1301 | pb->bm.data = (char*)filename; | 544 | if (!isdefault(param)) |
1302 | 545 | pb->x = param->data.number; | |
1303 | if (LIST_VALUE_PARSED(set, PB_X)) /* x */ | ||
1304 | pb->x = x; | ||
1305 | else | 546 | else |
1306 | pb->x = vp->x; | 547 | pb->x = vp->x; |
1307 | 548 | param++; | |
1308 | if (LIST_VALUE_PARSED(set, PB_WIDTH)) /* width */ | 549 | |
1309 | { | 550 | if (!isdefault(param)) |
1310 | /* A zero width causes a divide-by-zero error later, so reject it */ | 551 | pb->y = param->data.number; |
1311 | if (width == 0) | 552 | else |
1312 | return WPS_ERROR_INVALID_PARAM; | 553 | pb->y = -1; /* computed at rendering */ |
1313 | 554 | param++; | |
1314 | pb->width = width; | 555 | |
1315 | } | 556 | if (!isdefault(param)) |
557 | pb->width = param->data.number; | ||
1316 | else | 558 | else |
1317 | pb->width = vp->width - pb->x; | 559 | pb->width = vp->width - pb->x; |
1318 | 560 | param++; | |
1319 | if (LIST_VALUE_PARSED(set, PB_HEIGHT)) /* height, default to font height */ | 561 | |
562 | if (!isdefault(param)) | ||
1320 | { | 563 | { |
1321 | /* A zero height makes no sense - reject it */ | 564 | /* A zero height makes no sense - reject it */ |
1322 | if (height == 0) | 565 | if (param->data.number == 0) |
1323 | return WPS_ERROR_INVALID_PARAM; | 566 | return WPS_ERROR_INVALID_PARAM; |
1324 | 567 | ||
1325 | pb->height = height; | 568 | pb->height = param->data.number; |
1326 | } | 569 | } |
1327 | else | 570 | else |
1328 | { | 571 | { |
@@ -1337,30 +580,26 @@ static int parse_progressbar(const char *wps_bufptr, | |||
1337 | #endif | 580 | #endif |
1338 | } | 581 | } |
1339 | } | 582 | } |
1340 | 583 | param++; | |
1341 | if (LIST_VALUE_PARSED(set, PB_Y)) /* y */ | 584 | if (!isdefault(param)) |
1342 | pb->y = y; | 585 | pb->bm.data = param->data.text; |
1343 | else | 586 | |
1344 | pb->y = -line_num - 1; /* Will be computed during the rendering */ | 587 | |
1345 | 588 | if (token->type == SKIN_TOKEN_VOLUME) | |
1346 | if (*ptr != ')') | 589 | token->type = SKIN_TOKEN_VOLUMEBAR; |
1347 | return WPS_ERROR_INVALID_PARAM; | 590 | else if (token->type == SKIN_TOKEN_BATTERY_PERCENT) |
1348 | 591 | token->type = SKIN_TOKEN_BATTERY_PERCENTBAR; | |
1349 | add_to_ll_chain(&wps_data->progressbars, item); | ||
1350 | if (token->type == WPS_TOKEN_VOLUME) | ||
1351 | token->type = WPS_TOKEN_VOLUMEBAR; | ||
1352 | else if (token->type == WPS_TOKEN_BATTERY_PERCENT) | ||
1353 | token->type = WPS_TOKEN_BATTERY_PERCENTBAR; | ||
1354 | pb->type = token->type; | 592 | pb->type = token->type; |
1355 | 593 | ||
1356 | return ptr+1-wps_bufptr; | 594 | return 0; |
595 | |||
1357 | #else | 596 | #else |
1358 | (void)wps_bufptr; | 597 | (void)element; |
1359 | if (token->type != WPS_TOKEN_VOLUME && | 598 | if (token->type == SKIN_TOKEN_PROGRESSBAR || |
1360 | token->type != WPS_TOKEN_BATTERY_PERCENTBAR) | 599 | token->type == SKIN_TOKEN_PLAYER_PROGRESSBAR) |
1361 | { | 600 | { |
1362 | wps_data->full_line_progressbar = | 601 | wps_data->full_line_progressbar = |
1363 | token->type == WPS_TOKEN_PLAYER_PROGRESSBAR; | 602 | token->type == SKIN_TOKEN_PLAYER_PROGRESSBAR; |
1364 | } | 603 | } |
1365 | return 0; | 604 | return 0; |
1366 | 605 | ||
@@ -1368,32 +607,32 @@ static int parse_progressbar(const char *wps_bufptr, | |||
1368 | } | 607 | } |
1369 | 608 | ||
1370 | #ifdef HAVE_ALBUMART | 609 | #ifdef HAVE_ALBUMART |
1371 | static int parse_albumart_load(const char *wps_bufptr, | 610 | static int parse_albumart_load(struct skin_element* element, |
1372 | struct wps_token *token, | 611 | struct wps_token *token, |
1373 | struct wps_data *wps_data) | 612 | struct wps_data *wps_data) |
1374 | { | 613 | { |
1375 | const char *ptr = wps_bufptr; | ||
1376 | struct dim dimensions; | 614 | struct dim dimensions; |
1377 | int albumart_slot; | 615 | int albumart_slot; |
1378 | bool swap_for_rtl = lang_is_rtl() && follow_lang_direction; | 616 | bool swap_for_rtl = lang_is_rtl() && follow_lang_direction; |
1379 | struct skin_albumart *aa = skin_buffer_alloc(sizeof(struct skin_albumart)); | 617 | struct skin_albumart *aa = |
618 | (struct skin_albumart *)skin_buffer_alloc(sizeof(struct skin_albumart)); | ||
1380 | (void)token; /* silence warning */ | 619 | (void)token; /* silence warning */ |
1381 | if (!aa) | 620 | if (!aa) |
1382 | return skip_end_of_line(wps_bufptr); | 621 | return -1; |
1383 | 622 | ||
1384 | /* reset albumart info in wps */ | 623 | /* reset albumart info in wps */ |
1385 | aa->width = -1; | 624 | aa->width = -1; |
1386 | aa->height = -1; | 625 | aa->height = -1; |
1387 | aa->xalign = WPS_ALBUMART_ALIGN_CENTER; /* default */ | 626 | aa->xalign = WPS_ALBUMART_ALIGN_CENTER; /* default */ |
1388 | aa->yalign = WPS_ALBUMART_ALIGN_CENTER; /* default */ | 627 | aa->yalign = WPS_ALBUMART_ALIGN_CENTER; /* default */ |
1389 | aa->vp = &curr_vp->vp; | ||
1390 | 628 | ||
1391 | if (*ptr != '(') | 629 | aa->x = element->params[0].data.number; |
1392 | return WPS_ERROR_INVALID_PARAM; | 630 | aa->y = element->params[1].data.number; |
1393 | ptr++; | 631 | aa->width = element->params[2].data.number; |
1394 | /* format: %Cl|x|y|[[l|c|r]mwidth]|[[t|c|b]mheight]| */ | 632 | aa->height = element->params[3].data.number; |
1395 | if (!(ptr = parse_list("dddd", NULL,',',ptr, &aa->x, &aa->y, &aa->width, &aa->height))) | 633 | |
1396 | return WPS_ERROR_INVALID_PARAM; /* malformed token: e.g. %Cl7 */ | 634 | aa->vp = &curr_vp->vp; |
635 | aa->draw_handle = -1; | ||
1397 | 636 | ||
1398 | /* if we got here, we parsed everything ok .. ! */ | 637 | /* if we got here, we parsed everything ok .. ! */ |
1399 | if (aa->width < 0) | 638 | if (aa->width < 0) |
@@ -1410,7 +649,6 @@ static int parse_albumart_load(const char *wps_bufptr, | |||
1410 | aa->x = LCD_WIDTH - (aa->x + aa->width); | 649 | aa->x = LCD_WIDTH - (aa->x + aa->width); |
1411 | 650 | ||
1412 | aa->state = WPS_ALBUMART_LOAD; | 651 | aa->state = WPS_ALBUMART_LOAD; |
1413 | aa->draw = false; | ||
1414 | wps_data->albumart = aa; | 652 | wps_data->albumart = aa; |
1415 | 653 | ||
1416 | dimensions.width = aa->width; | 654 | dimensions.width = aa->width; |
@@ -1420,11 +658,10 @@ static int parse_albumart_load(const char *wps_bufptr, | |||
1420 | 658 | ||
1421 | if (0 <= albumart_slot) | 659 | if (0 <= albumart_slot) |
1422 | wps_data->playback_aa_slot = albumart_slot; | 660 | wps_data->playback_aa_slot = albumart_slot; |
1423 | 661 | ||
1424 | if (*ptr == ',') | 662 | if (element->params_count > 4 && !isdefault(&element->params[4])) |
1425 | { | 663 | { |
1426 | ptr++; | 664 | switch (*element->params[4].data.text) |
1427 | switch (*ptr) | ||
1428 | { | 665 | { |
1429 | case 'l': | 666 | case 'l': |
1430 | case 'L': | 667 | case 'L': |
@@ -1445,12 +682,10 @@ static int parse_albumart_load(const char *wps_bufptr, | |||
1445 | aa->xalign = WPS_ALBUMART_ALIGN_RIGHT; | 682 | aa->xalign = WPS_ALBUMART_ALIGN_RIGHT; |
1446 | break; | 683 | break; |
1447 | } | 684 | } |
1448 | ptr++; | ||
1449 | } | 685 | } |
1450 | if (*ptr == ',') | 686 | if (element->params_count > 5 && !isdefault(&element->params[5])) |
1451 | { | 687 | { |
1452 | ptr++; | 688 | switch (*element->params[5].data.text) |
1453 | switch (*ptr) | ||
1454 | { | 689 | { |
1455 | case 't': | 690 | case 't': |
1456 | case 'T': | 691 | case 'T': |
@@ -1465,32 +700,10 @@ static int parse_albumart_load(const char *wps_bufptr, | |||
1465 | aa->yalign = WPS_ALBUMART_ALIGN_BOTTOM; | 700 | aa->yalign = WPS_ALBUMART_ALIGN_BOTTOM; |
1466 | break; | 701 | break; |
1467 | } | 702 | } |
1468 | ptr++; | ||
1469 | } | 703 | } |
1470 | if (*ptr != ')') | 704 | return 0; |
1471 | return WPS_ERROR_INVALID_PARAM; | ||
1472 | |||
1473 | return skip_end_of_line(wps_bufptr); | ||
1474 | } | 705 | } |
1475 | 706 | ||
1476 | static int parse_albumart_display(const char *wps_bufptr, | ||
1477 | struct wps_token *token, | ||
1478 | struct wps_data *wps_data) | ||
1479 | { | ||
1480 | (void)wps_bufptr; | ||
1481 | (void)token; | ||
1482 | if (wps_data->albumart) | ||
1483 | { | ||
1484 | wps_data->albumart->vp = &curr_vp->vp; | ||
1485 | } | ||
1486 | #if 0 | ||
1487 | /* the old code did this so keep it here for now... | ||
1488 | * this is to allow the posibility to showing the next tracks AA! */ | ||
1489 | if (wps_bufptr+1 == 'n') | ||
1490 | return 1; | ||
1491 | #endif | ||
1492 | return 0; | ||
1493 | }; | ||
1494 | #endif /* HAVE_ALBUMART */ | 707 | #endif /* HAVE_ALBUMART */ |
1495 | 708 | ||
1496 | #ifdef HAVE_TOUCHSCREEN | 709 | #ifdef HAVE_TOUCHSCREEN |
@@ -1520,8 +733,9 @@ static const struct touchaction touchactions[] = { | |||
1520 | #endif | 733 | #endif |
1521 | }; | 734 | }; |
1522 | 735 | ||
1523 | static int parse_touchregion(const char *wps_bufptr, | 736 | static int parse_touchregion(struct skin_element *element, |
1524 | struct wps_token *token, struct wps_data *wps_data) | 737 | struct wps_token *token, |
738 | struct wps_data *wps_data) | ||
1525 | { | 739 | { |
1526 | (void)token; | 740 | (void)token; |
1527 | unsigned i, imax; | 741 | unsigned i, imax; |
@@ -1533,7 +747,7 @@ static int parse_touchregion(const char *wps_bufptr, | |||
1533 | int x,y,w,h; | 747 | int x,y,w,h; |
1534 | char temp[20]; | 748 | char temp[20]; |
1535 | 749 | ||
1536 | /* format: %T|x|y|width|height|action| | 750 | /* format: %T(x,y,width,height,action) |
1537 | * if action starts with & the area must be held to happen | 751 | * if action starts with & the area must be held to happen |
1538 | * action is one of: | 752 | * action is one of: |
1539 | * play - play/pause playback | 753 | * play - play/pause playback |
@@ -1554,35 +768,22 @@ static int parse_touchregion(const char *wps_bufptr, | |||
1554 | * voldown - decrease volume by one step | 768 | * voldown - decrease volume by one step |
1555 | */ | 769 | */ |
1556 | 770 | ||
1557 | 771 | ||
1558 | if (*ptr != '(') | 772 | region = (struct touchregion*)skin_buffer_alloc(sizeof(struct touchregion)); |
1559 | return WPS_ERROR_INVALID_PARAM; | ||
1560 | ptr++; | ||
1561 | |||
1562 | if (!(ptr = parse_list("dddds", NULL, ',', ptr, &x, &y, &w, &h, &action))) | ||
1563 | return WPS_ERROR_INVALID_PARAM; | ||
1564 | |||
1565 | /* Check there is a terminating ) */ | ||
1566 | if (*ptr != ')') | ||
1567 | return WPS_ERROR_INVALID_PARAM; | ||
1568 | |||
1569 | region = skin_buffer_alloc(sizeof(struct touchregion)); | ||
1570 | if (!region) | 773 | if (!region) |
1571 | return WPS_ERROR_INVALID_PARAM; | 774 | return WPS_ERROR_INVALID_PARAM; |
1572 | 775 | ||
1573 | /* should probably do some bounds checking here with the viewport... but later */ | 776 | /* should probably do some bounds checking here with the viewport... but later */ |
1574 | region->action = ACTION_NONE; | 777 | region->action = ACTION_NONE; |
1575 | region->x = x; | 778 | region->x = element->params[0].data.number; |
1576 | region->y = y; | 779 | region->y = element->params[1].data.number; |
1577 | region->width = w; | 780 | region->width = element->params[2].data.number; |
1578 | region->height = h; | 781 | region->height = element->params[3].data.number; |
1579 | region->wvp = curr_vp; | 782 | region->wvp = curr_vp; |
1580 | region->armed = false; | 783 | region->armed = false; |
1581 | region->reverse_bar = false; | 784 | region->reverse_bar = false; |
785 | action = element->params[4].data.text; | ||
1582 | 786 | ||
1583 | end = strchr(action, ')'); | ||
1584 | if (!end || (size_t)(end-action+1) > sizeof temp) | ||
1585 | return WPS_ERROR_INVALID_PARAM; | ||
1586 | strlcpy(temp, action, end-action+1); | 787 | strlcpy(temp, action, end-action+1); |
1587 | action = temp; | 788 | action = temp; |
1588 | 789 | ||
@@ -1625,449 +826,46 @@ static int parse_touchregion(const char *wps_bufptr, | |||
1625 | if (!item) | 826 | if (!item) |
1626 | return WPS_ERROR_INVALID_PARAM; | 827 | return WPS_ERROR_INVALID_PARAM; |
1627 | add_to_ll_chain(&wps_data->touchregions, item); | 828 | add_to_ll_chain(&wps_data->touchregions, item); |
1628 | return skip_end_of_line(wps_bufptr); | 829 | return 0; |
1629 | } | 830 | } |
1630 | #endif | 831 | #endif |
1631 | 832 | ||
1632 | /* Parse a generic token from the given string. Return the length read */ | 833 | static bool check_feature_tag(const int type) |
1633 | static int parse_token(const char *wps_bufptr, struct wps_data *wps_data) | ||
1634 | { | 834 | { |
1635 | int skip = 0, taglen = 0, ret; | ||
1636 | struct wps_token *token = wps_data->tokens + wps_data->num_tokens; | ||
1637 | const struct wps_tag *tag; | ||
1638 | memset(token, 0, sizeof(*token)); | ||
1639 | |||
1640 | switch(*wps_bufptr) | ||
1641 | { | ||
1642 | |||
1643 | case '%': | ||
1644 | case '<': | ||
1645 | case '|': | ||
1646 | case '>': | ||
1647 | case ';': | ||
1648 | case '#': | ||
1649 | case ')': | ||
1650 | case '(': | ||
1651 | case ',': | ||
1652 | /* escaped characters */ | ||
1653 | token->type = WPS_TOKEN_CHARACTER; | ||
1654 | token->value.c = *wps_bufptr; | ||
1655 | taglen = 1; | ||
1656 | wps_data->num_tokens++; | ||
1657 | break; | ||
1658 | |||
1659 | case '?': | ||
1660 | /* conditional tag */ | ||
1661 | token->type = WPS_TOKEN_CONDITIONAL; | ||
1662 | level++; | ||
1663 | condindex[level] = wps_data->num_tokens; | ||
1664 | numoptions[level] = 1; | ||
1665 | wps_data->num_tokens++; | ||
1666 | ret = parse_token(wps_bufptr + 1, wps_data); | ||
1667 | if (ret < 0) return ret; | ||
1668 | taglen = 1 + ret; | ||
1669 | break; | ||
1670 | |||
1671 | default: | ||
1672 | /* find what tag we have */ | ||
1673 | for (tag = all_tags; | ||
1674 | strncmp(wps_bufptr, tag->name, strlen(tag->name)) != 0; | ||
1675 | tag++) ; | ||
1676 | |||
1677 | taglen = (tag->type != WPS_TOKEN_UNKNOWN) ? strlen(tag->name) : 2; | ||
1678 | token->type = tag->type; | ||
1679 | curr_line->curr_subline->line_type |= tag->refresh_type; | ||
1680 | |||
1681 | /* if the tag has a special parsing function, we call it */ | ||
1682 | if (tag->parse_func) | ||
1683 | { | ||
1684 | ret = tag->parse_func(wps_bufptr + taglen, token, wps_data); | ||
1685 | if (ret < 0) return ret; | ||
1686 | skip += ret; | ||
1687 | } | ||
1688 | |||
1689 | /* Some tags we don't want to save as tokens */ | ||
1690 | if (tag->type == WPS_NO_TOKEN) | ||
1691 | break; | ||
1692 | |||
1693 | /* tags that start with 'F', 'I' or 'D' are for the next file */ | ||
1694 | if ( *(tag->name) == 'I' || *(tag->name) == 'F' || | ||
1695 | *(tag->name) == 'D') | ||
1696 | token->next = true; | ||
1697 | |||
1698 | wps_data->num_tokens++; | ||
1699 | break; | ||
1700 | } | ||
1701 | |||
1702 | skip += taglen; | ||
1703 | return skip; | ||
1704 | } | ||
1705 | |||
1706 | |||
1707 | /* | ||
1708 | * Returns the number of bytes to skip the buf pointer to access the false | ||
1709 | * branch in a _binary_ conditional | ||
1710 | * | ||
1711 | * That is: | ||
1712 | * - before the '|' if we have a false branch, (%?<true|false> -> %?<|false>) | ||
1713 | * - or before the closing '>' if there's no false branch (%?<true> -> %?<>) | ||
1714 | * | ||
1715 | * depending on the features of a target it's not called from check_feature_tag, | ||
1716 | * hence the __attribute__ or it issues compiler warnings | ||
1717 | * | ||
1718 | **/ | ||
1719 | |||
1720 | static int find_false_branch(const char *wps_bufptr) __attribute__((unused)); | ||
1721 | static int find_false_branch(const char *wps_bufptr) | ||
1722 | { | ||
1723 | const char *buf = wps_bufptr; | ||
1724 | /* wps_bufptr is after the opening '<', hence level = 1*/ | ||
1725 | int level = 1; | ||
1726 | char ch; | ||
1727 | do | ||
1728 | { | ||
1729 | ch = *buf; | ||
1730 | if (ch == '%') | ||
1731 | { /* filter out the characters we check later if they're printed | ||
1732 | * as literals */ | ||
1733 | ch = *(++buf); | ||
1734 | if (ch == '<' || ch == '>' || ch == '|') | ||
1735 | continue; | ||
1736 | /* else: some tags/printed literals we skip over */ | ||
1737 | } | ||
1738 | else if (ch == '<') /* nested conditional */ | ||
1739 | level++; | ||
1740 | else if (ch == '>') | ||
1741 | { /* closed our or a nested conditional, | ||
1742 | * do NOT skip over the '>' so that wps_parse() sees it for closing | ||
1743 | * if it is the closing one for our conditional */ | ||
1744 | level--; | ||
1745 | } | ||
1746 | else if (ch == '|' && level == 1) | ||
1747 | { /* we found our separator, point before and get out */ | ||
1748 | break; | ||
1749 | } | ||
1750 | /* if level is 0, we don't have a false branch */ | ||
1751 | } while (level > 0 && *(++buf)); | ||
1752 | |||
1753 | return buf - wps_bufptr; | ||
1754 | } | ||
1755 | |||
1756 | /* | ||
1757 | * returns the number of bytes to get the appropriate branch of a binary | ||
1758 | * conditional | ||
1759 | * | ||
1760 | * That means: | ||
1761 | * - if a feature is available, it returns 0 to not skip anything | ||
1762 | * - if the feature is not available, skip to the false branch and don't | ||
1763 | * parse the true branch at all | ||
1764 | * | ||
1765 | * */ | ||
1766 | static int check_feature_tag(const char *wps_bufptr, const int type) | ||
1767 | { | ||
1768 | (void)wps_bufptr; | ||
1769 | switch (type) | 835 | switch (type) |
1770 | { | 836 | { |
1771 | case WPS_TOKEN_RTC_PRESENT: | 837 | case SKIN_TOKEN_RTC_PRESENT: |
1772 | #if CONFIG_RTC | 838 | #if CONFIG_RTC |
1773 | return 0; | 839 | return true; |
1774 | #else | 840 | #else |
1775 | return find_false_branch(wps_bufptr); | 841 | return false; |
1776 | #endif /* CONFIG_RTC */ | 842 | #endif |
1777 | 843 | case SKIN_TOKEN_HAVE_RECORDING: | |
1778 | case WPS_TOKEN_HAVE_RECORDING: | ||
1779 | #ifdef HAVE_RECORDING | 844 | #ifdef HAVE_RECORDING |
1780 | return 0; | 845 | return true; |
1781 | #else | 846 | #else |
1782 | return find_false_branch(wps_bufptr); | 847 | return false; |
1783 | #endif /* HAVE_RECORDING */ | 848 | #endif |
1784 | 849 | case SKIN_TOKEN_HAVE_TUNER: | |
1785 | case WPS_TOKEN_HAVE_TUNER: | ||
1786 | #if CONFIG_TUNER | 850 | #if CONFIG_TUNER |
1787 | if (radio_hardware_present()) | 851 | if (radio_hardware_present()) |
1788 | return 0; | 852 | return true; |
1789 | #endif /* CONFIG_TUNER */ | 853 | #endif |
1790 | return find_false_branch(wps_bufptr); | 854 | return false; |
1791 | 855 | ||
1792 | #if CONFIG_TUNER | 856 | #if CONFIG_TUNER |
1793 | case WPS_TOKEN_HAVE_RDS: | 857 | case SKIN_TOKEN_HAVE_RDS: |
1794 | #ifdef HAVE_RDS_CAP | 858 | #ifdef HAVE_RDS_CAP |
1795 | return 0; | 859 | return true; |
1796 | #else | 860 | #else |
1797 | return find_false_branch(wps_bufptr); | 861 | return false; |
1798 | #endif /* HAVE_RDS_CAP */ | 862 | #endif /* HAVE_RDS_CAP */ |
1799 | #endif /* CONFIG_TUNER */ | 863 | #endif /* CONFIG_TUNER */ |
1800 | default: /* not a tag we care about, just don't skip */ | 864 | default: /* not a tag we care about, just don't skip */ |
1801 | return 0; | 865 | return true; |
1802 | } | ||
1803 | } | ||
1804 | |||
1805 | |||
1806 | /* Parses the WPS. | ||
1807 | data is the pointer to the structure where the parsed WPS should be stored. | ||
1808 | It is initialised. | ||
1809 | wps_bufptr points to the string containing the WPS tags */ | ||
1810 | #define TOKEN_BLOCK_SIZE 128 | ||
1811 | static bool wps_parse(struct wps_data *data, const char *wps_bufptr, bool debug) | ||
1812 | { | ||
1813 | if (!data || !wps_bufptr || !*wps_bufptr) | ||
1814 | return false; | ||
1815 | enum wps_parse_error fail = PARSE_OK; | ||
1816 | int ret; | ||
1817 | int max_tokens = TOKEN_BLOCK_SIZE; | ||
1818 | size_t buf_free = 0; | ||
1819 | line_number = 0; | ||
1820 | level = -1; | ||
1821 | |||
1822 | /* allocate enough RAM for a reasonable skin, grow as needed. | ||
1823 | * Free any used RAM before loading the images to be 100% RAM efficient */ | ||
1824 | data->tokens = (struct wps_token *)skin_buffer_grab(&buf_free); | ||
1825 | if (sizeof(struct wps_token)*max_tokens >= buf_free) | ||
1826 | return false; | ||
1827 | skin_buffer_increment(max_tokens * sizeof(struct wps_token), false); | ||
1828 | data->num_tokens = 0; | ||
1829 | |||
1830 | #if LCD_DEPTH > 1 | ||
1831 | /* Backdrop defaults to the setting unless %X is used, so set it now */ | ||
1832 | if (global_settings.backdrop_file[0]) | ||
1833 | { | ||
1834 | data->backdrop = "-"; | ||
1835 | } | ||
1836 | #endif | ||
1837 | |||
1838 | while (*wps_bufptr && !fail) | ||
1839 | { | ||
1840 | if (follow_lang_direction) | ||
1841 | follow_lang_direction--; | ||
1842 | /* first make sure there is enough room for tokens */ | ||
1843 | if (max_tokens <= data->num_tokens + 5) | ||
1844 | { | ||
1845 | int extra_tokens = TOKEN_BLOCK_SIZE; | ||
1846 | size_t needed = extra_tokens * sizeof(struct wps_token); | ||
1847 | /* do some smarts here to grow the array a bit */ | ||
1848 | if (skin_buffer_freespace() < needed) | ||
1849 | { | ||
1850 | fail = PARSE_FAIL_LIMITS_EXCEEDED; | ||
1851 | break; | ||
1852 | } | ||
1853 | skin_buffer_increment(needed, false); | ||
1854 | max_tokens += extra_tokens; | ||
1855 | } | ||
1856 | |||
1857 | switch(*wps_bufptr++) | ||
1858 | { | ||
1859 | |||
1860 | /* Regular tag */ | ||
1861 | case '%': | ||
1862 | if ((ret = parse_token(wps_bufptr, data)) < 0) | ||
1863 | { | ||
1864 | fail = PARSE_FAIL_COND_INVALID_PARAM; | ||
1865 | break; | ||
1866 | } | ||
1867 | else if (level >= WPS_MAX_COND_LEVEL - 1) | ||
1868 | { | ||
1869 | fail = PARSE_FAIL_LIMITS_EXCEEDED; | ||
1870 | break; | ||
1871 | } | ||
1872 | wps_bufptr += ret; | ||
1873 | break; | ||
1874 | |||
1875 | /* Alternating sublines separator */ | ||
1876 | case ';': | ||
1877 | if (level >= 0) /* there are unclosed conditionals */ | ||
1878 | { | ||
1879 | fail = PARSE_FAIL_UNCLOSED_COND; | ||
1880 | break; | ||
1881 | } | ||
1882 | |||
1883 | if (!skin_start_new_subline(curr_line, data->num_tokens)) | ||
1884 | fail = PARSE_FAIL_LIMITS_EXCEEDED; | ||
1885 | |||
1886 | break; | ||
1887 | |||
1888 | /* Conditional list start */ | ||
1889 | case '<': | ||
1890 | if (data->tokens[data->num_tokens-2].type != WPS_TOKEN_CONDITIONAL) | ||
1891 | { | ||
1892 | fail = PARSE_FAIL_COND_SYNTAX_ERROR; | ||
1893 | break; | ||
1894 | } | ||
1895 | wps_bufptr += check_feature_tag(wps_bufptr, | ||
1896 | data->tokens[data->num_tokens-1].type); | ||
1897 | data->tokens[data->num_tokens].type = WPS_TOKEN_CONDITIONAL_START; | ||
1898 | lastcond[level] = data->num_tokens++; | ||
1899 | break; | ||
1900 | |||
1901 | /* Conditional list end */ | ||
1902 | case '>': | ||
1903 | if (level < 0) /* not in a conditional, invalid char */ | ||
1904 | { | ||
1905 | fail = PARSE_FAIL_INVALID_CHAR; | ||
1906 | break; | ||
1907 | } | ||
1908 | |||
1909 | data->tokens[data->num_tokens].type = WPS_TOKEN_CONDITIONAL_END; | ||
1910 | if (lastcond[level]) | ||
1911 | data->tokens[lastcond[level]].value.i = data->num_tokens; | ||
1912 | else | ||
1913 | { | ||
1914 | fail = PARSE_FAIL_COND_SYNTAX_ERROR; | ||
1915 | break; | ||
1916 | } | ||
1917 | |||
1918 | lastcond[level] = 0; | ||
1919 | data->num_tokens++; | ||
1920 | data->tokens[condindex[level]].value.i = numoptions[level]; | ||
1921 | level--; | ||
1922 | break; | ||
1923 | |||
1924 | /* Conditional list option */ | ||
1925 | case '|': | ||
1926 | if (level < 0) /* not in a conditional, invalid char */ | ||
1927 | { | ||
1928 | fail = PARSE_FAIL_INVALID_CHAR; | ||
1929 | break; | ||
1930 | } | ||
1931 | |||
1932 | data->tokens[data->num_tokens].type = WPS_TOKEN_CONDITIONAL_OPTION; | ||
1933 | if (lastcond[level]) | ||
1934 | data->tokens[lastcond[level]].value.i = data->num_tokens; | ||
1935 | else | ||
1936 | { | ||
1937 | fail = PARSE_FAIL_COND_SYNTAX_ERROR; | ||
1938 | break; | ||
1939 | } | ||
1940 | |||
1941 | lastcond[level] = data->num_tokens; | ||
1942 | numoptions[level]++; | ||
1943 | data->num_tokens++; | ||
1944 | break; | ||
1945 | |||
1946 | /* Comment */ | ||
1947 | case '#': | ||
1948 | if (level >= 0) /* there are unclosed conditionals */ | ||
1949 | { | ||
1950 | fail = PARSE_FAIL_UNCLOSED_COND; | ||
1951 | break; | ||
1952 | } | ||
1953 | |||
1954 | wps_bufptr += skip_end_of_line(wps_bufptr); | ||
1955 | break; | ||
1956 | |||
1957 | /* End of this line */ | ||
1958 | case '\n': | ||
1959 | if (level >= 0) /* there are unclosed conditionals */ | ||
1960 | { | ||
1961 | fail = PARSE_FAIL_UNCLOSED_COND; | ||
1962 | break; | ||
1963 | } | ||
1964 | /* add a new token for the \n so empty lines are correct */ | ||
1965 | data->tokens[data->num_tokens].type = WPS_TOKEN_CHARACTER; | ||
1966 | data->tokens[data->num_tokens].value.c = '\n'; | ||
1967 | data->tokens[data->num_tokens].next = false; | ||
1968 | data->num_tokens++; | ||
1969 | |||
1970 | if (!skin_start_new_line(curr_vp, data->num_tokens)) | ||
1971 | { | ||
1972 | fail = PARSE_FAIL_LIMITS_EXCEEDED; | ||
1973 | break; | ||
1974 | } | ||
1975 | line_number++; | ||
1976 | |||
1977 | break; | ||
1978 | |||
1979 | /* String */ | ||
1980 | default: | ||
1981 | { | ||
1982 | unsigned int len = 1; | ||
1983 | const char *string_start = wps_bufptr - 1; | ||
1984 | |||
1985 | /* find the length of the string */ | ||
1986 | while (*wps_bufptr && *wps_bufptr != '#' && | ||
1987 | *wps_bufptr != '%' && *wps_bufptr != ';' && | ||
1988 | *wps_bufptr != '<' && *wps_bufptr != '>' && | ||
1989 | *wps_bufptr != '|' && *wps_bufptr != '\n') | ||
1990 | { | ||
1991 | wps_bufptr++; | ||
1992 | len++; | ||
1993 | } | ||
1994 | |||
1995 | /* look if we already have that string */ | ||
1996 | char *str; | ||
1997 | bool found = false; | ||
1998 | struct skin_token_list *list = data->strings; | ||
1999 | while (list) | ||
2000 | { | ||
2001 | str = (char*)list->token->value.data; | ||
2002 | found = (strlen(str) == len && | ||
2003 | strncmp(string_start, str, len) == 0); | ||
2004 | if (found) | ||
2005 | break; /* break here because the list item is | ||
2006 | used if its found */ | ||
2007 | list = list->next; | ||
2008 | } | ||
2009 | /* If a matching string is found, found is true and i is | ||
2010 | the index of the string. If not, found is false */ | ||
2011 | |||
2012 | if (!found) | ||
2013 | { | ||
2014 | /* new string */ | ||
2015 | str = (char*)skin_buffer_alloc(len+1); | ||
2016 | if (!str) | ||
2017 | { | ||
2018 | fail = PARSE_FAIL_LIMITS_EXCEEDED; | ||
2019 | break; | ||
2020 | } | ||
2021 | strlcpy(str, string_start, len+1); | ||
2022 | struct skin_token_list *item = | ||
2023 | new_skin_token_list_item(&data->tokens[data->num_tokens], str); | ||
2024 | if(!item) | ||
2025 | { | ||
2026 | fail = PARSE_FAIL_LIMITS_EXCEEDED; | ||
2027 | break; | ||
2028 | } | ||
2029 | add_to_ll_chain(&data->strings, item); | ||
2030 | } | ||
2031 | else | ||
2032 | { | ||
2033 | /* another occurrence of an existing string */ | ||
2034 | data->tokens[data->num_tokens].value.data = list->token->value.data; | ||
2035 | } | ||
2036 | data->tokens[data->num_tokens].type = WPS_TOKEN_STRING; | ||
2037 | data->num_tokens++; | ||
2038 | } | ||
2039 | break; | ||
2040 | } | ||
2041 | } | ||
2042 | |||
2043 | if (!fail && level >= 0) /* there are unclosed conditionals */ | ||
2044 | fail = PARSE_FAIL_UNCLOSED_COND; | ||
2045 | |||
2046 | if (*wps_bufptr && !fail) | ||
2047 | /* one of the limits of the while loop was exceeded */ | ||
2048 | fail = PARSE_FAIL_LIMITS_EXCEEDED; | ||
2049 | |||
2050 | /* Success! */ | ||
2051 | curr_line->curr_subline->last_token_idx = data->num_tokens; | ||
2052 | data->tokens[data->num_tokens++].type = WPS_NO_TOKEN; | ||
2053 | /* freeup unused tokens */ | ||
2054 | skin_buffer_free_from_front(sizeof(struct wps_token) | ||
2055 | * (max_tokens - data->num_tokens)); | ||
2056 | |||
2057 | #ifdef DEBUG_SKIN_ENGINE | ||
2058 | if (debug) | ||
2059 | { | ||
2060 | print_debug_info(data, fail, line_number); | ||
2061 | debug_skin_usage(); | ||
2062 | } | 866 | } |
2063 | #else | ||
2064 | (void)debug; | ||
2065 | #endif | ||
2066 | |||
2067 | return (fail == 0); | ||
2068 | } | 867 | } |
2069 | 868 | ||
2070 | |||
2071 | /* | 869 | /* |
2072 | * initial setup of wps_data; does reset everything | 870 | * initial setup of wps_data; does reset everything |
2073 | * except fields which need to survive, i.e. | 871 | * except fields which need to survive, i.e. |
@@ -2075,6 +873,7 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr, bool debug) | |||
2075 | **/ | 873 | **/ |
2076 | static void skin_data_reset(struct wps_data *wps_data) | 874 | static void skin_data_reset(struct wps_data *wps_data) |
2077 | { | 875 | { |
876 | wps_data->tree = NULL; | ||
2078 | #ifdef HAVE_LCD_BITMAP | 877 | #ifdef HAVE_LCD_BITMAP |
2079 | wps_data->images = NULL; | 878 | wps_data->images = NULL; |
2080 | wps_data->progressbars = NULL; | 879 | wps_data->progressbars = NULL; |
@@ -2085,8 +884,6 @@ static void skin_data_reset(struct wps_data *wps_data) | |||
2085 | #ifdef HAVE_TOUCHSCREEN | 884 | #ifdef HAVE_TOUCHSCREEN |
2086 | wps_data->touchregions = NULL; | 885 | wps_data->touchregions = NULL; |
2087 | #endif | 886 | #endif |
2088 | wps_data->viewports = NULL; | ||
2089 | wps_data->strings = NULL; | ||
2090 | #ifdef HAVE_ALBUMART | 887 | #ifdef HAVE_ALBUMART |
2091 | wps_data->albumart = NULL; | 888 | wps_data->albumart = NULL; |
2092 | if (wps_data->playback_aa_slot >= 0) | 889 | if (wps_data->playback_aa_slot >= 0) |
@@ -2095,8 +892,6 @@ static void skin_data_reset(struct wps_data *wps_data) | |||
2095 | wps_data->playback_aa_slot = -1; | 892 | wps_data->playback_aa_slot = -1; |
2096 | } | 893 | } |
2097 | #endif | 894 | #endif |
2098 | wps_data->tokens = NULL; | ||
2099 | wps_data->num_tokens = 0; | ||
2100 | 895 | ||
2101 | #ifdef HAVE_LCD_BITMAP | 896 | #ifdef HAVE_LCD_BITMAP |
2102 | wps_data->peak_meter_enabled = false; | 897 | wps_data->peak_meter_enabled = false; |
@@ -2119,6 +914,7 @@ static bool load_skin_bmp(struct wps_data *wps_data, struct bitmap *bitmap, char | |||
2119 | { | 914 | { |
2120 | (void)wps_data; /* only needed for remote targets */ | 915 | (void)wps_data; /* only needed for remote targets */ |
2121 | char img_path[MAX_PATH]; | 916 | char img_path[MAX_PATH]; |
917 | int fd; | ||
2122 | get_image_filename(bitmap->data, bmpdir, | 918 | get_image_filename(bitmap->data, bmpdir, |
2123 | img_path, sizeof(img_path)); | 919 | img_path, sizeof(img_path)); |
2124 | 920 | ||
@@ -2131,14 +927,24 @@ static bool load_skin_bmp(struct wps_data *wps_data, struct bitmap *bitmap, char | |||
2131 | #endif | 927 | #endif |
2132 | format = FORMAT_ANY|FORMAT_TRANSPARENT; | 928 | format = FORMAT_ANY|FORMAT_TRANSPARENT; |
2133 | 929 | ||
2134 | size_t max_buf; | 930 | fd = open(img_path, O_RDONLY); |
2135 | char* imgbuf = (char*)skin_buffer_grab(&max_buf); | 931 | if (fd < 0) |
932 | return false; | ||
933 | size_t buf_size = read_bmp_file(img_path, bitmap, 0, | ||
934 | format|FORMAT_RETURN_SIZE, NULL); | ||
935 | char* imgbuf = (char*)skin_buffer_alloc(buf_size); | ||
936 | if (!imgbuf) | ||
937 | { | ||
938 | close(fd); | ||
939 | return NULL; | ||
940 | } | ||
941 | lseek(fd, 0, SEEK_SET); | ||
2136 | bitmap->data = imgbuf; | 942 | bitmap->data = imgbuf; |
2137 | int ret = read_bmp_file(img_path, bitmap, max_buf, format, NULL); | 943 | int ret = read_bmp_fd(fd, bitmap, buf_size, format, NULL); |
2138 | 944 | ||
945 | close(fd); | ||
2139 | if (ret > 0) | 946 | if (ret > 0) |
2140 | { | 947 | { |
2141 | skin_buffer_increment(ret, true); | ||
2142 | return true; | 948 | return true; |
2143 | } | 949 | } |
2144 | else | 950 | else |
@@ -2204,14 +1010,14 @@ static bool skin_load_fonts(struct wps_data *data) | |||
2204 | { | 1010 | { |
2205 | /* don't spit out after the first failue to aid debugging */ | 1011 | /* don't spit out after the first failue to aid debugging */ |
2206 | bool success = true; | 1012 | bool success = true; |
2207 | struct skin_token_list *vp_list; | 1013 | struct skin_element *vp_list; |
2208 | int font_id; | 1014 | int font_id; |
2209 | /* walk though each viewport and assign its font */ | 1015 | /* walk though each viewport and assign its font */ |
2210 | for(vp_list = data->viewports; vp_list; vp_list = vp_list->next) | 1016 | for(vp_list = data->tree; vp_list; vp_list = vp_list->next) |
2211 | { | 1017 | { |
2212 | /* first, find the viewports that have a non-sys/ui-font font */ | 1018 | /* first, find the viewports that have a non-sys/ui-font font */ |
2213 | struct skin_viewport *skin_vp = | 1019 | struct skin_viewport *skin_vp = |
2214 | (struct skin_viewport*)vp_list->token->value.data; | 1020 | (struct skin_viewport*)vp_list->data; |
2215 | struct viewport *vp = &skin_vp->vp; | 1021 | struct viewport *vp = &skin_vp->vp; |
2216 | 1022 | ||
2217 | 1023 | ||
@@ -2250,6 +1056,7 @@ static bool skin_load_fonts(struct wps_data *data) | |||
2250 | { | 1056 | { |
2251 | DEBUGF("Unable to load font %d: '%s.fnt'\n", | 1057 | DEBUGF("Unable to load font %d: '%s.fnt'\n", |
2252 | font_id, font->name); | 1058 | font_id, font->name); |
1059 | font->name = NULL; /* to stop trying to load it again if we fail */ | ||
2253 | success = false; | 1060 | success = false; |
2254 | font->name = NULL; | 1061 | font->name = NULL; |
2255 | continue; | 1062 | continue; |
@@ -2262,6 +1069,277 @@ static bool skin_load_fonts(struct wps_data *data) | |||
2262 | } | 1069 | } |
2263 | 1070 | ||
2264 | #endif /* HAVE_LCD_BITMAP */ | 1071 | #endif /* HAVE_LCD_BITMAP */ |
1072 | static int convert_viewport(struct wps_data *data, struct skin_element* element) | ||
1073 | { | ||
1074 | struct skin_viewport *skin_vp = | ||
1075 | (struct skin_viewport *)skin_buffer_alloc(sizeof(struct skin_viewport)); | ||
1076 | struct screen *display = &screens[curr_screen]; | ||
1077 | |||
1078 | if (!skin_vp) | ||
1079 | return CALLBACK_ERROR; | ||
1080 | |||
1081 | skin_vp->hidden_flags = 0; | ||
1082 | skin_vp->label = VP_NO_LABEL; | ||
1083 | element->data = skin_vp; | ||
1084 | curr_vp = skin_vp; | ||
1085 | curr_viewport_element = element; | ||
1086 | |||
1087 | viewport_set_defaults(&skin_vp->vp, curr_screen); | ||
1088 | |||
1089 | #if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)) | ||
1090 | skin_vp->start_fgcolour = skin_vp->vp.fg_pattern; | ||
1091 | skin_vp->start_bgcolour = skin_vp->vp.bg_pattern; | ||
1092 | #endif | ||
1093 | |||
1094 | |||
1095 | struct skin_tag_parameter *param = element->params; | ||
1096 | if (element->params_count == 0) /* default viewport */ | ||
1097 | { | ||
1098 | if (!data->tree) /* first viewport in the skin */ | ||
1099 | data->tree = element; | ||
1100 | skin_vp->label = VP_DEFAULT_LABEL; | ||
1101 | return CALLBACK_OK; | ||
1102 | } | ||
1103 | |||
1104 | if (element->params_count == 6) | ||
1105 | { | ||
1106 | if (element->tag->type == SKIN_TOKEN_UIVIEWPORT_LOAD) | ||
1107 | { | ||
1108 | if (isdefault(param)) | ||
1109 | { | ||
1110 | skin_vp->hidden_flags = VP_NEVER_VISIBLE; | ||
1111 | skin_vp->label = VP_INFO_LABEL|VP_DEFAULT_LABEL; | ||
1112 | } | ||
1113 | else | ||
1114 | { | ||
1115 | skin_vp->hidden_flags = VP_NEVER_VISIBLE; | ||
1116 | skin_vp->label = VP_INFO_LABEL|param->data.text[0]; | ||
1117 | } | ||
1118 | } | ||
1119 | else | ||
1120 | { | ||
1121 | skin_vp->hidden_flags = VP_DRAW_HIDEABLE|VP_DRAW_HIDDEN; | ||
1122 | skin_vp->label = param->data.text[0]; | ||
1123 | } | ||
1124 | param++; | ||
1125 | } | ||
1126 | /* x */ | ||
1127 | if (!isdefault(param)) | ||
1128 | { | ||
1129 | skin_vp->vp.x = param->data.number; | ||
1130 | if (param->data.number < 0) | ||
1131 | skin_vp->vp.x += display->lcdwidth; | ||
1132 | } | ||
1133 | param++; | ||
1134 | /* y */ | ||
1135 | if (!isdefault(param)) | ||
1136 | { | ||
1137 | skin_vp->vp.y = param->data.number; | ||
1138 | if (param->data.number < 0) | ||
1139 | skin_vp->vp.y += display->lcdheight; | ||
1140 | } | ||
1141 | param++; | ||
1142 | /* width */ | ||
1143 | if (!isdefault(param)) | ||
1144 | { | ||
1145 | skin_vp->vp.width = param->data.number; | ||
1146 | if (param->data.number < 0) | ||
1147 | skin_vp->vp.width = (skin_vp->vp.width + display->lcdwidth) - skin_vp->vp.x; | ||
1148 | } | ||
1149 | else | ||
1150 | { | ||
1151 | skin_vp->vp.width = display->lcdwidth - skin_vp->vp.x; | ||
1152 | } | ||
1153 | param++; | ||
1154 | /* height */ | ||
1155 | if (!isdefault(param)) | ||
1156 | { | ||
1157 | skin_vp->vp.height = param->data.number; | ||
1158 | if (param->data.number < 0) | ||
1159 | skin_vp->vp.height = (skin_vp->vp.height + display->lcdheight) - skin_vp->vp.y; | ||
1160 | } | ||
1161 | else | ||
1162 | { | ||
1163 | skin_vp->vp.height = display->lcdheight - skin_vp->vp.y; | ||
1164 | } | ||
1165 | param++; | ||
1166 | #ifdef HAVE_LCD_BITMAP | ||
1167 | /* font */ | ||
1168 | if (!isdefault(param)) | ||
1169 | { | ||
1170 | skin_vp->vp.font = param->data.number; | ||
1171 | } | ||
1172 | #endif | ||
1173 | |||
1174 | return CALLBACK_OK; | ||
1175 | |||
1176 | } | ||
1177 | |||
1178 | int skin_element_callback(struct skin_element* element, void* data) | ||
1179 | { | ||
1180 | struct wps_data *wps_data = (struct wps_data *)data; | ||
1181 | struct wps_token *token; | ||
1182 | parse_function function = NULL; | ||
1183 | |||
1184 | switch (element->type) | ||
1185 | { | ||
1186 | /* IMPORTANT: element params are shared, so copy them if needed | ||
1187 | * or use then NOW, dont presume they have a long lifespan | ||
1188 | */ | ||
1189 | case TAG: | ||
1190 | { | ||
1191 | token = (struct wps_token*)skin_buffer_alloc(sizeof(struct wps_token)); | ||
1192 | memset(token, 0, sizeof(*token)); | ||
1193 | token->type = element->tag->type; | ||
1194 | |||
1195 | if ((element->tag->flags&SKIN_REFRESH_ALL) == SKIN_RTC_REFRESH) | ||
1196 | { | ||
1197 | #ifdef CONFIG_RTC | ||
1198 | curr_line->update_mode |= SKIN_REFRESH_DYNAMIC; | ||
1199 | #else | ||
1200 | curr_line->update_mode |= SKIN_REFRESH_STATIC; | ||
1201 | #endif | ||
1202 | } | ||
1203 | else | ||
1204 | curr_line->update_mode |= element->tag->flags&SKIN_REFRESH_ALL; | ||
1205 | |||
1206 | element->data = token; | ||
1207 | |||
1208 | /* Some tags need special handling for the tag, so add them here */ | ||
1209 | switch (token->type) | ||
1210 | { | ||
1211 | case SKIN_TOKEN_ALIGN_LANGDIRECTION: | ||
1212 | follow_lang_direction = 2; | ||
1213 | break; | ||
1214 | case SKIN_TOKEN_PROGRESSBAR: | ||
1215 | case SKIN_TOKEN_VOLUME: | ||
1216 | case SKIN_TOKEN_BATTERY_PERCENT: | ||
1217 | case SKIN_TOKEN_PLAYER_PROGRESSBAR: | ||
1218 | function = parse_progressbar_tag; | ||
1219 | break; | ||
1220 | case SKIN_TOKEN_SUBLINE_TIMEOUT: | ||
1221 | case SKIN_TOKEN_BUTTON_VOLUME: | ||
1222 | case SKIN_TOKEN_TRACK_STARTING: | ||
1223 | case SKIN_TOKEN_TRACK_ENDING: | ||
1224 | case SKIN_TOKEN_LASTTOUCH: | ||
1225 | function = parse_timeout_tag; | ||
1226 | break; | ||
1227 | #ifdef HAVE_LCD_BITMAP | ||
1228 | case SKIN_TOKEN_DISABLE_THEME: | ||
1229 | case SKIN_TOKEN_ENABLE_THEME: | ||
1230 | case SKIN_TOKEN_DRAW_INBUILTBAR: | ||
1231 | function = parse_statusbar_tags; | ||
1232 | break; | ||
1233 | #endif | ||
1234 | case SKIN_TOKEN_FILE_DIRECTORY: | ||
1235 | token->value.i = element->params[0].data.number; | ||
1236 | break; | ||
1237 | #if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)) | ||
1238 | case SKIN_TOKEN_VIEWPORT_FGCOLOUR: | ||
1239 | case SKIN_TOKEN_VIEWPORT_BGCOLOUR: | ||
1240 | function = parse_viewportcolour; | ||
1241 | break; | ||
1242 | case SKIN_TOKEN_IMAGE_BACKDROP: | ||
1243 | function = parse_image_special; | ||
1244 | break; | ||
1245 | #endif | ||
1246 | case SKIN_TOKEN_TRANSLATEDSTRING: | ||
1247 | case SKIN_TOKEN_SETTING: | ||
1248 | function = parse_setting_and_lang; | ||
1249 | break; | ||
1250 | #ifdef HAVE_LCD_BITMAP | ||
1251 | case SKIN_TOKEN_VIEWPORT_CUSTOMLIST: | ||
1252 | function = parse_playlistview; | ||
1253 | break; | ||
1254 | case SKIN_TOKEN_LOAD_FONT: | ||
1255 | function = parse_font_load; | ||
1256 | break; | ||
1257 | case SKIN_TOKEN_VIEWPORT_ENABLE: | ||
1258 | case SKIN_TOKEN_UIVIEWPORT_ENABLE: | ||
1259 | token->value.i = element->params[0].data.text[0]; | ||
1260 | break; | ||
1261 | case SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY: | ||
1262 | function = parse_image_display; | ||
1263 | break; | ||
1264 | case SKIN_TOKEN_IMAGE_PRELOAD: | ||
1265 | case SKIN_TOKEN_IMAGE_DISPLAY: | ||
1266 | function = parse_image_load; | ||
1267 | break; | ||
1268 | #endif | ||
1269 | #ifdef HAVE_TOUCHSCREEN | ||
1270 | case SKIN_TOKEN_TOUCHREGION: | ||
1271 | function = parse_touchregion; | ||
1272 | break; | ||
1273 | #endif | ||
1274 | #ifdef HAVE_ALBUMART | ||
1275 | case SKIN_TOKEN_ALBUMART_DISPLAY: | ||
1276 | if (wps_data->albumart) | ||
1277 | wps_data->albumart->vp = &curr_vp->vp; | ||
1278 | break; | ||
1279 | case SKIN_TOKEN_ALBUMART_LOAD: | ||
1280 | function = parse_albumart_load; | ||
1281 | break; | ||
1282 | #endif | ||
1283 | default: | ||
1284 | break; | ||
1285 | } | ||
1286 | if (function) | ||
1287 | { | ||
1288 | if (function(element, token, wps_data) < 0) | ||
1289 | return CALLBACK_ERROR; | ||
1290 | } | ||
1291 | /* tags that start with 'F', 'I' or 'D' are for the next file */ | ||
1292 | if ( *(element->tag->name) == 'I' || *(element->tag->name) == 'F' || | ||
1293 | *(element->tag->name) == 'D') | ||
1294 | token->next = true; | ||
1295 | if (follow_lang_direction > 0 ) | ||
1296 | follow_lang_direction--; | ||
1297 | break; | ||
1298 | } | ||
1299 | case VIEWPORT: | ||
1300 | return convert_viewport(wps_data, element); | ||
1301 | case LINE: | ||
1302 | { | ||
1303 | struct line *line = | ||
1304 | (struct line *)skin_buffer_alloc(sizeof(struct line)); | ||
1305 | line->update_mode = SKIN_REFRESH_STATIC; | ||
1306 | line->timeout = DEFAULT_SUBLINE_TIME_MULTIPLIER * TIMEOUT_UNIT; | ||
1307 | curr_line = line; | ||
1308 | element->data = line; | ||
1309 | } | ||
1310 | break; | ||
1311 | case LINE_ALTERNATOR: | ||
1312 | { | ||
1313 | struct line_alternator *alternator = | ||
1314 | (struct line_alternator *)skin_buffer_alloc(sizeof(struct line_alternator)); | ||
1315 | alternator->current_line = 0; | ||
1316 | #ifndef __PCTOOL__ | ||
1317 | alternator->last_change_tick = current_tick; | ||
1318 | #endif | ||
1319 | element->data = alternator; | ||
1320 | } | ||
1321 | break; | ||
1322 | case CONDITIONAL: | ||
1323 | { | ||
1324 | struct conditional *conditional = | ||
1325 | (struct conditional *)skin_buffer_alloc(sizeof(struct conditional)); | ||
1326 | conditional->last_value = -1; | ||
1327 | conditional->token = element->data; | ||
1328 | element->data = conditional; | ||
1329 | if (!check_feature_tag(element->tag->type)) | ||
1330 | { | ||
1331 | return FEATURE_NOT_AVAILABLE; | ||
1332 | } | ||
1333 | return CALLBACK_OK; | ||
1334 | } | ||
1335 | case TEXT: | ||
1336 | curr_line->update_mode |= SKIN_REFRESH_STATIC; | ||
1337 | break; | ||
1338 | default: | ||
1339 | break; | ||
1340 | } | ||
1341 | return CALLBACK_OK; | ||
1342 | } | ||
2265 | 1343 | ||
2266 | /* to setup up the wps-data from a format-buffer (isfile = false) | 1344 | /* to setup up the wps-data from a format-buffer (isfile = false) |
2267 | from a (wps-)file (isfile = true)*/ | 1345 | from a (wps-)file (isfile = true)*/ |
@@ -2298,37 +1376,13 @@ bool skin_data_load(enum screen_type screen, struct wps_data *wps_data, | |||
2298 | } | 1376 | } |
2299 | #endif | 1377 | #endif |
2300 | 1378 | ||
1379 | |||
2301 | skin_data_reset(wps_data); | 1380 | skin_data_reset(wps_data); |
2302 | wps_data->wps_loaded = false; | 1381 | wps_data->wps_loaded = false; |
2303 | curr_screen = screen; | 1382 | curr_screen = screen; |
2304 | |||
2305 | /* alloc default viewport, will be fixed up later */ | ||
2306 | curr_vp = skin_buffer_alloc(sizeof(struct skin_viewport)); | ||
2307 | if (!curr_vp) | ||
2308 | return false; | ||
2309 | struct skin_token_list *list = new_skin_token_list_item(NULL, curr_vp); | ||
2310 | if (!list) | ||
2311 | return false; | ||
2312 | add_to_ll_chain(&wps_data->viewports, list); | ||
2313 | |||
2314 | |||
2315 | /* Initialise the first (default) viewport */ | ||
2316 | curr_vp->label = VP_DEFAULT_LABEL; | ||
2317 | curr_vp->hidden_flags = 0; | ||
2318 | curr_vp->lines = NULL; | ||
2319 | |||
2320 | viewport_set_defaults(&curr_vp->vp, screen); | ||
2321 | #if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)) | ||
2322 | curr_vp->start_fgcolour = curr_vp->vp.fg_pattern; | ||
2323 | curr_vp->start_bgcolour = curr_vp->vp.bg_pattern; | ||
2324 | #endif | ||
2325 | #ifdef HAVE_LCD_BITMAP | ||
2326 | curr_vp->vp.font = FONT_UI; | ||
2327 | #endif | ||
2328 | |||
2329 | curr_line = NULL; | 1383 | curr_line = NULL; |
2330 | if (!skin_start_new_line(curr_vp, 0)) | 1384 | curr_vp = NULL; |
2331 | return false; | 1385 | curr_viewport_element = NULL; |
2332 | 1386 | ||
2333 | if (isfile) | 1387 | if (isfile) |
2334 | { | 1388 | { |
@@ -2364,9 +1418,15 @@ bool skin_data_load(enum screen_type screen, struct wps_data *wps_data, | |||
2364 | { | 1418 | { |
2365 | wps_buffer = (char*)buf; | 1419 | wps_buffer = (char*)buf; |
2366 | } | 1420 | } |
2367 | /* parse the WPS source */ | 1421 | #if LCD_DEPTH > 1 || defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1 |
2368 | if (!wps_parse(wps_data, wps_buffer, isfile)) { | 1422 | wps_data->backdrop = "-"; |
1423 | #endif | ||
1424 | /* parse the skin source */ | ||
1425 | skin_buffer_save_position(); | ||
1426 | wps_data->tree = skin_parse(wps_buffer, skin_element_callback, wps_data); | ||
1427 | if (!wps_data->tree) { | ||
2369 | skin_data_reset(wps_data); | 1428 | skin_data_reset(wps_data); |
1429 | skin_buffer_restore_position(); | ||
2370 | return false; | 1430 | return false; |
2371 | } | 1431 | } |
2372 | 1432 | ||
@@ -2387,6 +1447,7 @@ bool skin_data_load(enum screen_type screen, struct wps_data *wps_data, | |||
2387 | !skin_load_fonts(wps_data)) | 1447 | !skin_load_fonts(wps_data)) |
2388 | { | 1448 | { |
2389 | skin_data_reset(wps_data); | 1449 | skin_data_reset(wps_data); |
1450 | skin_buffer_restore_position(); | ||
2390 | return false; | 1451 | return false; |
2391 | } | 1452 | } |
2392 | #endif | 1453 | #endif |
@@ -2410,8 +1471,8 @@ bool skin_data_load(enum screen_type screen, struct wps_data *wps_data, | |||
2410 | #endif | 1471 | #endif |
2411 | wps_data->wps_loaded = true; | 1472 | wps_data->wps_loaded = true; |
2412 | #ifdef DEBUG_SKIN_ENGINE | 1473 | #ifdef DEBUG_SKIN_ENGINE |
2413 | if (isfile && debug_wps) | 1474 | // if (isfile && debug_wps) |
2414 | debug_skin_usage(); | 1475 | // debug_skin_usage(); |
2415 | #endif | 1476 | #endif |
2416 | return true; | 1477 | return true; |
2417 | } | 1478 | } |
diff --git a/apps/gui/skin_engine/skin_render.c b/apps/gui/skin_engine/skin_render.c new file mode 100644 index 0000000000..e05f97ff4e --- /dev/null +++ b/apps/gui/skin_engine/skin_render.c | |||
@@ -0,0 +1,614 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id: skin_parser.c 26752 2010-06-10 21:22:16Z bieber $ | ||
9 | * | ||
10 | * Copyright (C) 2010 Jonathan Gordon | ||
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 | #include <stdlib.h> | ||
23 | #include <stdio.h> | ||
24 | #include <string.h> | ||
25 | #include <stdbool.h> | ||
26 | #include <ctype.h> | ||
27 | #include "strlcat.h" | ||
28 | |||
29 | #include "config.h" | ||
30 | #include "kernel.h" | ||
31 | #ifdef HAVE_ALBUMART | ||
32 | #include "albumart.h" | ||
33 | #endif | ||
34 | #include "skin_display.h" | ||
35 | #include "skin_engine.h" | ||
36 | #include "skin_parser.h" | ||
37 | #include "tag_table.h" | ||
38 | #include "skin_scan.h" | ||
39 | #if CONFIG_TUNER | ||
40 | #include "radio.h" | ||
41 | #endif | ||
42 | #include "language.h" | ||
43 | #include "playback.h" | ||
44 | |||
45 | |||
46 | #define MAX_LINE 1024 | ||
47 | |||
48 | struct skin_draw_info { | ||
49 | struct gui_wps *gwps; | ||
50 | struct skin_viewport *skin_vp; | ||
51 | int line_number; | ||
52 | unsigned long refresh_type; | ||
53 | |||
54 | char* cur_align_start; | ||
55 | struct align_pos align; | ||
56 | bool no_line_break; | ||
57 | bool line_scrolls; | ||
58 | bool force_redraw; | ||
59 | |||
60 | char *buf; | ||
61 | size_t buf_size; | ||
62 | }; | ||
63 | |||
64 | typedef bool (*skin_render_func)(struct skin_element* alternator, struct skin_draw_info *info); | ||
65 | bool skin_render_alternator(struct skin_element* alternator, struct skin_draw_info *info); | ||
66 | |||
67 | |||
68 | static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info, | ||
69 | struct skin_element *element, struct viewport* vp) | ||
70 | { | ||
71 | #ifndef HAVE_LCD_BITMAP | ||
72 | (void)vp; /* silence warnings */ | ||
73 | #endif | ||
74 | struct wps_token *token = (struct wps_token *)element->data; | ||
75 | struct wps_data *data = gwps->data; | ||
76 | bool do_refresh = (element->tag->flags & info->refresh_type) > 0; | ||
77 | switch (token->type) | ||
78 | { | ||
79 | #if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)) | ||
80 | case SKIN_TOKEN_VIEWPORT_FGCOLOUR: | ||
81 | { | ||
82 | struct viewport_colour *col = token->value.data; | ||
83 | col->vp->fg_pattern = col->colour; | ||
84 | } | ||
85 | break; | ||
86 | case SKIN_TOKEN_VIEWPORT_BGCOLOUR: | ||
87 | { | ||
88 | struct viewport_colour *col = token->value.data; | ||
89 | col->vp->bg_pattern = col->colour; | ||
90 | } | ||
91 | break; | ||
92 | #endif | ||
93 | case SKIN_TOKEN_VIEWPORT_ENABLE: | ||
94 | { | ||
95 | char label = token->value.i; | ||
96 | char temp = VP_DRAW_HIDEABLE; | ||
97 | struct skin_element *viewport = gwps->data->tree; | ||
98 | while (viewport) | ||
99 | { | ||
100 | struct skin_viewport *skinvp = (struct skin_viewport*)viewport->data; | ||
101 | if (skinvp->label == label) | ||
102 | { | ||
103 | if (skinvp->hidden_flags&VP_DRAW_HIDDEN) | ||
104 | { | ||
105 | temp |= VP_DRAW_WASHIDDEN; | ||
106 | } | ||
107 | skinvp->hidden_flags = temp; | ||
108 | } | ||
109 | viewport = viewport->next; | ||
110 | } | ||
111 | } | ||
112 | break; | ||
113 | #ifdef HAVE_LCD_BITMAP | ||
114 | case SKIN_TOKEN_UIVIEWPORT_ENABLE: | ||
115 | sb_set_info_vp(gwps->display->screen_type, | ||
116 | token->value.i|VP_INFO_LABEL); | ||
117 | break; | ||
118 | case SKIN_TOKEN_PEAKMETER: | ||
119 | data->peak_meter_enabled = true; | ||
120 | if (do_refresh) | ||
121 | draw_peakmeters(gwps, info->line_number, vp); | ||
122 | break; | ||
123 | #endif | ||
124 | case SKIN_TOKEN_VOLUMEBAR: | ||
125 | case SKIN_TOKEN_BATTERY_PERCENTBAR: | ||
126 | case SKIN_TOKEN_PROGRESSBAR: | ||
127 | { | ||
128 | #ifdef HAVE_LCD_BITMAP | ||
129 | struct progressbar *bar = (struct progressbar*)token->value.data; | ||
130 | if (do_refresh) | ||
131 | draw_progressbar(gwps, info->line_number, bar); | ||
132 | #else /* HAVE_LCD_CHARCELL */ | ||
133 | if (do_refresh) | ||
134 | { | ||
135 | if (data->full_line_progressbar) | ||
136 | draw_player_fullbar(gwps, info->buf, info->buf_size); | ||
137 | else | ||
138 | draw_player_progress(gwps); | ||
139 | } | ||
140 | #endif | ||
141 | } | ||
142 | break; | ||
143 | #ifdef HAVE_LCD_BITMAP | ||
144 | case SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY: | ||
145 | { | ||
146 | char n = token->value.i & 0xFF; | ||
147 | int subimage = token->value.i >> 8; | ||
148 | struct gui_img *img = find_image(n, data); | ||
149 | if (img && img->loaded) | ||
150 | img->display = subimage; | ||
151 | break; | ||
152 | } | ||
153 | #ifdef HAVE_ALBUMART | ||
154 | case SKIN_TOKEN_ALBUMART_DISPLAY: | ||
155 | /* now draw the AA */ | ||
156 | if (data->albumart) | ||
157 | { | ||
158 | int handle = playback_current_aa_hid(data->playback_aa_slot); | ||
159 | #if CONFIG_TUNER | ||
160 | if (in_radio_screen() || (get_radio_status() != FMRADIO_OFF)) | ||
161 | { | ||
162 | struct dim dim = {data->albumart->width, data->albumart->height}; | ||
163 | handle = radio_get_art_hid(&dim); | ||
164 | } | ||
165 | #endif | ||
166 | data->albumart->draw_handle = handle; | ||
167 | } | ||
168 | break; | ||
169 | #endif | ||
170 | case SKIN_TOKEN_DRAW_INBUILTBAR: | ||
171 | gui_statusbar_draw(&(statusbars.statusbars[gwps->display->screen_type]), | ||
172 | info->refresh_type == SKIN_REFRESH_ALL, | ||
173 | token->value.data); | ||
174 | break; | ||
175 | case SKIN_TOKEN_VIEWPORT_CUSTOMLIST: | ||
176 | if (do_refresh) | ||
177 | draw_playlist_viewer_list(gwps, token->value.data); | ||
178 | break; | ||
179 | |||
180 | #endif /* HAVE_LCD_BITMAP */ | ||
181 | default: | ||
182 | return false; | ||
183 | } | ||
184 | return true; | ||
185 | } | ||
186 | |||
187 | |||
188 | |||
189 | static void do_tags_in_hidden_conditional(struct skin_element* branch, | ||
190 | struct skin_draw_info *info) | ||
191 | { | ||
192 | #ifdef HAVE_LCD_BITMAP | ||
193 | struct gui_wps *gwps = info->gwps; | ||
194 | struct wps_data *data = gwps->data; | ||
195 | #endif | ||
196 | /* Tags here are ones which need to be "turned off" or cleared | ||
197 | * if they are in a conditional branch which isnt being used */ | ||
198 | if (branch->type == LINE_ALTERNATOR) | ||
199 | { | ||
200 | int i; | ||
201 | for (i=0; i<branch->children_count; i++) | ||
202 | { | ||
203 | do_tags_in_hidden_conditional(branch->children[i], info); | ||
204 | } | ||
205 | } | ||
206 | else if (branch->type == LINE && branch->children_count) | ||
207 | { | ||
208 | struct skin_element *child = branch->children[0]; | ||
209 | struct wps_token *token; | ||
210 | while (child) | ||
211 | { | ||
212 | if (child->type == CONDITIONAL) | ||
213 | { | ||
214 | int i; | ||
215 | for (i=0; i<child->children_count; i++) | ||
216 | { | ||
217 | do_tags_in_hidden_conditional(child->children[i], info); | ||
218 | } | ||
219 | child = child->next; | ||
220 | continue; | ||
221 | } | ||
222 | else if (child->type != TAG || !child->data) | ||
223 | { | ||
224 | child = child->next; | ||
225 | continue; | ||
226 | } | ||
227 | token = (struct wps_token *)child->data; | ||
228 | #ifdef HAVE_LCD_BITMAP | ||
229 | /* clear all pictures in the conditional and nested ones */ | ||
230 | if (token->type == SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY) | ||
231 | { | ||
232 | struct gui_img *img = find_image(token->value.i&0xFF, data); | ||
233 | clear_image_pos(gwps, img); | ||
234 | } | ||
235 | else if (token->type == SKIN_TOKEN_PEAKMETER) | ||
236 | { | ||
237 | data->peak_meter_enabled = false; | ||
238 | } | ||
239 | else if (token->type == SKIN_TOKEN_VIEWPORT_ENABLE) | ||
240 | { | ||
241 | char label = token->value.i&0x7f; | ||
242 | struct skin_element *viewport; | ||
243 | for (viewport = data->tree; | ||
244 | viewport; | ||
245 | viewport = viewport->next) | ||
246 | { | ||
247 | struct skin_viewport *skin_viewport = (struct skin_viewport*)viewport->data; | ||
248 | if ((skin_viewport->label&0x7f) != label) | ||
249 | continue; | ||
250 | if (skin_viewport->hidden_flags&VP_NEVER_VISIBLE) | ||
251 | { | ||
252 | continue; | ||
253 | } | ||
254 | if (skin_viewport->hidden_flags&VP_DRAW_HIDEABLE) | ||
255 | { | ||
256 | if (skin_viewport->hidden_flags&VP_DRAW_HIDDEN) | ||
257 | skin_viewport->hidden_flags |= VP_DRAW_WASHIDDEN; | ||
258 | else | ||
259 | { | ||
260 | gwps->display->set_viewport(&skin_viewport->vp); | ||
261 | gwps->display->clear_viewport(); | ||
262 | gwps->display->scroll_stop(&skin_viewport->vp); | ||
263 | gwps->display->set_viewport(&info->skin_vp->vp); | ||
264 | skin_viewport->hidden_flags |= VP_DRAW_HIDDEN; | ||
265 | } | ||
266 | } | ||
267 | } | ||
268 | } | ||
269 | #endif | ||
270 | #ifdef HAVE_ALBUMART | ||
271 | else if (data->albumart && token->type == SKIN_TOKEN_ALBUMART_DISPLAY) | ||
272 | { | ||
273 | draw_album_art(gwps, | ||
274 | playback_current_aa_hid(data->playback_aa_slot), true); | ||
275 | } | ||
276 | #endif | ||
277 | child = child->next; | ||
278 | } | ||
279 | } | ||
280 | } | ||
281 | |||
282 | static void fix_line_alignment(struct skin_draw_info *info, struct skin_element *element) | ||
283 | { | ||
284 | struct align_pos *align = &info->align; | ||
285 | char *cur_pos = info->cur_align_start + strlen(info->cur_align_start); | ||
286 | switch (element->tag->type) | ||
287 | { | ||
288 | case SKIN_TOKEN_ALIGN_LEFT: | ||
289 | *cur_pos = '\0'; cur_pos++; *cur_pos = '\0'; | ||
290 | align->left = cur_pos; | ||
291 | info->cur_align_start = cur_pos; | ||
292 | break; | ||
293 | case SKIN_TOKEN_ALIGN_LEFT_RTL: | ||
294 | *cur_pos = '\0'; cur_pos++; *cur_pos = '\0'; | ||
295 | if (lang_is_rtl()) | ||
296 | align->right = cur_pos; | ||
297 | else | ||
298 | align->left = cur_pos; | ||
299 | info->cur_align_start = cur_pos; | ||
300 | break; | ||
301 | case SKIN_TOKEN_ALIGN_CENTER: | ||
302 | *cur_pos = '\0'; cur_pos++; *cur_pos = '\0'; | ||
303 | align->center = cur_pos; | ||
304 | info->cur_align_start = cur_pos; | ||
305 | break; | ||
306 | case SKIN_TOKEN_ALIGN_RIGHT: | ||
307 | *cur_pos = '\0'; cur_pos++; *cur_pos = '\0'; | ||
308 | align->right = cur_pos; | ||
309 | info->cur_align_start = cur_pos; | ||
310 | break; | ||
311 | case SKIN_TOKEN_ALIGN_RIGHT_RTL: | ||
312 | *cur_pos = '\0'; cur_pos++; *cur_pos = '\0'; | ||
313 | if (lang_is_rtl()) | ||
314 | align->left = cur_pos; | ||
315 | else | ||
316 | align->right = cur_pos; | ||
317 | info->cur_align_start = cur_pos; | ||
318 | break; | ||
319 | default: | ||
320 | break; | ||
321 | } | ||
322 | } | ||
323 | |||
324 | /* Draw a LINE element onto the display */ | ||
325 | bool skin_render_line(struct skin_element* line, struct skin_draw_info *info) | ||
326 | { | ||
327 | bool needs_update = false; | ||
328 | int last_value, value; | ||
329 | |||
330 | if (line->children_count == 0) | ||
331 | return false; /* empty line, do nothing */ | ||
332 | |||
333 | struct skin_element *child = line->children[0]; | ||
334 | struct conditional *conditional; | ||
335 | skin_render_func func = skin_render_line; | ||
336 | char tempbuf[128]; | ||
337 | int old_refresh_mode = info->refresh_type; | ||
338 | while (child) | ||
339 | { | ||
340 | tempbuf[0] = '\0'; | ||
341 | switch (child->type) | ||
342 | { | ||
343 | case CONDITIONAL: | ||
344 | conditional = (struct conditional*)child->data; | ||
345 | last_value = conditional->last_value; | ||
346 | value = evaluate_conditional(info->gwps, conditional, child->children_count); | ||
347 | |||
348 | if (value != 1 && value >= child->children_count) | ||
349 | value = child->children_count-1; | ||
350 | if (child->children_count == 1) | ||
351 | { | ||
352 | /* special handling so | ||
353 | * %?aa<true> and %?<true|false> need special handlng here */ | ||
354 | |||
355 | if (value == 1) /* tag is false */ | ||
356 | { | ||
357 | /* we are in a false branch of a %?aa<true> conditional */ | ||
358 | if (last_value == 0) | ||
359 | do_tags_in_hidden_conditional(child->children[0], info); | ||
360 | break; | ||
361 | } | ||
362 | value = 0; | ||
363 | } | ||
364 | else | ||
365 | { | ||
366 | if (last_value >= 0 && value != last_value && last_value < child->children_count) | ||
367 | do_tags_in_hidden_conditional(child->children[last_value], info); | ||
368 | } | ||
369 | if (child->children[value]->type == LINE_ALTERNATOR) | ||
370 | { | ||
371 | func = skin_render_alternator; | ||
372 | } | ||
373 | else if (child->children[value]->type == LINE) | ||
374 | func = skin_render_line; | ||
375 | |||
376 | if (value != last_value) | ||
377 | { | ||
378 | info->refresh_type = SKIN_REFRESH_ALL; | ||
379 | info->force_redraw = true; | ||
380 | } | ||
381 | |||
382 | if (func(child->children[value], info)) | ||
383 | needs_update = true; | ||
384 | else | ||
385 | needs_update = needs_update || (last_value != value); | ||
386 | |||
387 | info->refresh_type = old_refresh_mode; | ||
388 | break; | ||
389 | case TAG: | ||
390 | if (child->tag->flags & NOBREAK) | ||
391 | info->no_line_break = true; | ||
392 | if (child->tag->type == SKIN_TOKEN_SUBLINE_SCROLL) | ||
393 | info->line_scrolls = true; | ||
394 | |||
395 | fix_line_alignment(info, child); | ||
396 | |||
397 | if (!child->data) | ||
398 | { | ||
399 | break; | ||
400 | } | ||
401 | if (!do_non_text_tags(info->gwps, info, child, &info->skin_vp->vp)) | ||
402 | { | ||
403 | const char *value = get_token_value(info->gwps, child->data, | ||
404 | tempbuf, sizeof(tempbuf), NULL); | ||
405 | if (value) | ||
406 | { | ||
407 | needs_update = needs_update || | ||
408 | ((child->tag->flags&info->refresh_type)!=0); | ||
409 | strlcat(info->cur_align_start, value, | ||
410 | info->buf_size - (info->cur_align_start-info->buf)); | ||
411 | } | ||
412 | } | ||
413 | break; | ||
414 | case TEXT: | ||
415 | strlcat(info->cur_align_start, child->data, | ||
416 | info->buf_size - (info->cur_align_start-info->buf)); | ||
417 | needs_update = needs_update || | ||
418 | (info->refresh_type&SKIN_REFRESH_STATIC) != 0; | ||
419 | break; | ||
420 | case COMMENT: | ||
421 | default: | ||
422 | break; | ||
423 | } | ||
424 | |||
425 | child = child->next; | ||
426 | } | ||
427 | return needs_update; | ||
428 | } | ||
429 | |||
430 | bool skin_render_alternator(struct skin_element* element, struct skin_draw_info *info) | ||
431 | { | ||
432 | bool changed_lines = false; | ||
433 | struct line_alternator *alternator = (struct line_alternator*)element->data; | ||
434 | unsigned old_refresh = info->refresh_type; | ||
435 | if (info->refresh_type == SKIN_REFRESH_ALL) | ||
436 | { | ||
437 | alternator->current_line = 0; | ||
438 | alternator->last_change_tick = current_tick; | ||
439 | changed_lines = true; | ||
440 | } | ||
441 | else | ||
442 | { | ||
443 | struct skin_element *current_line = element->children[alternator->current_line]; | ||
444 | struct line *line = (struct line *)current_line->data; | ||
445 | int next_change = alternator->last_change_tick + line->timeout; | ||
446 | if (TIME_AFTER(current_tick, next_change)) | ||
447 | { | ||
448 | alternator->current_line++; | ||
449 | if (alternator->current_line >= element->children_count) | ||
450 | alternator->current_line = 0; | ||
451 | alternator->last_change_tick = current_tick; | ||
452 | changed_lines = true; | ||
453 | } | ||
454 | } | ||
455 | if (element->children[alternator->current_line]->children_count == 0) | ||
456 | { | ||
457 | /* skip empty sublines */ | ||
458 | alternator->current_line++; | ||
459 | if (alternator->current_line >= element->children_count) | ||
460 | alternator->current_line = 0; | ||
461 | changed_lines = true; | ||
462 | } | ||
463 | |||
464 | if (changed_lines) | ||
465 | { | ||
466 | info->refresh_type = SKIN_REFRESH_ALL; | ||
467 | info->force_redraw = true; | ||
468 | } | ||
469 | bool ret = skin_render_line(element->children[alternator->current_line], info); | ||
470 | info->refresh_type = old_refresh; | ||
471 | return changed_lines || ret; | ||
472 | } | ||
473 | |||
474 | void skin_render_viewport(struct skin_element* viewport, struct gui_wps *gwps, | ||
475 | struct skin_viewport* skin_viewport, unsigned long refresh_type) | ||
476 | { | ||
477 | struct screen *display = gwps->display; | ||
478 | char linebuf[MAX_LINE]; | ||
479 | skin_render_func func = skin_render_line; | ||
480 | struct skin_element* line = viewport; | ||
481 | struct skin_draw_info info = { | ||
482 | .gwps = gwps, | ||
483 | .buf = linebuf, | ||
484 | .buf_size = sizeof(linebuf), | ||
485 | .line_number = 0, | ||
486 | .no_line_break = false, | ||
487 | .line_scrolls = false, | ||
488 | .refresh_type = refresh_type, | ||
489 | .skin_vp = skin_viewport | ||
490 | }; | ||
491 | |||
492 | struct align_pos * align = &info.align; | ||
493 | bool needs_update; | ||
494 | #ifdef HAVE_LCD_BITMAP | ||
495 | /* Set images to not to be displayed */ | ||
496 | struct skin_token_list *imglist = gwps->data->images; | ||
497 | while (imglist) | ||
498 | { | ||
499 | struct gui_img *img = (struct gui_img *)imglist->token->value.data; | ||
500 | img->display = -1; | ||
501 | imglist = imglist->next; | ||
502 | } | ||
503 | #endif | ||
504 | |||
505 | while (line) | ||
506 | { | ||
507 | linebuf[0] = '\0'; | ||
508 | info.no_line_break = false; | ||
509 | info.line_scrolls = false; | ||
510 | info.force_redraw = false; | ||
511 | |||
512 | info.cur_align_start = info.buf; | ||
513 | align->left = info.buf; | ||
514 | align->center = NULL; | ||
515 | align->right = NULL; | ||
516 | |||
517 | |||
518 | if (line->type == LINE_ALTERNATOR) | ||
519 | func = skin_render_alternator; | ||
520 | else if (line->type == LINE) | ||
521 | func = skin_render_line; | ||
522 | |||
523 | needs_update = func(line, &info); | ||
524 | |||
525 | /* only update if the line needs to be, and there is something to write */ | ||
526 | if (refresh_type && needs_update) | ||
527 | { | ||
528 | if (info.line_scrolls) | ||
529 | { | ||
530 | /* if the line is a scrolling one we don't want to update | ||
531 | too often, so that it has the time to scroll */ | ||
532 | if ((refresh_type & SKIN_REFRESH_SCROLL) || info.force_redraw) | ||
533 | write_line(display, align, info.line_number, true); | ||
534 | } | ||
535 | else | ||
536 | write_line(display, align, info.line_number, false); | ||
537 | } | ||
538 | if (!info.no_line_break) | ||
539 | info.line_number++; | ||
540 | line = line->next; | ||
541 | } | ||
542 | #ifdef HAVE_LCD_BITMAP | ||
543 | wps_display_images(gwps, &skin_viewport->vp); | ||
544 | #endif | ||
545 | } | ||
546 | |||
547 | void skin_render(struct gui_wps *gwps, unsigned refresh_mode) | ||
548 | { | ||
549 | struct wps_data *data = gwps->data; | ||
550 | struct screen *display = gwps->display; | ||
551 | |||
552 | struct skin_element* viewport = data->tree; | ||
553 | struct skin_viewport* skin_viewport; | ||
554 | |||
555 | int old_refresh_mode = refresh_mode; | ||
556 | |||
557 | #ifdef HAVE_LCD_CHARCELLS | ||
558 | int i; | ||
559 | for (i = 0; i < 8; i++) | ||
560 | { | ||
561 | if (data->wps_progress_pat[i] == 0) | ||
562 | data->wps_progress_pat[i] = display->get_locked_pattern(); | ||
563 | } | ||
564 | #endif | ||
565 | viewport = data->tree; | ||
566 | skin_viewport = (struct skin_viewport *)viewport->data; | ||
567 | if (skin_viewport->label == VP_DEFAULT_LABEL && viewport->next) | ||
568 | refresh_mode = 0; | ||
569 | |||
570 | for (viewport = data->tree; | ||
571 | viewport; | ||
572 | viewport = viewport->next) | ||
573 | { | ||
574 | /* SETUP */ | ||
575 | skin_viewport = (struct skin_viewport*)viewport->data; | ||
576 | unsigned vp_refresh_mode = refresh_mode; | ||
577 | #if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1) | ||
578 | skin_viewport->vp.fg_pattern = skin_viewport->start_fgcolour; | ||
579 | skin_viewport->vp.bg_pattern = skin_viewport->start_bgcolour; | ||
580 | #endif | ||
581 | |||
582 | /* dont redraw the viewport if its disabled */ | ||
583 | if (skin_viewport->hidden_flags&VP_NEVER_VISIBLE) | ||
584 | { /* don't draw anything into this one */ | ||
585 | vp_refresh_mode = 0; | ||
586 | } | ||
587 | else if ((skin_viewport->hidden_flags&VP_DRAW_HIDDEN)) | ||
588 | { | ||
589 | skin_viewport->hidden_flags |= VP_DRAW_WASHIDDEN; | ||
590 | continue; | ||
591 | } | ||
592 | else if (((skin_viewport->hidden_flags& | ||
593 | (VP_DRAW_WASHIDDEN|VP_DRAW_HIDEABLE)) | ||
594 | == (VP_DRAW_WASHIDDEN|VP_DRAW_HIDEABLE))) | ||
595 | { | ||
596 | vp_refresh_mode = SKIN_REFRESH_ALL; | ||
597 | skin_viewport->hidden_flags = VP_DRAW_HIDEABLE; | ||
598 | } | ||
599 | |||
600 | display->set_viewport(&skin_viewport->vp); | ||
601 | if ((vp_refresh_mode&SKIN_REFRESH_ALL) == SKIN_REFRESH_ALL) | ||
602 | { | ||
603 | display->clear_viewport(); | ||
604 | } | ||
605 | /* render */ | ||
606 | skin_render_viewport(viewport->children[0], gwps, | ||
607 | skin_viewport, vp_refresh_mode); | ||
608 | refresh_mode = old_refresh_mode; | ||
609 | } | ||
610 | |||
611 | /* Restore the default viewport */ | ||
612 | display->set_viewport(NULL); | ||
613 | display->update(); | ||
614 | } | ||
diff --git a/apps/gui/skin_engine/skin_tokens.c b/apps/gui/skin_engine/skin_tokens.c index b0a55ca13c..c5e1ebc831 100644 --- a/apps/gui/skin_engine/skin_tokens.c +++ b/apps/gui/skin_engine/skin_tokens.c | |||
@@ -167,19 +167,19 @@ const char *get_id3_token(struct wps_token *token, struct mp3entry *id3, | |||
167 | unsigned long elapsed = id3->elapsed + state->ff_rewind_count; | 167 | unsigned long elapsed = id3->elapsed + state->ff_rewind_count; |
168 | switch (token->type) | 168 | switch (token->type) |
169 | { | 169 | { |
170 | case WPS_TOKEN_METADATA_ARTIST: | 170 | case SKIN_TOKEN_METADATA_ARTIST: |
171 | return id3->artist; | 171 | return id3->artist; |
172 | case WPS_TOKEN_METADATA_COMPOSER: | 172 | case SKIN_TOKEN_METADATA_COMPOSER: |
173 | return id3->composer; | 173 | return id3->composer; |
174 | case WPS_TOKEN_METADATA_ALBUM: | 174 | case SKIN_TOKEN_METADATA_ALBUM: |
175 | return id3->album; | 175 | return id3->album; |
176 | case WPS_TOKEN_METADATA_ALBUM_ARTIST: | 176 | case SKIN_TOKEN_METADATA_ALBUM_ARTIST: |
177 | return id3->albumartist; | 177 | return id3->albumartist; |
178 | case WPS_TOKEN_METADATA_GROUPING: | 178 | case SKIN_TOKEN_METADATA_GROUPING: |
179 | return id3->grouping; | 179 | return id3->grouping; |
180 | case WPS_TOKEN_METADATA_GENRE: | 180 | case SKIN_TOKEN_METADATA_GENRE: |
181 | return id3->genre_string; | 181 | return id3->genre_string; |
182 | case WPS_TOKEN_METADATA_DISC_NUMBER: | 182 | case SKIN_TOKEN_METADATA_DISC_NUMBER: |
183 | if (id3->disc_string) | 183 | if (id3->disc_string) |
184 | return id3->disc_string; | 184 | return id3->disc_string; |
185 | if (id3->discnum) { | 185 | if (id3->discnum) { |
@@ -187,7 +187,7 @@ const char *get_id3_token(struct wps_token *token, struct mp3entry *id3, | |||
187 | return buf; | 187 | return buf; |
188 | } | 188 | } |
189 | return NULL; | 189 | return NULL; |
190 | case WPS_TOKEN_METADATA_TRACK_NUMBER: | 190 | case SKIN_TOKEN_METADATA_TRACK_NUMBER: |
191 | if (id3->track_string) | 191 | if (id3->track_string) |
192 | return id3->track_string; | 192 | return id3->track_string; |
193 | if (id3->tracknum) { | 193 | if (id3->tracknum) { |
@@ -195,9 +195,9 @@ const char *get_id3_token(struct wps_token *token, struct mp3entry *id3, | |||
195 | return buf; | 195 | return buf; |
196 | } | 196 | } |
197 | return NULL; | 197 | return NULL; |
198 | case WPS_TOKEN_METADATA_TRACK_TITLE: | 198 | case SKIN_TOKEN_METADATA_TRACK_TITLE: |
199 | return id3->title; | 199 | return id3->title; |
200 | case WPS_TOKEN_METADATA_VERSION: | 200 | case SKIN_TOKEN_METADATA_VERSION: |
201 | switch (id3->id3version) | 201 | switch (id3->id3version) |
202 | { | 202 | { |
203 | case ID3_VER_1_0: | 203 | case ID3_VER_1_0: |
@@ -214,7 +214,7 @@ const char *get_id3_token(struct wps_token *token, struct mp3entry *id3, | |||
214 | break; | 214 | break; |
215 | } | 215 | } |
216 | return NULL; | 216 | return NULL; |
217 | case WPS_TOKEN_METADATA_YEAR: | 217 | case SKIN_TOKEN_METADATA_YEAR: |
218 | if( id3->year_string ) | 218 | if( id3->year_string ) |
219 | return id3->year_string; | 219 | return id3->year_string; |
220 | if (id3->year) { | 220 | if (id3->year) { |
@@ -222,29 +222,29 @@ const char *get_id3_token(struct wps_token *token, struct mp3entry *id3, | |||
222 | return buf; | 222 | return buf; |
223 | } | 223 | } |
224 | return NULL; | 224 | return NULL; |
225 | case WPS_TOKEN_METADATA_COMMENT: | 225 | case SKIN_TOKEN_METADATA_COMMENT: |
226 | return id3->comment; | 226 | return id3->comment; |
227 | case WPS_TOKEN_FILE_PATH: | 227 | case SKIN_TOKEN_FILE_PATH: |
228 | return id3->path; | 228 | return id3->path; |
229 | case WPS_TOKEN_FILE_BITRATE: | 229 | case SKIN_TOKEN_FILE_BITRATE: |
230 | if(id3->bitrate) | 230 | if(id3->bitrate) |
231 | snprintf(buf, buf_size, "%d", id3->bitrate); | 231 | snprintf(buf, buf_size, "%d", id3->bitrate); |
232 | else | 232 | else |
233 | return "?"; | 233 | return "?"; |
234 | return buf; | 234 | return buf; |
235 | case WPS_TOKEN_TRACK_TIME_ELAPSED: | 235 | case SKIN_TOKEN_TRACK_TIME_ELAPSED: |
236 | format_time(buf, buf_size, elapsed); | 236 | format_time(buf, buf_size, elapsed); |
237 | return buf; | 237 | return buf; |
238 | 238 | ||
239 | case WPS_TOKEN_TRACK_TIME_REMAINING: | 239 | case SKIN_TOKEN_TRACK_TIME_REMAINING: |
240 | format_time(buf, buf_size, length - elapsed); | 240 | format_time(buf, buf_size, length - elapsed); |
241 | return buf; | 241 | return buf; |
242 | 242 | ||
243 | case WPS_TOKEN_TRACK_LENGTH: | 243 | case SKIN_TOKEN_TRACK_LENGTH: |
244 | format_time(buf, buf_size, length); | 244 | format_time(buf, buf_size, length); |
245 | return buf; | 245 | return buf; |
246 | 246 | ||
247 | case WPS_TOKEN_TRACK_ELAPSED_PERCENT: | 247 | case SKIN_TOKEN_TRACK_ELAPSED_PERCENT: |
248 | if (length <= 0) | 248 | if (length <= 0) |
249 | return NULL; | 249 | return NULL; |
250 | 250 | ||
@@ -255,14 +255,14 @@ const char *get_id3_token(struct wps_token *token, struct mp3entry *id3, | |||
255 | snprintf(buf, buf_size, "%lu", 100 * elapsed / length); | 255 | snprintf(buf, buf_size, "%lu", 100 * elapsed / length); |
256 | return buf; | 256 | return buf; |
257 | 257 | ||
258 | case WPS_TOKEN_TRACK_STARTING: | 258 | case SKIN_TOKEN_TRACK_STARTING: |
259 | { | 259 | { |
260 | unsigned long time = token->value.i * 1000; | 260 | unsigned long time = token->value.i * 1000; |
261 | if (elapsed < time) | 261 | if (elapsed < time) |
262 | return "starting"; | 262 | return "starting"; |
263 | } | 263 | } |
264 | return NULL; | 264 | return NULL; |
265 | case WPS_TOKEN_TRACK_ENDING: | 265 | case SKIN_TOKEN_TRACK_ENDING: |
266 | { | 266 | { |
267 | unsigned long time = token->value.i * 1000; | 267 | unsigned long time = token->value.i * 1000; |
268 | if (length - elapsed < time) | 268 | if (length - elapsed < time) |
@@ -270,7 +270,7 @@ const char *get_id3_token(struct wps_token *token, struct mp3entry *id3, | |||
270 | } | 270 | } |
271 | return NULL; | 271 | return NULL; |
272 | 272 | ||
273 | case WPS_TOKEN_FILE_CODEC: | 273 | case SKIN_TOKEN_FILE_CODEC: |
274 | if (intval) | 274 | if (intval) |
275 | { | 275 | { |
276 | if(id3->codectype == AFMT_UNKNOWN) | 276 | if(id3->codectype == AFMT_UNKNOWN) |
@@ -280,10 +280,10 @@ const char *get_id3_token(struct wps_token *token, struct mp3entry *id3, | |||
280 | } | 280 | } |
281 | return get_codectype(id3); | 281 | return get_codectype(id3); |
282 | 282 | ||
283 | case WPS_TOKEN_FILE_FREQUENCY: | 283 | case SKIN_TOKEN_FILE_FREQUENCY: |
284 | snprintf(buf, buf_size, "%ld", id3->frequency); | 284 | snprintf(buf, buf_size, "%ld", id3->frequency); |
285 | return buf; | 285 | return buf; |
286 | case WPS_TOKEN_FILE_FREQUENCY_KHZ: | 286 | case SKIN_TOKEN_FILE_FREQUENCY_KHZ: |
287 | /* ignore remainders < 100, so 22050 Hz becomes just 22k */ | 287 | /* ignore remainders < 100, so 22050 Hz becomes just 22k */ |
288 | if ((id3->frequency % 1000) < 100) | 288 | if ((id3->frequency % 1000) < 100) |
289 | snprintf(buf, buf_size, "%ld", id3->frequency / 1000); | 289 | snprintf(buf, buf_size, "%ld", id3->frequency / 1000); |
@@ -292,7 +292,7 @@ const char *get_id3_token(struct wps_token *token, struct mp3entry *id3, | |||
292 | id3->frequency / 1000, | 292 | id3->frequency / 1000, |
293 | (id3->frequency % 1000) / 100); | 293 | (id3->frequency % 1000) / 100); |
294 | return buf; | 294 | return buf; |
295 | case WPS_TOKEN_FILE_NAME: | 295 | case SKIN_TOKEN_FILE_NAME: |
296 | if (get_dir(buf, buf_size, id3->path, 0)) { | 296 | if (get_dir(buf, buf_size, id3->path, 0)) { |
297 | /* Remove extension */ | 297 | /* Remove extension */ |
298 | char* sep = strrchr(buf, '.'); | 298 | char* sep = strrchr(buf, '.'); |
@@ -302,28 +302,28 @@ const char *get_id3_token(struct wps_token *token, struct mp3entry *id3, | |||
302 | return buf; | 302 | return buf; |
303 | } | 303 | } |
304 | return NULL; | 304 | return NULL; |
305 | case WPS_TOKEN_FILE_NAME_WITH_EXTENSION: | 305 | case SKIN_TOKEN_FILE_NAME_WITH_EXTENSION: |
306 | return get_dir(buf, buf_size, id3->path, 0); | 306 | return get_dir(buf, buf_size, id3->path, 0); |
307 | case WPS_TOKEN_FILE_SIZE: | 307 | case SKIN_TOKEN_FILE_SIZE: |
308 | snprintf(buf, buf_size, "%ld", id3->filesize / 1024); | 308 | snprintf(buf, buf_size, "%ld", id3->filesize / 1024); |
309 | return buf; | 309 | return buf; |
310 | case WPS_TOKEN_FILE_VBR: | 310 | case SKIN_TOKEN_FILE_VBR: |
311 | return (id3->vbr) ? "(avg)" : NULL; | 311 | return (id3->vbr) ? "(avg)" : NULL; |
312 | case WPS_TOKEN_FILE_DIRECTORY: | 312 | case SKIN_TOKEN_FILE_DIRECTORY: |
313 | return get_dir(buf, buf_size, id3->path, token->value.i); | 313 | return get_dir(buf, buf_size, id3->path, token->value.i); |
314 | 314 | ||
315 | #ifdef HAVE_TAGCACHE | 315 | #ifdef HAVE_TAGCACHE |
316 | case WPS_TOKEN_DATABASE_PLAYCOUNT: | 316 | case SKIN_TOKEN_DATABASE_PLAYCOUNT: |
317 | if (intval) | 317 | if (intval) |
318 | *intval = id3->playcount + 1; | 318 | *intval = id3->playcount + 1; |
319 | snprintf(buf, buf_size, "%ld", id3->playcount); | 319 | snprintf(buf, buf_size, "%ld", id3->playcount); |
320 | return buf; | 320 | return buf; |
321 | case WPS_TOKEN_DATABASE_RATING: | 321 | case SKIN_TOKEN_DATABASE_RATING: |
322 | if (intval) | 322 | if (intval) |
323 | *intval = id3->rating + 1; | 323 | *intval = id3->rating + 1; |
324 | snprintf(buf, buf_size, "%d", id3->rating); | 324 | snprintf(buf, buf_size, "%d", id3->rating); |
325 | return buf; | 325 | return buf; |
326 | case WPS_TOKEN_DATABASE_AUTOSCORE: | 326 | case SKIN_TOKEN_DATABASE_AUTOSCORE: |
327 | if (intval) | 327 | if (intval) |
328 | *intval = id3->score + 1; | 328 | *intval = id3->score + 1; |
329 | snprintf(buf, buf_size, "%d", id3->score); | 329 | snprintf(buf, buf_size, "%d", id3->score); |
@@ -340,13 +340,13 @@ const char *get_id3_token(struct wps_token *token, struct mp3entry *id3, | |||
340 | { | 340 | { |
341 | /* Most tokens expect NULL on error so leave that for the default case, | 341 | /* Most tokens expect NULL on error so leave that for the default case, |
342 | * The ones that expect "0" need to be handled */ | 342 | * The ones that expect "0" need to be handled */ |
343 | case WPS_TOKEN_FILE_FREQUENCY: | 343 | case SKIN_TOKEN_FILE_FREQUENCY: |
344 | case WPS_TOKEN_FILE_FREQUENCY_KHZ: | 344 | case SKIN_TOKEN_FILE_FREQUENCY_KHZ: |
345 | case WPS_TOKEN_FILE_SIZE: | 345 | case SKIN_TOKEN_FILE_SIZE: |
346 | #ifdef HAVE_TAGCACHE | 346 | #ifdef HAVE_TAGCACHE |
347 | case WPS_TOKEN_DATABASE_PLAYCOUNT: | 347 | case SKIN_TOKEN_DATABASE_PLAYCOUNT: |
348 | case WPS_TOKEN_DATABASE_RATING: | 348 | case SKIN_TOKEN_DATABASE_RATING: |
349 | case WPS_TOKEN_DATABASE_AUTOSCORE: | 349 | case SKIN_TOKEN_DATABASE_AUTOSCORE: |
350 | #endif | 350 | #endif |
351 | if (intval) | 351 | if (intval) |
352 | *intval = 0; | 352 | *intval = 0; |
@@ -397,30 +397,30 @@ const char *get_radio_token(struct wps_token *token, int preset_offset, | |||
397 | switch (token->type) | 397 | switch (token->type) |
398 | { | 398 | { |
399 | /* Radio/tuner tokens */ | 399 | /* Radio/tuner tokens */ |
400 | case WPS_TOKEN_TUNER_TUNED: | 400 | case SKIN_TOKEN_TUNER_TUNED: |
401 | if (tuner_get(RADIO_TUNED)) | 401 | if (tuner_get(RADIO_TUNED)) |
402 | return "t"; | 402 | return "t"; |
403 | return NULL; | 403 | return NULL; |
404 | case WPS_TOKEN_TUNER_SCANMODE: | 404 | case SKIN_TOKEN_TUNER_SCANMODE: |
405 | if (radio_scan_mode()) | 405 | if (radio_scan_mode()) |
406 | return "s"; | 406 | return "s"; |
407 | return NULL; | 407 | return NULL; |
408 | case WPS_TOKEN_TUNER_STEREO: | 408 | case SKIN_TOKEN_TUNER_STEREO: |
409 | if (radio_is_stereo()) | 409 | if (radio_is_stereo()) |
410 | return "s"; | 410 | return "s"; |
411 | return NULL; | 411 | return NULL; |
412 | case WPS_TOKEN_TUNER_MINFREQ: /* changes based on "region" */ | 412 | case SKIN_TOKEN_TUNER_MINFREQ: /* changes based on "region" */ |
413 | return format_freq_MHz(region_data->freq_min, | 413 | return format_freq_MHz(region_data->freq_min, |
414 | region_data->freq_step, buf, buf_size); | 414 | region_data->freq_step, buf, buf_size); |
415 | case WPS_TOKEN_TUNER_MAXFREQ: /* changes based on "region" */ | 415 | case SKIN_TOKEN_TUNER_MAXFREQ: /* changes based on "region" */ |
416 | return format_freq_MHz(region_data->freq_max, | 416 | return format_freq_MHz(region_data->freq_max, |
417 | region_data->freq_step, buf, buf_size); | 417 | region_data->freq_step, buf, buf_size); |
418 | case WPS_TOKEN_TUNER_CURFREQ: | 418 | case SKIN_TOKEN_TUNER_CURFREQ: |
419 | return format_freq_MHz(radio_current_frequency(), | 419 | return format_freq_MHz(radio_current_frequency(), |
420 | region_data->freq_step, buf, buf_size); | 420 | region_data->freq_step, buf, buf_size); |
421 | case WPS_TOKEN_PRESET_NAME: | 421 | case SKIN_TOKEN_PRESET_NAME: |
422 | case WPS_TOKEN_PRESET_FREQ: | 422 | case SKIN_TOKEN_PRESET_FREQ: |
423 | case WPS_TOKEN_PRESET_ID: | 423 | case SKIN_TOKEN_PRESET_ID: |
424 | { | 424 | { |
425 | int preset_count = radio_preset_count(); | 425 | int preset_count = radio_preset_count(); |
426 | int cur_preset = radio_current_preset(); | 426 | int cur_preset = radio_current_preset(); |
@@ -431,30 +431,32 @@ const char *get_radio_token(struct wps_token *token, int preset_offset, | |||
431 | preset %= preset_count; | 431 | preset %= preset_count; |
432 | if (preset < 0) | 432 | if (preset < 0) |
433 | preset += preset_count; | 433 | preset += preset_count; |
434 | if (token->type == WPS_TOKEN_PRESET_NAME) | 434 | if (token->type == SKIN_TOKEN_PRESET_NAME) |
435 | snprintf(buf, buf_size, "%s", radio_get_preset(preset)->name); | 435 | snprintf(buf, buf_size, "%s", radio_get_preset(preset)->name); |
436 | else if (token->type == WPS_TOKEN_PRESET_FREQ) | 436 | else if (token->type == SKIN_TOKEN_PRESET_FREQ) |
437 | format_freq_MHz(radio_get_preset(preset)->frequency, | 437 | format_freq_MHz(radio_get_preset(preset)->frequency, |
438 | region_data->freq_step, buf, buf_size); | 438 | region_data->freq_step, buf, buf_size); |
439 | else | 439 | else |
440 | snprintf(buf, buf_size, "%d", preset + 1); | 440 | snprintf(buf, buf_size, "%d", preset + 1); |
441 | return buf; | 441 | return buf; |
442 | } | 442 | } |
443 | case WPS_TOKEN_PRESET_COUNT: | 443 | case SKIN_TOKEN_PRESET_COUNT: |
444 | snprintf(buf, buf_size, "%d", radio_preset_count()); | 444 | snprintf(buf, buf_size, "%d", radio_preset_count()); |
445 | if (intval) | 445 | if (intval) |
446 | *intval = radio_preset_count(); | 446 | *intval = radio_preset_count(); |
447 | return buf; | 447 | return buf; |
448 | case WPS_TOKEN_HAVE_RDS: | 448 | case SKIN_TOKEN_HAVE_RDS: |
449 | #ifdef HAVE_RDS_CAP | 449 | #ifdef HAVE_RDS_CAP |
450 | return "rds"; | 450 | return "rds"; |
451 | case WPS_TOKEN_RDS_NAME: | 451 | case SKIN_TOKEN_RDS_NAME: |
452 | return tuner_get_rds_info(RADIO_RDS_NAME); | 452 | return tuner_get_rds_info(RADIO_RDS_NAME); |
453 | case WPS_TOKEN_RDS_TEXT: | 453 | case SKIN_TOKEN_RDS_TEXT: |
454 | return tuner_get_rds_info(RADIO_RDS_TEXT); | 454 | return tuner_get_rds_info(RADIO_RDS_TEXT); |
455 | #else | 455 | #else |
456 | return NULL; /* end of the WPS_TOKEN_HAVE_RDS case */ | 456 | return NULL; /* end of the SKIN_TOKEN_HAVE_RDS case */ |
457 | #endif /* HAVE_RDS_CAP */ | 457 | #endif /* HAVE_RDS_CAP */ |
458 | default: | ||
459 | return NULL; | ||
458 | } | 460 | } |
459 | return NULL; | 461 | return NULL; |
460 | } | 462 | } |
@@ -497,8 +499,8 @@ const char *get_token_value(struct gui_wps *gwps, | |||
497 | 499 | ||
498 | /* if the token is an RTC one, update the time | 500 | /* if the token is an RTC one, update the time |
499 | and do the necessary checks */ | 501 | and do the necessary checks */ |
500 | if (token->type >= WPS_TOKENS_RTC_BEGIN | 502 | if (token->type >= SKIN_TOKENS_RTC_BEGIN |
501 | && token->type <= WPS_TOKENS_RTC_END) | 503 | && token->type <= SKIN_TOKENS_RTC_END) |
502 | { | 504 | { |
503 | tm = get_time(); | 505 | tm = get_time(); |
504 | 506 | ||
@@ -531,44 +533,44 @@ const char *get_token_value(struct gui_wps *gwps, | |||
531 | 533 | ||
532 | switch (token->type) | 534 | switch (token->type) |
533 | { | 535 | { |
534 | case WPS_TOKEN_CHARACTER: | 536 | case SKIN_TOKEN_CHARACTER: |
535 | if (token->value.c == '\n') | 537 | if (token->value.c == '\n') |
536 | return NULL; | 538 | return NULL; |
537 | return &(token->value.c); | 539 | return &(token->value.c); |
538 | 540 | ||
539 | case WPS_TOKEN_STRING: | 541 | case SKIN_TOKEN_STRING: |
540 | return (char*)token->value.data; | 542 | return (char*)token->value.data; |
541 | 543 | ||
542 | case WPS_TOKEN_TRANSLATEDSTRING: | 544 | case SKIN_TOKEN_TRANSLATEDSTRING: |
543 | return (char*)P2STR(ID2P(token->value.i)); | 545 | return (char*)P2STR(ID2P(token->value.i)); |
544 | 546 | ||
545 | case WPS_TOKEN_PLAYLIST_ENTRIES: | 547 | case SKIN_TOKEN_PLAYLIST_ENTRIES: |
546 | snprintf(buf, buf_size, "%d", playlist_amount()); | 548 | snprintf(buf, buf_size, "%d", playlist_amount()); |
547 | return buf; | 549 | return buf; |
548 | 550 | ||
549 | case WPS_TOKEN_LIST_TITLE_TEXT: | 551 | case SKIN_TOKEN_LIST_TITLE_TEXT: |
550 | return (char*)token->value.data; | 552 | return (char*)token->value.data; |
551 | case WPS_TOKEN_LIST_TITLE_ICON: | 553 | case SKIN_TOKEN_LIST_TITLE_ICON: |
552 | if (intval) | 554 | if (intval) |
553 | *intval = token->value.i; | 555 | *intval = token->value.i; |
554 | snprintf(buf, buf_size, "%d", token->value.i); | 556 | snprintf(buf, buf_size, "%d", token->value.i); |
555 | return buf; | 557 | return buf; |
556 | 558 | ||
557 | case WPS_TOKEN_PLAYLIST_NAME: | 559 | case SKIN_TOKEN_PLAYLIST_NAME: |
558 | return playlist_name(NULL, buf, buf_size); | 560 | return playlist_name(NULL, buf, buf_size); |
559 | 561 | ||
560 | case WPS_TOKEN_PLAYLIST_POSITION: | 562 | case SKIN_TOKEN_PLAYLIST_POSITION: |
561 | snprintf(buf, buf_size, "%d", playlist_get_display_index()); | 563 | snprintf(buf, buf_size, "%d", playlist_get_display_index()); |
562 | return buf; | 564 | return buf; |
563 | 565 | ||
564 | case WPS_TOKEN_PLAYLIST_SHUFFLE: | 566 | case SKIN_TOKEN_PLAYLIST_SHUFFLE: |
565 | if ( global_settings.playlist_shuffle ) | 567 | if ( global_settings.playlist_shuffle ) |
566 | return "s"; | 568 | return "s"; |
567 | else | 569 | else |
568 | return NULL; | 570 | return NULL; |
569 | break; | 571 | break; |
570 | 572 | ||
571 | case WPS_TOKEN_VOLUME: | 573 | case SKIN_TOKEN_VOLUME: |
572 | snprintf(buf, buf_size, "%d", global_settings.volume); | 574 | snprintf(buf, buf_size, "%d", global_settings.volume); |
573 | if (intval) | 575 | if (intval) |
574 | { | 576 | { |
@@ -593,7 +595,7 @@ const char *get_token_value(struct gui_wps *gwps, | |||
593 | } | 595 | } |
594 | return buf; | 596 | return buf; |
595 | #ifdef HAVE_ALBUMART | 597 | #ifdef HAVE_ALBUMART |
596 | case WPS_TOKEN_ALBUMART_FOUND: | 598 | case SKIN_TOKEN_ALBUMART_FOUND: |
597 | if (data->albumart) | 599 | if (data->albumart) |
598 | { | 600 | { |
599 | int handle = -1; | 601 | int handle = -1; |
@@ -609,16 +611,9 @@ const char *get_token_value(struct gui_wps *gwps, | |||
609 | return "C"; | 611 | return "C"; |
610 | } | 612 | } |
611 | return NULL; | 613 | return NULL; |
612 | |||
613 | case WPS_TOKEN_ALBUMART_DISPLAY: | ||
614 | if (!data->albumart) | ||
615 | return NULL; | ||
616 | if (!data->albumart->draw) | ||
617 | data->albumart->draw = true; | ||
618 | return NULL; | ||
619 | #endif | 614 | #endif |
620 | 615 | ||
621 | case WPS_TOKEN_BATTERY_PERCENT: | 616 | case SKIN_TOKEN_BATTERY_PERCENT: |
622 | { | 617 | { |
623 | int l = battery_level(); | 618 | int l = battery_level(); |
624 | 619 | ||
@@ -641,14 +636,14 @@ const char *get_token_value(struct gui_wps *gwps, | |||
641 | } | 636 | } |
642 | } | 637 | } |
643 | 638 | ||
644 | case WPS_TOKEN_BATTERY_VOLTS: | 639 | case SKIN_TOKEN_BATTERY_VOLTS: |
645 | { | 640 | { |
646 | unsigned int v = battery_voltage(); | 641 | unsigned int v = battery_voltage(); |
647 | snprintf(buf, buf_size, "%d.%02d", v / 1000, (v % 1000) / 10); | 642 | snprintf(buf, buf_size, "%d.%02d", v / 1000, (v % 1000) / 10); |
648 | return buf; | 643 | return buf; |
649 | } | 644 | } |
650 | 645 | ||
651 | case WPS_TOKEN_BATTERY_TIME: | 646 | case SKIN_TOKEN_BATTERY_TIME: |
652 | { | 647 | { |
653 | int t = battery_time(); | 648 | int t = battery_time(); |
654 | if (t >= 0) | 649 | if (t >= 0) |
@@ -659,7 +654,7 @@ const char *get_token_value(struct gui_wps *gwps, | |||
659 | } | 654 | } |
660 | 655 | ||
661 | #if CONFIG_CHARGING | 656 | #if CONFIG_CHARGING |
662 | case WPS_TOKEN_BATTERY_CHARGER_CONNECTED: | 657 | case SKIN_TOKEN_BATTERY_CHARGER_CONNECTED: |
663 | { | 658 | { |
664 | if(charger_input_state==CHARGER) | 659 | if(charger_input_state==CHARGER) |
665 | return "p"; | 660 | return "p"; |
@@ -668,7 +663,7 @@ const char *get_token_value(struct gui_wps *gwps, | |||
668 | } | 663 | } |
669 | #endif | 664 | #endif |
670 | #if CONFIG_CHARGING >= CHARGING_MONITOR | 665 | #if CONFIG_CHARGING >= CHARGING_MONITOR |
671 | case WPS_TOKEN_BATTERY_CHARGING: | 666 | case SKIN_TOKEN_BATTERY_CHARGING: |
672 | { | 667 | { |
673 | if (charge_state == CHARGING || charge_state == TOPOFF) { | 668 | if (charge_state == CHARGING || charge_state == TOPOFF) { |
674 | return "c"; | 669 | return "c"; |
@@ -678,12 +673,12 @@ const char *get_token_value(struct gui_wps *gwps, | |||
678 | } | 673 | } |
679 | #endif | 674 | #endif |
680 | #ifdef HAVE_USB_POWER | 675 | #ifdef HAVE_USB_POWER |
681 | case WPS_TOKEN_USB_POWERED: | 676 | case SKIN_TOKEN_USB_POWERED: |
682 | if (usb_powered()) | 677 | if (usb_powered()) |
683 | return "u"; | 678 | return "u"; |
684 | return NULL; | 679 | return NULL; |
685 | #endif | 680 | #endif |
686 | case WPS_TOKEN_BATTERY_SLEEPTIME: | 681 | case SKIN_TOKEN_BATTERY_SLEEPTIME: |
687 | { | 682 | { |
688 | if (get_sleep_timer() == 0) | 683 | if (get_sleep_timer() == 0) |
689 | return NULL; | 684 | return NULL; |
@@ -694,7 +689,7 @@ const char *get_token_value(struct gui_wps *gwps, | |||
694 | } | 689 | } |
695 | } | 690 | } |
696 | 691 | ||
697 | case WPS_TOKEN_PLAYBACK_STATUS: | 692 | case SKIN_TOKEN_PLAYBACK_STATUS: |
698 | { | 693 | { |
699 | int status = current_playmode(); | 694 | int status = current_playmode(); |
700 | /* music */ | 695 | /* music */ |
@@ -734,13 +729,13 @@ const char *get_token_value(struct gui_wps *gwps, | |||
734 | return buf; | 729 | return buf; |
735 | } | 730 | } |
736 | 731 | ||
737 | case WPS_TOKEN_REPEAT_MODE: | 732 | case SKIN_TOKEN_REPEAT_MODE: |
738 | if (intval) | 733 | if (intval) |
739 | *intval = global_settings.repeat_mode + 1; | 734 | *intval = global_settings.repeat_mode + 1; |
740 | snprintf(buf, buf_size, "%d", global_settings.repeat_mode); | 735 | snprintf(buf, buf_size, "%d", global_settings.repeat_mode); |
741 | return buf; | 736 | return buf; |
742 | 737 | ||
743 | case WPS_TOKEN_RTC_PRESENT: | 738 | case SKIN_TOKEN_RTC_PRESENT: |
744 | #if CONFIG_RTC | 739 | #if CONFIG_RTC |
745 | return "c"; | 740 | return "c"; |
746 | #else | 741 | #else |
@@ -748,41 +743,41 @@ const char *get_token_value(struct gui_wps *gwps, | |||
748 | #endif | 743 | #endif |
749 | 744 | ||
750 | #if CONFIG_RTC | 745 | #if CONFIG_RTC |
751 | case WPS_TOKEN_RTC_12HOUR_CFG: | 746 | case SKIN_TOKEN_RTC_12HOUR_CFG: |
752 | if (intval) | 747 | if (intval) |
753 | *intval = global_settings.timeformat + 1; | 748 | *intval = global_settings.timeformat + 1; |
754 | snprintf(buf, buf_size, "%d", global_settings.timeformat); | 749 | snprintf(buf, buf_size, "%d", global_settings.timeformat); |
755 | return buf; | 750 | return buf; |
756 | 751 | ||
757 | case WPS_TOKEN_RTC_DAY_OF_MONTH: | 752 | case SKIN_TOKEN_RTC_DAY_OF_MONTH: |
758 | /* d: day of month (01..31) */ | 753 | /* d: day of month (01..31) */ |
759 | snprintf(buf, buf_size, "%02d", tm->tm_mday); | 754 | snprintf(buf, buf_size, "%02d", tm->tm_mday); |
760 | if (intval) | 755 | if (intval) |
761 | *intval = tm->tm_mday - 1; | 756 | *intval = tm->tm_mday - 1; |
762 | return buf; | 757 | return buf; |
763 | 758 | ||
764 | case WPS_TOKEN_RTC_DAY_OF_MONTH_BLANK_PADDED: | 759 | case SKIN_TOKEN_RTC_DAY_OF_MONTH_BLANK_PADDED: |
765 | /* e: day of month, blank padded ( 1..31) */ | 760 | /* e: day of month, blank padded ( 1..31) */ |
766 | snprintf(buf, buf_size, "%2d", tm->tm_mday); | 761 | snprintf(buf, buf_size, "%2d", tm->tm_mday); |
767 | if (intval) | 762 | if (intval) |
768 | *intval = tm->tm_mday - 1; | 763 | *intval = tm->tm_mday - 1; |
769 | return buf; | 764 | return buf; |
770 | 765 | ||
771 | case WPS_TOKEN_RTC_HOUR_24_ZERO_PADDED: | 766 | case SKIN_TOKEN_RTC_HOUR_24_ZERO_PADDED: |
772 | /* H: hour (00..23) */ | 767 | /* H: hour (00..23) */ |
773 | snprintf(buf, buf_size, "%02d", tm->tm_hour); | 768 | snprintf(buf, buf_size, "%02d", tm->tm_hour); |
774 | if (intval) | 769 | if (intval) |
775 | *intval = tm->tm_hour; | 770 | *intval = tm->tm_hour; |
776 | return buf; | 771 | return buf; |
777 | 772 | ||
778 | case WPS_TOKEN_RTC_HOUR_24: | 773 | case SKIN_TOKEN_RTC_HOUR_24: |
779 | /* k: hour ( 0..23) */ | 774 | /* k: hour ( 0..23) */ |
780 | snprintf(buf, buf_size, "%2d", tm->tm_hour); | 775 | snprintf(buf, buf_size, "%2d", tm->tm_hour); |
781 | if (intval) | 776 | if (intval) |
782 | *intval = tm->tm_hour; | 777 | *intval = tm->tm_hour; |
783 | return buf; | 778 | return buf; |
784 | 779 | ||
785 | case WPS_TOKEN_RTC_HOUR_12_ZERO_PADDED: | 780 | case SKIN_TOKEN_RTC_HOUR_12_ZERO_PADDED: |
786 | /* I: hour (01..12) */ | 781 | /* I: hour (01..12) */ |
787 | snprintf(buf, buf_size, "%02d", | 782 | snprintf(buf, buf_size, "%02d", |
788 | (tm->tm_hour % 12 == 0) ? 12 : tm->tm_hour % 12); | 783 | (tm->tm_hour % 12 == 0) ? 12 : tm->tm_hour % 12); |
@@ -790,7 +785,7 @@ const char *get_token_value(struct gui_wps *gwps, | |||
790 | *intval = (tm->tm_hour % 12 == 0) ? 12 : tm->tm_hour % 12; | 785 | *intval = (tm->tm_hour % 12 == 0) ? 12 : tm->tm_hour % 12; |
791 | return buf; | 786 | return buf; |
792 | 787 | ||
793 | case WPS_TOKEN_RTC_HOUR_12: | 788 | case SKIN_TOKEN_RTC_HOUR_12: |
794 | /* l: hour ( 1..12) */ | 789 | /* l: hour ( 1..12) */ |
795 | snprintf(buf, buf_size, "%2d", | 790 | snprintf(buf, buf_size, "%2d", |
796 | (tm->tm_hour % 12 == 0) ? 12 : tm->tm_hour % 12); | 791 | (tm->tm_hour % 12 == 0) ? 12 : tm->tm_hour % 12); |
@@ -798,107 +793,107 @@ const char *get_token_value(struct gui_wps *gwps, | |||
798 | *intval = (tm->tm_hour % 12 == 0) ? 12 : tm->tm_hour % 12; | 793 | *intval = (tm->tm_hour % 12 == 0) ? 12 : tm->tm_hour % 12; |
799 | return buf; | 794 | return buf; |
800 | 795 | ||
801 | case WPS_TOKEN_RTC_MONTH: | 796 | case SKIN_TOKEN_RTC_MONTH: |
802 | /* m: month (01..12) */ | 797 | /* m: month (01..12) */ |
803 | if (intval) | 798 | if (intval) |
804 | *intval = tm->tm_mon + 1; | 799 | *intval = tm->tm_mon + 1; |
805 | snprintf(buf, buf_size, "%02d", tm->tm_mon + 1); | 800 | snprintf(buf, buf_size, "%02d", tm->tm_mon + 1); |
806 | return buf; | 801 | return buf; |
807 | 802 | ||
808 | case WPS_TOKEN_RTC_MINUTE: | 803 | case SKIN_TOKEN_RTC_MINUTE: |
809 | /* M: minute (00..59) */ | 804 | /* M: minute (00..59) */ |
810 | snprintf(buf, buf_size, "%02d", tm->tm_min); | 805 | snprintf(buf, buf_size, "%02d", tm->tm_min); |
811 | if (intval) | 806 | if (intval) |
812 | *intval = tm->tm_min; | 807 | *intval = tm->tm_min; |
813 | return buf; | 808 | return buf; |
814 | 809 | ||
815 | case WPS_TOKEN_RTC_SECOND: | 810 | case SKIN_TOKEN_RTC_SECOND: |
816 | /* S: second (00..59) */ | 811 | /* S: second (00..59) */ |
817 | snprintf(buf, buf_size, "%02d", tm->tm_sec); | 812 | snprintf(buf, buf_size, "%02d", tm->tm_sec); |
818 | if (intval) | 813 | if (intval) |
819 | *intval = tm->tm_sec; | 814 | *intval = tm->tm_sec; |
820 | return buf; | 815 | return buf; |
821 | 816 | ||
822 | case WPS_TOKEN_RTC_YEAR_2_DIGITS: | 817 | case SKIN_TOKEN_RTC_YEAR_2_DIGITS: |
823 | /* y: last two digits of year (00..99) */ | 818 | /* y: last two digits of year (00..99) */ |
824 | snprintf(buf, buf_size, "%02d", tm->tm_year % 100); | 819 | snprintf(buf, buf_size, "%02d", tm->tm_year % 100); |
825 | if (intval) | 820 | if (intval) |
826 | *intval = tm->tm_year % 100; | 821 | *intval = tm->tm_year % 100; |
827 | return buf; | 822 | return buf; |
828 | 823 | ||
829 | case WPS_TOKEN_RTC_YEAR_4_DIGITS: | 824 | case SKIN_TOKEN_RTC_YEAR_4_DIGITS: |
830 | /* Y: year (1970...) */ | 825 | /* Y: year (1970...) */ |
831 | snprintf(buf, buf_size, "%04d", tm->tm_year + 1900); | 826 | snprintf(buf, buf_size, "%04d", tm->tm_year + 1900); |
832 | if (intval) | 827 | if (intval) |
833 | *intval = tm->tm_year + 1900; | 828 | *intval = tm->tm_year + 1900; |
834 | return buf; | 829 | return buf; |
835 | 830 | ||
836 | case WPS_TOKEN_RTC_AM_PM_UPPER: | 831 | case SKIN_TOKEN_RTC_AM_PM_UPPER: |
837 | /* p: upper case AM or PM indicator */ | 832 | /* p: upper case AM or PM indicator */ |
838 | if (intval) | 833 | if (intval) |
839 | *intval = tm->tm_hour/12 == 0 ? 0 : 1; | 834 | *intval = tm->tm_hour/12 == 0 ? 0 : 1; |
840 | return tm->tm_hour/12 == 0 ? "AM" : "PM"; | 835 | return tm->tm_hour/12 == 0 ? "AM" : "PM"; |
841 | 836 | ||
842 | case WPS_TOKEN_RTC_AM_PM_LOWER: | 837 | case SKIN_TOKEN_RTC_AM_PM_LOWER: |
843 | /* P: lower case am or pm indicator */ | 838 | /* P: lower case am or pm indicator */ |
844 | if (intval) | 839 | if (intval) |
845 | *intval = tm->tm_hour/12 == 0 ? 0 : 1; | 840 | *intval = tm->tm_hour/12 == 0 ? 0 : 1; |
846 | return tm->tm_hour/12 == 0 ? "am" : "pm"; | 841 | return tm->tm_hour/12 == 0 ? "am" : "pm"; |
847 | 842 | ||
848 | case WPS_TOKEN_RTC_WEEKDAY_NAME: | 843 | case SKIN_TOKEN_RTC_WEEKDAY_NAME: |
849 | /* a: abbreviated weekday name (Sun..Sat) */ | 844 | /* a: abbreviated weekday name (Sun..Sat) */ |
850 | return str(LANG_WEEKDAY_SUNDAY + tm->tm_wday); | 845 | return str(LANG_WEEKDAY_SUNDAY + tm->tm_wday); |
851 | 846 | ||
852 | case WPS_TOKEN_RTC_MONTH_NAME: | 847 | case SKIN_TOKEN_RTC_MONTH_NAME: |
853 | /* b: abbreviated month name (Jan..Dec) */ | 848 | /* b: abbreviated month name (Jan..Dec) */ |
854 | return str(LANG_MONTH_JANUARY + tm->tm_mon); | 849 | return str(LANG_MONTH_JANUARY + tm->tm_mon); |
855 | 850 | ||
856 | case WPS_TOKEN_RTC_DAY_OF_WEEK_START_MON: | 851 | case SKIN_TOKEN_RTC_DAY_OF_WEEK_START_MON: |
857 | /* u: day of week (1..7); 1 is Monday */ | 852 | /* u: day of week (1..7); 1 is Monday */ |
858 | if (intval) | 853 | if (intval) |
859 | *intval = (tm->tm_wday == 0) ? 7 : tm->tm_wday; | 854 | *intval = (tm->tm_wday == 0) ? 7 : tm->tm_wday; |
860 | snprintf(buf, buf_size, "%1d", tm->tm_wday + 1); | 855 | snprintf(buf, buf_size, "%1d", tm->tm_wday + 1); |
861 | return buf; | 856 | return buf; |
862 | 857 | ||
863 | case WPS_TOKEN_RTC_DAY_OF_WEEK_START_SUN: | 858 | case SKIN_TOKEN_RTC_DAY_OF_WEEK_START_SUN: |
864 | /* w: day of week (0..6); 0 is Sunday */ | 859 | /* w: day of week (0..6); 0 is Sunday */ |
865 | if (intval) | 860 | if (intval) |
866 | *intval = tm->tm_wday + 1; | 861 | *intval = tm->tm_wday + 1; |
867 | snprintf(buf, buf_size, "%1d", tm->tm_wday); | 862 | snprintf(buf, buf_size, "%1d", tm->tm_wday); |
868 | return buf; | 863 | return buf; |
869 | #else | 864 | #else |
870 | case WPS_TOKEN_RTC_DAY_OF_MONTH: | 865 | case SKIN_TOKEN_RTC_DAY_OF_MONTH: |
871 | case WPS_TOKEN_RTC_DAY_OF_MONTH_BLANK_PADDED: | 866 | case SKIN_TOKEN_RTC_DAY_OF_MONTH_BLANK_PADDED: |
872 | case WPS_TOKEN_RTC_HOUR_24_ZERO_PADDED: | 867 | case SKIN_TOKEN_RTC_HOUR_24_ZERO_PADDED: |
873 | case WPS_TOKEN_RTC_HOUR_24: | 868 | case SKIN_TOKEN_RTC_HOUR_24: |
874 | case WPS_TOKEN_RTC_HOUR_12_ZERO_PADDED: | 869 | case SKIN_TOKEN_RTC_HOUR_12_ZERO_PADDED: |
875 | case WPS_TOKEN_RTC_HOUR_12: | 870 | case SKIN_TOKEN_RTC_HOUR_12: |
876 | case WPS_TOKEN_RTC_MONTH: | 871 | case SKIN_TOKEN_RTC_MONTH: |
877 | case WPS_TOKEN_RTC_MINUTE: | 872 | case SKIN_TOKEN_RTC_MINUTE: |
878 | case WPS_TOKEN_RTC_SECOND: | 873 | case SKIN_TOKEN_RTC_SECOND: |
879 | case WPS_TOKEN_RTC_AM_PM_UPPER: | 874 | case SKIN_TOKEN_RTC_AM_PM_UPPER: |
880 | case WPS_TOKEN_RTC_AM_PM_LOWER: | 875 | case SKIN_TOKEN_RTC_AM_PM_LOWER: |
881 | case WPS_TOKEN_RTC_YEAR_2_DIGITS: | 876 | case SKIN_TOKEN_RTC_YEAR_2_DIGITS: |
882 | return "--"; | 877 | return "--"; |
883 | case WPS_TOKEN_RTC_YEAR_4_DIGITS: | 878 | case SKIN_TOKEN_RTC_YEAR_4_DIGITS: |
884 | return "----"; | 879 | return "----"; |
885 | case WPS_TOKEN_RTC_WEEKDAY_NAME: | 880 | case SKIN_TOKEN_RTC_WEEKDAY_NAME: |
886 | case WPS_TOKEN_RTC_MONTH_NAME: | 881 | case SKIN_TOKEN_RTC_MONTH_NAME: |
887 | return "---"; | 882 | return "---"; |
888 | case WPS_TOKEN_RTC_DAY_OF_WEEK_START_MON: | 883 | case SKIN_TOKEN_RTC_DAY_OF_WEEK_START_MON: |
889 | case WPS_TOKEN_RTC_DAY_OF_WEEK_START_SUN: | 884 | case SKIN_TOKEN_RTC_DAY_OF_WEEK_START_SUN: |
890 | return "-"; | 885 | return "-"; |
891 | #endif | 886 | #endif |
892 | 887 | ||
893 | #ifdef HAVE_LCD_CHARCELLS | 888 | #ifdef HAVE_LCD_CHARCELLS |
894 | case WPS_TOKEN_PROGRESSBAR: | 889 | case SKIN_TOKEN_PROGRESSBAR: |
895 | { | 890 | { |
896 | char *end = utf8encode(data->wps_progress_pat[0], buf); | 891 | char *end = utf8encode(data->wps_progress_pat[0], buf); |
897 | *end = '\0'; | 892 | *end = '\0'; |
898 | return buf; | 893 | return buf; |
899 | } | 894 | } |
900 | 895 | ||
901 | case WPS_TOKEN_PLAYER_PROGRESSBAR: | 896 | case SKIN_TOKEN_PLAYER_PROGRESSBAR: |
902 | if(is_new_player()) | 897 | if(is_new_player()) |
903 | { | 898 | { |
904 | /* we need 11 characters (full line) for | 899 | /* we need 11 characters (full line) for |
@@ -916,7 +911,7 @@ const char *get_token_value(struct gui_wps *gwps, | |||
916 | 911 | ||
917 | 912 | ||
918 | #if (CONFIG_CODEC == SWCODEC) | 913 | #if (CONFIG_CODEC == SWCODEC) |
919 | case WPS_TOKEN_CROSSFADE: | 914 | case SKIN_TOKEN_CROSSFADE: |
920 | #ifdef HAVE_CROSSFADE | 915 | #ifdef HAVE_CROSSFADE |
921 | if (intval) | 916 | if (intval) |
922 | *intval = global_settings.crossfade + 1; | 917 | *intval = global_settings.crossfade + 1; |
@@ -926,7 +921,7 @@ const char *get_token_value(struct gui_wps *gwps, | |||
926 | #endif | 921 | #endif |
927 | return buf; | 922 | return buf; |
928 | 923 | ||
929 | case WPS_TOKEN_REPLAYGAIN: | 924 | case SKIN_TOKEN_REPLAYGAIN: |
930 | { | 925 | { |
931 | int val; | 926 | int val; |
932 | 927 | ||
@@ -974,7 +969,7 @@ const char *get_token_value(struct gui_wps *gwps, | |||
974 | #endif /* (CONFIG_CODEC == SWCODEC) */ | 969 | #endif /* (CONFIG_CODEC == SWCODEC) */ |
975 | 970 | ||
976 | #if (CONFIG_CODEC != MAS3507D) | 971 | #if (CONFIG_CODEC != MAS3507D) |
977 | case WPS_TOKEN_SOUND_PITCH: | 972 | case SKIN_TOKEN_SOUND_PITCH: |
978 | { | 973 | { |
979 | int32_t pitch = sound_get_pitch(); | 974 | int32_t pitch = sound_get_pitch(); |
980 | snprintf(buf, buf_size, "%ld.%ld", | 975 | snprintf(buf, buf_size, "%ld.%ld", |
@@ -989,7 +984,7 @@ const char *get_token_value(struct gui_wps *gwps, | |||
989 | #endif | 984 | #endif |
990 | 985 | ||
991 | #if CONFIG_CODEC == SWCODEC | 986 | #if CONFIG_CODEC == SWCODEC |
992 | case WPS_TOKEN_SOUND_SPEED: | 987 | case SKIN_TOKEN_SOUND_SPEED: |
993 | { | 988 | { |
994 | int32_t pitch = sound_get_pitch(); | 989 | int32_t pitch = sound_get_pitch(); |
995 | int32_t speed; | 990 | int32_t speed; |
@@ -1007,7 +1002,7 @@ const char *get_token_value(struct gui_wps *gwps, | |||
1007 | } | 1002 | } |
1008 | #endif | 1003 | #endif |
1009 | 1004 | ||
1010 | case WPS_TOKEN_MAIN_HOLD: | 1005 | case SKIN_TOKEN_MAIN_HOLD: |
1011 | #ifdef HAS_BUTTON_HOLD | 1006 | #ifdef HAS_BUTTON_HOLD |
1012 | if (button_hold()) | 1007 | if (button_hold()) |
1013 | #else | 1008 | #else |
@@ -1018,7 +1013,7 @@ const char *get_token_value(struct gui_wps *gwps, | |||
1018 | return NULL; | 1013 | return NULL; |
1019 | 1014 | ||
1020 | #ifdef HAS_REMOTE_BUTTON_HOLD | 1015 | #ifdef HAS_REMOTE_BUTTON_HOLD |
1021 | case WPS_TOKEN_REMOTE_HOLD: | 1016 | case SKIN_TOKEN_REMOTE_HOLD: |
1022 | if (remote_button_hold()) | 1017 | if (remote_button_hold()) |
1023 | return "r"; | 1018 | return "r"; |
1024 | else | 1019 | else |
@@ -1026,20 +1021,20 @@ const char *get_token_value(struct gui_wps *gwps, | |||
1026 | #endif | 1021 | #endif |
1027 | 1022 | ||
1028 | #if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD) | 1023 | #if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD) |
1029 | case WPS_TOKEN_VLED_HDD: | 1024 | case SKIN_TOKEN_VLED_HDD: |
1030 | if(led_read(HZ/2)) | 1025 | if(led_read(HZ/2)) |
1031 | return "h"; | 1026 | return "h"; |
1032 | else | 1027 | else |
1033 | return NULL; | 1028 | return NULL; |
1034 | #endif | 1029 | #endif |
1035 | case WPS_TOKEN_BUTTON_VOLUME: | 1030 | case SKIN_TOKEN_BUTTON_VOLUME: |
1036 | if (global_status.last_volume_change && | 1031 | if (global_status.last_volume_change && |
1037 | TIME_BEFORE(current_tick, global_status.last_volume_change + | 1032 | TIME_BEFORE(current_tick, global_status.last_volume_change + |
1038 | token->value.i * TIMEOUT_UNIT)) | 1033 | token->value.i * TIMEOUT_UNIT)) |
1039 | return "v"; | 1034 | return "v"; |
1040 | return NULL; | 1035 | return NULL; |
1041 | 1036 | ||
1042 | case WPS_TOKEN_LASTTOUCH: | 1037 | case SKIN_TOKEN_LASTTOUCH: |
1043 | { | 1038 | { |
1044 | #ifdef HAVE_TOUCHSCREEN | 1039 | #ifdef HAVE_TOUCHSCREEN |
1045 | unsigned int last_touch = touchscreen_last_touch(); | 1040 | unsigned int last_touch = touchscreen_last_touch(); |
@@ -1051,7 +1046,7 @@ const char *get_token_value(struct gui_wps *gwps, | |||
1051 | } | 1046 | } |
1052 | return NULL; | 1047 | return NULL; |
1053 | 1048 | ||
1054 | case WPS_TOKEN_SETTING: | 1049 | case SKIN_TOKEN_SETTING: |
1055 | { | 1050 | { |
1056 | const struct settings_list *s = settings+token->value.i; | 1051 | const struct settings_list *s = settings+token->value.i; |
1057 | if (intval) | 1052 | if (intval) |
@@ -1120,14 +1115,14 @@ const char *get_token_value(struct gui_wps *gwps, | |||
1120 | cfg_to_string(token->value.i,buf,buf_size); | 1115 | cfg_to_string(token->value.i,buf,buf_size); |
1121 | return buf; | 1116 | return buf; |
1122 | } | 1117 | } |
1123 | case WPS_TOKEN_HAVE_TUNER: | 1118 | case SKIN_TOKEN_HAVE_TUNER: |
1124 | #if CONFIG_TUNER | 1119 | #if CONFIG_TUNER |
1125 | if (radio_hardware_present()) | 1120 | if (radio_hardware_present()) |
1126 | return "r"; | 1121 | return "r"; |
1127 | #endif | 1122 | #endif |
1128 | return NULL; | 1123 | return NULL; |
1129 | /* Recording tokens */ | 1124 | /* Recording tokens */ |
1130 | case WPS_TOKEN_HAVE_RECORDING: | 1125 | case SKIN_TOKEN_HAVE_RECORDING: |
1131 | #ifdef HAVE_RECORDING | 1126 | #ifdef HAVE_RECORDING |
1132 | return "r"; | 1127 | return "r"; |
1133 | #else | 1128 | #else |
@@ -1135,11 +1130,11 @@ const char *get_token_value(struct gui_wps *gwps, | |||
1135 | #endif | 1130 | #endif |
1136 | 1131 | ||
1137 | #ifdef HAVE_RECORDING | 1132 | #ifdef HAVE_RECORDING |
1138 | case WPS_TOKEN_IS_RECORDING: | 1133 | case SKIN_TOKEN_IS_RECORDING: |
1139 | if (audio_status() == AUDIO_STATUS_RECORD) | 1134 | if (audio_status() == AUDIO_STATUS_RECORD) |
1140 | return "r"; | 1135 | return "r"; |
1141 | return NULL; | 1136 | return NULL; |
1142 | case WPS_TOKEN_REC_FREQ: /* order from REC_FREQ_CFG_VAL_LIST */ | 1137 | case SKIN_TOKEN_REC_FREQ: /* order from REC_FREQ_CFG_VAL_LIST */ |
1143 | { | 1138 | { |
1144 | #if CONFIG_CODEC == SWCODEC | 1139 | #if CONFIG_CODEC == SWCODEC |
1145 | unsigned long samprk; | 1140 | unsigned long samprk; |
@@ -1227,7 +1222,7 @@ const char *get_token_value(struct gui_wps *gwps, | |||
1227 | return buf; | 1222 | return buf; |
1228 | } | 1223 | } |
1229 | #if CONFIG_CODEC == SWCODEC | 1224 | #if CONFIG_CODEC == SWCODEC |
1230 | case WPS_TOKEN_REC_ENCODER: | 1225 | case SKIN_TOKEN_REC_ENCODER: |
1231 | { | 1226 | { |
1232 | int rec_format = global_settings.rec_format+1; /* WAV, AIFF, WV, MPEG */ | 1227 | int rec_format = global_settings.rec_format+1; /* WAV, AIFF, WV, MPEG */ |
1233 | if (intval) | 1228 | if (intval) |
@@ -1248,7 +1243,7 @@ const char *get_token_value(struct gui_wps *gwps, | |||
1248 | break; | 1243 | break; |
1249 | } | 1244 | } |
1250 | #endif | 1245 | #endif |
1251 | case WPS_TOKEN_REC_BITRATE: | 1246 | case SKIN_TOKEN_REC_BITRATE: |
1252 | #if CONFIG_CODEC == SWCODEC | 1247 | #if CONFIG_CODEC == SWCODEC |
1253 | if (global_settings.rec_format == REC_FORMAT_MPA_L3) | 1248 | if (global_settings.rec_format == REC_FORMAT_MPA_L3) |
1254 | { | 1249 | { |
@@ -1317,12 +1312,12 @@ const char *get_token_value(struct gui_wps *gwps, | |||
1317 | snprintf(buf, buf_size, "%d", global_settings.rec_quality); | 1312 | snprintf(buf, buf_size, "%d", global_settings.rec_quality); |
1318 | return buf; | 1313 | return buf; |
1319 | #endif | 1314 | #endif |
1320 | case WPS_TOKEN_REC_MONO: | 1315 | case SKIN_TOKEN_REC_MONO: |
1321 | if (!global_settings.rec_channels) | 1316 | if (!global_settings.rec_channels) |
1322 | return "m"; | 1317 | return "m"; |
1323 | return NULL; | 1318 | return NULL; |
1324 | 1319 | ||
1325 | case WPS_TOKEN_REC_SECONDS: | 1320 | case SKIN_TOKEN_REC_SECONDS: |
1326 | { | 1321 | { |
1327 | int time = (audio_recorded_time() / HZ) % 60; | 1322 | int time = (audio_recorded_time() / HZ) % 60; |
1328 | if (intval) | 1323 | if (intval) |
@@ -1330,7 +1325,7 @@ const char *get_token_value(struct gui_wps *gwps, | |||
1330 | snprintf(buf, buf_size, "%02d", time); | 1325 | snprintf(buf, buf_size, "%02d", time); |
1331 | return buf; | 1326 | return buf; |
1332 | } | 1327 | } |
1333 | case WPS_TOKEN_REC_MINUTES: | 1328 | case SKIN_TOKEN_REC_MINUTES: |
1334 | { | 1329 | { |
1335 | int time = (audio_recorded_time() / HZ) / 60; | 1330 | int time = (audio_recorded_time() / HZ) / 60; |
1336 | if (intval) | 1331 | if (intval) |
@@ -1338,7 +1333,7 @@ const char *get_token_value(struct gui_wps *gwps, | |||
1338 | snprintf(buf, buf_size, "%02d", time); | 1333 | snprintf(buf, buf_size, "%02d", time); |
1339 | return buf; | 1334 | return buf; |
1340 | } | 1335 | } |
1341 | case WPS_TOKEN_REC_HOURS: | 1336 | case SKIN_TOKEN_REC_HOURS: |
1342 | { | 1337 | { |
1343 | int time = (audio_recorded_time() / HZ) / 3600; | 1338 | int time = (audio_recorded_time() / HZ) / 3600; |
1344 | if (intval) | 1339 | if (intval) |
@@ -1349,7 +1344,7 @@ const char *get_token_value(struct gui_wps *gwps, | |||
1349 | 1344 | ||
1350 | #endif /* HAVE_RECORDING */ | 1345 | #endif /* HAVE_RECORDING */ |
1351 | 1346 | ||
1352 | case WPS_TOKEN_CURRENT_SCREEN: | 1347 | case SKIN_TOKEN_CURRENT_SCREEN: |
1353 | { | 1348 | { |
1354 | int curr_screen = current_screen(); | 1349 | int curr_screen = current_screen(); |
1355 | 1350 | ||
@@ -1390,7 +1385,7 @@ const char *get_token_value(struct gui_wps *gwps, | |||
1390 | return buf; | 1385 | return buf; |
1391 | } | 1386 | } |
1392 | 1387 | ||
1393 | case WPS_TOKEN_LANG_IS_RTL: | 1388 | case SKIN_TOKEN_LANG_IS_RTL: |
1394 | return lang_is_rtl() ? "r" : NULL; | 1389 | return lang_is_rtl() ? "r" : NULL; |
1395 | 1390 | ||
1396 | default: | 1391 | default: |
diff --git a/apps/gui/skin_engine/skin_tokens.h b/apps/gui/skin_engine/skin_tokens.h index 47311312db..d259fe431c 100644 --- a/apps/gui/skin_engine/skin_tokens.h +++ b/apps/gui/skin_engine/skin_tokens.h | |||
@@ -23,243 +23,11 @@ | |||
23 | #define _SKIN_TOKENS_H_ | 23 | #define _SKIN_TOKENS_H_ |
24 | 24 | ||
25 | #include <stdbool.h> | 25 | #include <stdbool.h> |
26 | 26 | #include "tag_table.h" | |
27 | |||
28 | enum wps_token_type { | ||
29 | |||
30 | TOKEN_MARKER_CONTROL_TOKENS = -1, | ||
31 | WPS_NO_TOKEN = 0, /* for WPS tags we don't want to save as tokens */ | ||
32 | WPS_TOKEN_UNKNOWN, | ||
33 | |||
34 | /* Markers */ | ||
35 | WPS_TOKEN_CHARACTER, | ||
36 | WPS_TOKEN_STRING, | ||
37 | WPS_TOKEN_TRANSLATEDSTRING, | ||
38 | |||
39 | /* Alignment */ | ||
40 | WPS_TOKEN_ALIGN_LEFT, | ||
41 | WPS_TOKEN_ALIGN_LEFT_RTL, | ||
42 | WPS_TOKEN_ALIGN_CENTER, | ||
43 | WPS_TOKEN_ALIGN_RIGHT, | ||
44 | WPS_TOKEN_ALIGN_RIGHT_RTL, | ||
45 | |||
46 | /* Sublines */ | ||
47 | WPS_TOKEN_SUBLINE_TIMEOUT, | ||
48 | |||
49 | /* Conditional */ | ||
50 | WPS_TOKEN_CONDITIONAL, | ||
51 | WPS_TOKEN_CONDITIONAL_START, | ||
52 | WPS_TOKEN_CONDITIONAL_OPTION, | ||
53 | WPS_TOKEN_CONDITIONAL_END, | ||
54 | |||
55 | /* Viewport display */ | ||
56 | WPS_VIEWPORT_ENABLE, | ||
57 | WPS_VIEWPORT_CUSTOMLIST, | ||
58 | WPS_TOKEN_UIVIEWPORT_ENABLE, | ||
59 | WPS_TOKEN_VIEWPORT_FGCOLOUR, | ||
60 | WPS_TOKEN_VIEWPORT_BGCOLOUR, | ||
61 | |||
62 | /* Battery */ | ||
63 | TOKEN_MARKER_BATTERY, | ||
64 | WPS_TOKEN_BATTERY_PERCENT, | ||
65 | WPS_TOKEN_BATTERY_PERCENTBAR, | ||
66 | WPS_TOKEN_BATTERY_VOLTS, | ||
67 | WPS_TOKEN_BATTERY_TIME, | ||
68 | WPS_TOKEN_BATTERY_CHARGER_CONNECTED, | ||
69 | WPS_TOKEN_BATTERY_CHARGING, | ||
70 | WPS_TOKEN_BATTERY_SLEEPTIME, | ||
71 | WPS_TOKEN_USB_POWERED, | ||
72 | |||
73 | /* Sound */ | ||
74 | TOKEN_MARKER_SOUND, | ||
75 | #if (CONFIG_CODEC != MAS3507D) | ||
76 | WPS_TOKEN_SOUND_PITCH, | ||
77 | #endif | ||
78 | #if (CONFIG_CODEC == SWCODEC) | ||
79 | WPS_TOKEN_SOUND_SPEED, | ||
80 | WPS_TOKEN_REPLAYGAIN, | ||
81 | WPS_TOKEN_CROSSFADE, | ||
82 | #endif | ||
83 | |||
84 | /* Time */ | ||
85 | TOKEN_MARKER_RTC, | ||
86 | WPS_TOKEN_RTC_PRESENT, | ||
87 | |||
88 | /* The begin/end values allow us to know if a token is an RTC one. | ||
89 | New RTC tokens should be added between the markers. */ | ||
90 | |||
91 | WPS_TOKENS_RTC_BEGIN, /* just the start marker, not an actual token */ | ||
92 | |||
93 | WPS_TOKEN_RTC_DAY_OF_MONTH, | ||
94 | WPS_TOKEN_RTC_DAY_OF_MONTH_BLANK_PADDED, | ||
95 | WPS_TOKEN_RTC_12HOUR_CFG, | ||
96 | WPS_TOKEN_RTC_HOUR_24_ZERO_PADDED, | ||
97 | WPS_TOKEN_RTC_HOUR_24, | ||
98 | WPS_TOKEN_RTC_HOUR_12_ZERO_PADDED, | ||
99 | WPS_TOKEN_RTC_HOUR_12, | ||
100 | WPS_TOKEN_RTC_MONTH, | ||
101 | WPS_TOKEN_RTC_MINUTE, | ||
102 | WPS_TOKEN_RTC_SECOND, | ||
103 | WPS_TOKEN_RTC_YEAR_2_DIGITS, | ||
104 | WPS_TOKEN_RTC_YEAR_4_DIGITS, | ||
105 | WPS_TOKEN_RTC_AM_PM_UPPER, | ||
106 | WPS_TOKEN_RTC_AM_PM_LOWER, | ||
107 | WPS_TOKEN_RTC_WEEKDAY_NAME, | ||
108 | WPS_TOKEN_RTC_MONTH_NAME, | ||
109 | WPS_TOKEN_RTC_DAY_OF_WEEK_START_MON, | ||
110 | WPS_TOKEN_RTC_DAY_OF_WEEK_START_SUN, | ||
111 | |||
112 | WPS_TOKENS_RTC_END, /* just the end marker, not an actual token */ | ||
113 | |||
114 | /* Database */ | ||
115 | TOKEN_MARKER_DATABASE, | ||
116 | #ifdef HAVE_TAGCACHE | ||
117 | WPS_TOKEN_DATABASE_PLAYCOUNT, | ||
118 | WPS_TOKEN_DATABASE_RATING, | ||
119 | WPS_TOKEN_DATABASE_AUTOSCORE, | ||
120 | #endif | ||
121 | |||
122 | /* File */ | ||
123 | TOKEN_MARKER_FILE, | ||
124 | WPS_TOKEN_FILE_BITRATE, | ||
125 | WPS_TOKEN_FILE_CODEC, | ||
126 | WPS_TOKEN_FILE_FREQUENCY, | ||
127 | WPS_TOKEN_FILE_FREQUENCY_KHZ, | ||
128 | WPS_TOKEN_FILE_NAME, | ||
129 | WPS_TOKEN_FILE_NAME_WITH_EXTENSION, | ||
130 | WPS_TOKEN_FILE_PATH, | ||
131 | WPS_TOKEN_FILE_SIZE, | ||
132 | WPS_TOKEN_FILE_VBR, | ||
133 | WPS_TOKEN_FILE_DIRECTORY, | ||
134 | |||
135 | /* Image */ | ||
136 | TOKEN_MARKER_IMAGES, | ||
137 | #ifdef HAVE_LCD_BITMAP | ||
138 | WPS_TOKEN_IMAGE_BACKDROP, | ||
139 | WPS_TOKEN_IMAGE_PROGRESS_BAR, | ||
140 | WPS_TOKEN_IMAGE_PRELOAD, | ||
141 | WPS_TOKEN_IMAGE_PRELOAD_DISPLAY, | ||
142 | WPS_TOKEN_IMAGE_DISPLAY, | ||
143 | #endif | ||
144 | |||
145 | #ifdef HAVE_ALBUMART | ||
146 | /* Albumart */ | ||
147 | WPS_TOKEN_ALBUMART_DISPLAY, | ||
148 | WPS_TOKEN_ALBUMART_FOUND, | ||
149 | #endif | ||
150 | |||
151 | /* Metadata */ | ||
152 | TOKEN_MARKER_METADATA, | ||
153 | WPS_TOKEN_METADATA_ARTIST, | ||
154 | WPS_TOKEN_METADATA_COMPOSER, | ||
155 | WPS_TOKEN_METADATA_ALBUM_ARTIST, | ||
156 | WPS_TOKEN_METADATA_GROUPING, | ||
157 | WPS_TOKEN_METADATA_ALBUM, | ||
158 | WPS_TOKEN_METADATA_GENRE, | ||
159 | WPS_TOKEN_METADATA_DISC_NUMBER, | ||
160 | WPS_TOKEN_METADATA_TRACK_NUMBER, | ||
161 | WPS_TOKEN_METADATA_TRACK_TITLE, | ||
162 | WPS_TOKEN_METADATA_VERSION, | ||
163 | WPS_TOKEN_METADATA_YEAR, | ||
164 | WPS_TOKEN_METADATA_COMMENT, | ||
165 | |||
166 | TOKEN_MARKER_PLAYBACK_INFO, | ||
167 | /* Mode */ | ||
168 | WPS_TOKEN_REPEAT_MODE, | ||
169 | WPS_TOKEN_PLAYBACK_STATUS, | ||
170 | /* Progressbar */ | ||
171 | WPS_TOKEN_PROGRESSBAR, | ||
172 | #ifdef HAVE_LCD_CHARCELLS | ||
173 | WPS_TOKEN_PLAYER_PROGRESSBAR, | ||
174 | #endif | ||
175 | #ifdef HAVE_LCD_BITMAP | ||
176 | /* Peakmeter */ | ||
177 | WPS_TOKEN_PEAKMETER, | ||
178 | #endif | ||
179 | |||
180 | /* Current track */ | ||
181 | WPS_TOKEN_TRACK_ELAPSED_PERCENT, | ||
182 | WPS_TOKEN_TRACK_TIME_ELAPSED, | ||
183 | WPS_TOKEN_TRACK_TIME_REMAINING, | ||
184 | WPS_TOKEN_TRACK_LENGTH, | ||
185 | WPS_TOKEN_TRACK_STARTING, | ||
186 | WPS_TOKEN_TRACK_ENDING, | ||
187 | |||
188 | /* Playlist */ | ||
189 | TOKEN_MARKER_PLAYLIST, | ||
190 | WPS_TOKEN_PLAYLIST_ENTRIES, | ||
191 | WPS_TOKEN_PLAYLIST_NAME, | ||
192 | WPS_TOKEN_PLAYLIST_POSITION, | ||
193 | WPS_TOKEN_PLAYLIST_SHUFFLE, | ||
194 | |||
195 | |||
196 | /* buttons */ | ||
197 | TOKEN_MARKER_MISC, | ||
198 | WPS_TOKEN_DRAW_INBUILTBAR, | ||
199 | WPS_TOKEN_LIST_TITLE_TEXT, | ||
200 | WPS_TOKEN_LIST_TITLE_ICON, | ||
201 | WPS_TOKEN_BUTTON_VOLUME, | ||
202 | WPS_TOKEN_LASTTOUCH, | ||
203 | #if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD) | ||
204 | /* Virtual LED */ | ||
205 | WPS_TOKEN_VLED_HDD, | ||
206 | #endif | ||
207 | /* Volume level */ | ||
208 | WPS_TOKEN_VOLUME, | ||
209 | WPS_TOKEN_VOLUMEBAR, | ||
210 | /* hold */ | ||
211 | WPS_TOKEN_MAIN_HOLD, | ||
212 | #ifdef HAS_REMOTE_BUTTON_HOLD | ||
213 | WPS_TOKEN_REMOTE_HOLD, | ||
214 | #endif | ||
215 | |||
216 | /* Setting option */ | ||
217 | WPS_TOKEN_SETTING, | ||
218 | WPS_TOKEN_CURRENT_SCREEN, | ||
219 | WPS_TOKEN_LANG_IS_RTL, | ||
220 | |||
221 | /* Recording Tokens */ | ||
222 | TOKEN_MARKER_RECORDING, | ||
223 | WPS_TOKEN_HAVE_RECORDING, | ||
224 | WPS_TOKEN_IS_RECORDING, | ||
225 | WPS_TOKEN_REC_FREQ, | ||
226 | WPS_TOKEN_REC_ENCODER, | ||
227 | WPS_TOKEN_REC_BITRATE, /* SWCODEC: MP3 bitrate, HWCODEC: MP3 "quality" */ | ||
228 | WPS_TOKEN_REC_MONO, | ||
229 | WPS_TOKEN_REC_SECONDS, | ||
230 | WPS_TOKEN_REC_MINUTES, | ||
231 | WPS_TOKEN_REC_HOURS, | ||
232 | |||
233 | |||
234 | /* Radio Tokens */ | ||
235 | TOKEN_MARKER_TUNER, | ||
236 | WPS_TOKEN_HAVE_TUNER, | ||
237 | #if CONFIG_TUNER | ||
238 | WPS_TOKEN_TUNER_TUNED, | ||
239 | WPS_TOKEN_TUNER_SCANMODE, | ||
240 | WPS_TOKEN_TUNER_STEREO, | ||
241 | WPS_TOKEN_TUNER_MINFREQ, /* changes based on "region" */ | ||
242 | WPS_TOKEN_TUNER_MAXFREQ, /* changes based on "region" */ | ||
243 | WPS_TOKEN_TUNER_CURFREQ, | ||
244 | WPS_TOKEN_PRESET_ID, /* "id" of this preset.. really the array element number */ | ||
245 | WPS_TOKEN_PRESET_NAME, | ||
246 | WPS_TOKEN_PRESET_FREQ, | ||
247 | WPS_TOKEN_PRESET_COUNT, | ||
248 | /* RDS tokens */ | ||
249 | WPS_TOKEN_HAVE_RDS, | ||
250 | #ifdef HAVE_RDS_CAP | ||
251 | WPS_TOKEN_RDS_NAME, | ||
252 | WPS_TOKEN_RDS_TEXT, | ||
253 | #endif | ||
254 | #endif /* CONFIG_TUNER */ | ||
255 | |||
256 | |||
257 | TOKEN_MARKER_END, /* this needs to be the last value in this enum */ | ||
258 | }; | ||
259 | 27 | ||
260 | struct wps_token { | 28 | struct wps_token { |
261 | unsigned char type; /* enough to store the token type */ | 29 | enum skin_token_type type; /* enough to store the token type */ |
262 | 30 | ||
263 | /* Whether the tag (e.g. track name or the album) refers the | 31 | /* Whether the tag (e.g. track name or the album) refers the |
264 | current or the next song (false=current, true=next) */ | 32 | current or the next song (false=current, true=next) */ |
265 | bool next; | 33 | bool next; |
diff --git a/apps/gui/skin_engine/wps_debug.c b/apps/gui/skin_engine/wps_debug.c index 59e8542eff..2ab7e5ab4e 100644 --- a/apps/gui/skin_engine/wps_debug.c +++ b/apps/gui/skin_engine/wps_debug.c | |||
@@ -26,7 +26,6 @@ | |||
26 | 26 | ||
27 | #include <stdio.h> | 27 | #include <stdio.h> |
28 | #include <string.h> | 28 | #include <string.h> |
29 | #include "skin_buffer.h" | ||
30 | #include "settings_list.h" | 29 | #include "settings_list.h" |
31 | #ifdef __PCTOOL__ | 30 | #ifdef __PCTOOL__ |
32 | #ifdef WPSEDITOR | 31 | #ifdef WPSEDITOR |
diff --git a/apps/gui/skin_engine/wps_internals.h b/apps/gui/skin_engine/wps_internals.h index f3f83370f4..ec37560e79 100644 --- a/apps/gui/skin_engine/wps_internals.h +++ b/apps/gui/skin_engine/wps_internals.h | |||
@@ -24,6 +24,8 @@ | |||
24 | 24 | ||
25 | #ifndef _WPS_ENGINE_INTERNALS_ | 25 | #ifndef _WPS_ENGINE_INTERNALS_ |
26 | #define _WPS_ENGINE_INTERNALS_ | 26 | #define _WPS_ENGINE_INTERNALS_ |
27 | |||
28 | |||
27 | /* Timeout unit expressed in HZ. In WPS, all timeouts are given in seconds | 29 | /* Timeout unit expressed in HZ. In WPS, all timeouts are given in seconds |
28 | (possibly with a decimal fraction) but stored as integer values. | 30 | (possibly with a decimal fraction) but stored as integer values. |
29 | E.g. 2.5 is stored as 25. This means 25 tenth of a second, i.e. 25 units. | 31 | E.g. 2.5 is stored as 25. This means 25 tenth of a second, i.e. 25 units. |
@@ -32,6 +34,8 @@ | |||
32 | #define DEFAULT_SUBLINE_TIME_MULTIPLIER 20 /* In TIMEOUT_UNIT's */ | 34 | #define DEFAULT_SUBLINE_TIME_MULTIPLIER 20 /* In TIMEOUT_UNIT's */ |
33 | 35 | ||
34 | #include "skin_tokens.h" | 36 | #include "skin_tokens.h" |
37 | #include "tag_table.h" | ||
38 | #include "skin_parser.h" | ||
35 | 39 | ||
36 | 40 | ||
37 | /* TODO: sort this mess out */ | 41 | /* TODO: sort this mess out */ |
@@ -40,19 +44,6 @@ | |||
40 | #include "statusbar.h" | 44 | #include "statusbar.h" |
41 | #include "metadata.h" | 45 | #include "metadata.h" |
42 | 46 | ||
43 | /* constants used in line_type and as refresh_mode for wps_refresh */ | ||
44 | #define WPS_REFRESH_STATIC (1u<<0) /* line doesn't change over time */ | ||
45 | #define WPS_REFRESH_DYNAMIC (1u<<1) /* line may change (e.g. time flag) */ | ||
46 | #define WPS_REFRESH_SCROLL (1u<<2) /* line scrolls */ | ||
47 | #define WPS_REFRESH_PLAYER_PROGRESS (1u<<3) /* line contains a progress bar */ | ||
48 | #define WPS_REFRESH_PEAK_METER (1u<<4) /* line contains a peak meter */ | ||
49 | #define WPS_REFRESH_STATUSBAR (1u<<5) /* refresh statusbar */ | ||
50 | #define WPS_REFRESH_ALL (0xffffffffu) /* to refresh all line types */ | ||
51 | |||
52 | /* to refresh only those lines that change over time */ | ||
53 | #define WPS_REFRESH_NON_STATIC (WPS_REFRESH_DYNAMIC| \ | ||
54 | WPS_REFRESH_PLAYER_PROGRESS| \ | ||
55 | WPS_REFRESH_PEAK_METER) | ||
56 | /* alignments */ | 47 | /* alignments */ |
57 | #define WPS_ALIGN_RIGHT 32 | 48 | #define WPS_ALIGN_RIGHT 32 |
58 | #define WPS_ALIGN_CENTER 64 | 49 | #define WPS_ALIGN_CENTER 64 |
@@ -82,16 +73,16 @@ struct gui_img { | |||
82 | short int y; /* y-pos */ | 73 | short int y; /* y-pos */ |
83 | short int num_subimages; /* number of sub-images */ | 74 | short int num_subimages; /* number of sub-images */ |
84 | short int subimage_height; /* height of each sub-image */ | 75 | short int subimage_height; /* height of each sub-image */ |
85 | short int display; /* -1 for no display, 0..n to display a subimage */ | ||
86 | struct bitmap bm; | 76 | struct bitmap bm; |
87 | char label; | 77 | char label; |
88 | bool loaded; /* load state */ | 78 | bool loaded; /* load state */ |
89 | bool always_display; /* not using the preload/display mechanism */ | 79 | bool always_display; /* not using the preload/display mechanism */ |
80 | int display; | ||
90 | }; | 81 | }; |
91 | 82 | ||
92 | 83 | ||
93 | struct progressbar { | 84 | struct progressbar { |
94 | enum wps_token_type type; | 85 | enum skin_token_type type; |
95 | struct viewport *vp; | 86 | struct viewport *vp; |
96 | /* regular pb */ | 87 | /* regular pb */ |
97 | short x; | 88 | short x; |
@@ -105,8 +96,6 @@ struct progressbar { | |||
105 | /*progressbar image*/ | 96 | /*progressbar image*/ |
106 | struct bitmap bm; | 97 | struct bitmap bm; |
107 | bool have_bitmap_pb; | 98 | bool have_bitmap_pb; |
108 | |||
109 | bool draw; | ||
110 | }; | 99 | }; |
111 | #endif | 100 | #endif |
112 | 101 | ||
@@ -157,45 +146,6 @@ enum wps_parse_error { | |||
157 | PARSE_FAIL_LIMITS_EXCEEDED, | 146 | PARSE_FAIL_LIMITS_EXCEEDED, |
158 | }; | 147 | }; |
159 | 148 | ||
160 | |||
161 | /* Description of a subline on the WPS */ | ||
162 | struct skin_subline { | ||
163 | |||
164 | /* Index of the first token for this subline in the token array. | ||
165 | Tokens of this subline end where tokens for the next subline | ||
166 | begin. */ | ||
167 | unsigned short first_token_idx; | ||
168 | unsigned short last_token_idx; | ||
169 | |||
170 | /* Bit or'ed WPS_REFRESH_xxx */ | ||
171 | unsigned char line_type; | ||
172 | |||
173 | /* How long the subline should be displayed, in 10ths of sec */ | ||
174 | unsigned char time_mult; | ||
175 | |||
176 | /* pointer to the next subline in this line */ | ||
177 | struct skin_subline *next; | ||
178 | }; | ||
179 | |||
180 | /* Description of a line on the WPS. A line is a set of sublines. | ||
181 | A subline is displayed for a certain amount of time. After that, | ||
182 | the next subline of the line is displayed. And so on. */ | ||
183 | struct skin_line { | ||
184 | |||
185 | /* Linked list of all the sublines on this line, | ||
186 | * a line *must* have at least one subline so no need to add an extra pointer */ | ||
187 | struct skin_subline sublines; | ||
188 | /* pointer to the current subline */ | ||
189 | struct skin_subline *curr_subline; | ||
190 | |||
191 | /* When the next subline of this line should be displayed | ||
192 | (absolute time value in ticks) */ | ||
193 | long subline_expire_time; | ||
194 | |||
195 | /* pointer to the next line */ | ||
196 | struct skin_line *next; | ||
197 | }; | ||
198 | |||
199 | #define VP_DRAW_HIDEABLE 0x1 | 149 | #define VP_DRAW_HIDEABLE 0x1 |
200 | #define VP_DRAW_HIDDEN 0x2 | 150 | #define VP_DRAW_HIDDEN 0x2 |
201 | #define VP_DRAW_WASHIDDEN 0x4 | 151 | #define VP_DRAW_WASHIDDEN 0x4 |
@@ -206,7 +156,6 @@ struct skin_line { | |||
206 | #define VP_INFO_LABEL 0x80 | 156 | #define VP_INFO_LABEL 0x80 |
207 | struct skin_viewport { | 157 | struct skin_viewport { |
208 | struct viewport vp; /* The LCD viewport struct */ | 158 | struct viewport vp; /* The LCD viewport struct */ |
209 | struct skin_line *lines; | ||
210 | char hidden_flags; | 159 | char hidden_flags; |
211 | char label; | 160 | char label; |
212 | unsigned start_fgcolour; | 161 | unsigned start_fgcolour; |
@@ -236,9 +185,6 @@ struct touchregion { | |||
236 | }; | 185 | }; |
237 | #endif | 186 | #endif |
238 | 187 | ||
239 | #define MAX_PLAYLISTLINE_TOKENS 16 | ||
240 | #define MAX_PLAYLISTLINE_STRINGS 8 | ||
241 | #define MAX_PLAYLISTLINE_STRLEN 8 | ||
242 | enum info_line_type { | 188 | enum info_line_type { |
243 | TRACK_HAS_INFO = 0, | 189 | TRACK_HAS_INFO = 0, |
244 | TRACK_HAS_NO_INFO | 190 | TRACK_HAS_NO_INFO |
@@ -250,36 +196,50 @@ struct playlistviewer { | |||
250 | #ifdef HAVE_TC_RAMCACHE | 196 | #ifdef HAVE_TC_RAMCACHE |
251 | struct mp3entry tempid3; | 197 | struct mp3entry tempid3; |
252 | #endif | 198 | #endif |
253 | struct { | 199 | struct skin_element *lines[2]; |
254 | enum wps_token_type tokens[MAX_PLAYLISTLINE_TOKENS]; | ||
255 | char strings[MAX_PLAYLISTLINE_STRINGS][MAX_PLAYLISTLINE_STRLEN]; | ||
256 | int count; | ||
257 | bool scroll; | ||
258 | } lines[2]; | ||
259 | }; | 200 | }; |
260 | 201 | ||
261 | 202 | ||
262 | #ifdef HAVE_ALBUMART | 203 | #ifdef HAVE_ALBUMART |
263 | struct skin_albumart { | 204 | struct skin_albumart { |
264 | /* Album art support */ | 205 | /* Album art support */ |
265 | struct viewport *vp;/* The viewport this is in */ | ||
266 | int x; | 206 | int x; |
267 | int y; | 207 | int y; |
268 | int width; | 208 | int width; |
269 | int height; | 209 | int height; |
270 | 210 | ||
271 | bool draw; | ||
272 | unsigned char xalign; /* WPS_ALBUMART_ALIGN_LEFT, _CENTER, _RIGHT */ | 211 | unsigned char xalign; /* WPS_ALBUMART_ALIGN_LEFT, _CENTER, _RIGHT */ |
273 | unsigned char yalign; /* WPS_ALBUMART_ALIGN_TOP, _CENTER, _BOTTOM */ | 212 | unsigned char yalign; /* WPS_ALBUMART_ALIGN_TOP, _CENTER, _BOTTOM */ |
274 | unsigned char state; /* WPS_ALBUMART_NONE, _CHECK, _LOAD */ | 213 | unsigned char state; /* WPS_ALBUMART_NONE, _CHECK, _LOAD */ |
214 | |||
215 | struct viewport *vp; | ||
216 | int draw_handle; | ||
275 | }; | 217 | }; |
276 | #endif | 218 | #endif |
277 | 219 | ||
220 | |||
221 | struct line { | ||
222 | int timeout; /* if inside a line alternator */ | ||
223 | unsigned update_mode; | ||
224 | }; | ||
225 | |||
226 | struct line_alternator { | ||
227 | int current_line; | ||
228 | unsigned long last_change_tick; | ||
229 | }; | ||
230 | |||
231 | struct conditional { | ||
232 | int last_value; | ||
233 | struct wps_token *token; | ||
234 | }; | ||
235 | |||
236 | |||
278 | /* wps_data | 237 | /* wps_data |
279 | this struct holds all necessary data which describes the | 238 | this struct holds all necessary data which describes the |
280 | viewable content of a wps */ | 239 | viewable content of a wps */ |
281 | struct wps_data | 240 | struct wps_data |
282 | { | 241 | { |
242 | struct skin_element *tree; | ||
283 | #ifdef HAVE_LCD_BITMAP | 243 | #ifdef HAVE_LCD_BITMAP |
284 | struct skin_token_list *images; | 244 | struct skin_token_list *images; |
285 | struct skin_token_list *progressbars; | 245 | struct skin_token_list *progressbars; |
@@ -291,16 +251,10 @@ struct wps_data | |||
291 | #ifdef HAVE_TOUCHSCREEN | 251 | #ifdef HAVE_TOUCHSCREEN |
292 | struct skin_token_list *touchregions; | 252 | struct skin_token_list *touchregions; |
293 | #endif | 253 | #endif |
294 | struct skin_token_list *viewports; | ||
295 | struct skin_token_list *strings; | ||
296 | #ifdef HAVE_ALBUMART | 254 | #ifdef HAVE_ALBUMART |
297 | struct skin_albumart *albumart; | 255 | struct skin_albumart *albumart; |
298 | int playback_aa_slot; | 256 | int playback_aa_slot; |
299 | #endif | 257 | #endif |
300 | struct wps_token *tokens; | ||
301 | /* Total number of tokens in the WPS. During WPS parsing, this is | ||
302 | the index of the token being parsed. */ | ||
303 | int num_tokens; | ||
304 | 258 | ||
305 | #ifdef HAVE_LCD_BITMAP | 259 | #ifdef HAVE_LCD_BITMAP |
306 | bool peak_meter_enabled; | 260 | bool peak_meter_enabled; |
diff --git a/apps/gui/statusbar-skinned.c b/apps/gui/statusbar-skinned.c index 168b17fa38..8eb082d50f 100644 --- a/apps/gui/statusbar-skinned.c +++ b/apps/gui/statusbar-skinned.c | |||
@@ -27,6 +27,9 @@ | |||
27 | #include "appevents.h" | 27 | #include "appevents.h" |
28 | #include "screens.h" | 28 | #include "screens.h" |
29 | #include "screen_access.h" | 29 | #include "screen_access.h" |
30 | #include "strlcpy.h" | ||
31 | #include "skin_parser.h" | ||
32 | #include "skin_buffer.h" | ||
30 | #include "skin_engine/skin_engine.h" | 33 | #include "skin_engine/skin_engine.h" |
31 | #include "skin_engine/wps_internals.h" | 34 | #include "skin_engine/wps_internals.h" |
32 | #include "viewport.h" | 35 | #include "viewport.h" |
@@ -45,26 +48,55 @@ static struct wps_sync_data sb_skin_sync_data = { .do_full_update = false | |||
45 | 48 | ||
46 | /* initial setup of wps_data */ | 49 | /* initial setup of wps_data */ |
47 | static int update_delay = DEFAULT_UPDATE_DELAY; | 50 | static int update_delay = DEFAULT_UPDATE_DELAY; |
48 | 51 | struct wps_token *found_token; | |
49 | bool sb_set_title_text(char* title, enum themable_icons icon, enum screen_type screen) | 52 | static int set_title_worker(char* title, enum themable_icons icon, |
53 | struct wps_data *data, struct skin_element *root) | ||
50 | { | 54 | { |
51 | int i; | 55 | int retval = 0; |
52 | bool retval = false; | 56 | struct skin_element *element = root; |
53 | for(i=0; i<sb_skin_data[screen].num_tokens; i++) | 57 | while (element) |
54 | { | 58 | { |
55 | if (sb_skin_data[screen].tokens[i].type == WPS_TOKEN_LIST_TITLE_TEXT) | 59 | struct wps_token *token = NULL; |
60 | if (element->type == CONDITIONAL) | ||
61 | { | ||
62 | struct conditional *cond = (struct conditional *)element->data; | ||
63 | token = cond->token; | ||
64 | } | ||
65 | else if (element->type == TAG) | ||
66 | { | ||
67 | token = (struct wps_token *)element->data; | ||
68 | } | ||
69 | if (token) | ||
56 | { | 70 | { |
57 | sb_skin_data[screen].tokens[i].value.data = title; | 71 | if (token->type == SKIN_TOKEN_LIST_TITLE_TEXT) |
58 | retval = true; | 72 | { |
73 | found_token = token; | ||
74 | token->value.data = title; | ||
75 | retval = 1; | ||
76 | } | ||
77 | else if (token->type == SKIN_TOKEN_LIST_TITLE_ICON) | ||
78 | { | ||
79 | /* Icon_NOICON == -1 which the skin engine wants at position 1, so + 2 */ | ||
80 | token->value.i = icon+2; | ||
81 | } | ||
59 | } | 82 | } |
60 | else if (sb_skin_data[screen].tokens[i].type == WPS_TOKEN_LIST_TITLE_ICON) | 83 | if (element->children_count) |
61 | { | 84 | { |
62 | /* Icon_NOICON == -1 which the skin engine wants at position 1, so + 2 */ | 85 | int i; |
63 | sb_skin_data[screen].tokens[i].value.i = icon+2; | 86 | for (i=0; i<element->children_count; i++) |
87 | retval |= set_title_worker(title, icon, data, element->children[i]); | ||
64 | } | 88 | } |
89 | element = element->next; | ||
65 | } | 90 | } |
66 | return retval; | 91 | return retval; |
67 | } | 92 | } |
93 | |||
94 | bool sb_set_title_text(char* title, enum themable_icons icon, enum screen_type screen) | ||
95 | { | ||
96 | bool retval = set_title_worker(title, icon, &sb_skin_data[screen], | ||
97 | sb_skin_data[screen].tree) > 0; | ||
98 | return retval; | ||
99 | } | ||
68 | 100 | ||
69 | 101 | ||
70 | void sb_skin_data_load(enum screen_type screen, const char *buf, bool isfile) | 102 | void sb_skin_data_load(enum screen_type screen, const char *buf, bool isfile) |
@@ -75,18 +107,22 @@ void sb_skin_data_load(enum screen_type screen, const char *buf, bool isfile) | |||
75 | success = buf && skin_data_load(screen, data, buf, isfile); | 107 | success = buf && skin_data_load(screen, data, buf, isfile); |
76 | 108 | ||
77 | if (success) | 109 | if (success) |
78 | { /* hide the sb's default viewport because it has nasty effect with stuff | 110 | { |
111 | /* hide the sb's default viewport because it has nasty effect with stuff | ||
79 | * not part of the statusbar, | 112 | * not part of the statusbar, |
80 | * hence .sbs's without any other vps are unsupported*/ | 113 | * hence .sbs's without any other vps are unsupported*/ |
81 | struct skin_viewport *vp = find_viewport(VP_DEFAULT_LABEL, data); | 114 | struct skin_viewport *vp = find_viewport(VP_DEFAULT_LABEL, data); |
82 | struct skin_token_list *next_vp = data->viewports->next; | 115 | struct skin_element *next_vp = data->tree->next; |
83 | 116 | ||
84 | if (!next_vp) | 117 | if (vp) |
85 | { /* no second viewport, let parsing fail */ | 118 | { |
86 | success = false; | 119 | if (!next_vp) |
120 | { /* no second viewport, let parsing fail */ | ||
121 | success = false; | ||
122 | } | ||
123 | /* hide this viewport, forever */ | ||
124 | vp->hidden_flags = VP_NEVER_VISIBLE; | ||
87 | } | 125 | } |
88 | /* hide this viewport, forever */ | ||
89 | vp->hidden_flags = VP_NEVER_VISIBLE; | ||
90 | sb_set_info_vp(screen, VP_INFO_LABEL|VP_DEFAULT_LABEL); | 126 | sb_set_info_vp(screen, VP_INFO_LABEL|VP_DEFAULT_LABEL); |
91 | } | 127 | } |
92 | 128 | ||
@@ -135,7 +171,7 @@ bool sb_set_backdrop(enum screen_type screen, char* filename) | |||
135 | else | 171 | else |
136 | #endif | 172 | #endif |
137 | buf_size = LCD_BACKDROP_BYTES; | 173 | buf_size = LCD_BACKDROP_BYTES; |
138 | sb_skin[screen].data->backdrop = skin_buffer_alloc(buf_size); | 174 | sb_skin[screen].data->backdrop = (char*)skin_buffer_alloc(buf_size); |
139 | if (!sb_skin[screen].data->backdrop) | 175 | if (!sb_skin[screen].data->backdrop) |
140 | return false; | 176 | return false; |
141 | } | 177 | } |
@@ -150,6 +186,8 @@ void sb_skin_update(enum screen_type screen, bool force) | |||
150 | { | 186 | { |
151 | static long next_update[NB_SCREENS] = {0}; | 187 | static long next_update[NB_SCREENS] = {0}; |
152 | int i = screen; | 188 | int i = screen; |
189 | if (!sb_skin_data[screen].wps_loaded) | ||
190 | return; | ||
153 | if (TIME_AFTER(current_tick, next_update[i]) || force) | 191 | if (TIME_AFTER(current_tick, next_update[i]) || force) |
154 | { | 192 | { |
155 | #if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP) | 193 | #if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP) |
@@ -158,7 +196,7 @@ void sb_skin_update(enum screen_type screen, bool force) | |||
158 | if (lcd_active() || (i != SCREEN_MAIN)) | 196 | if (lcd_active() || (i != SCREEN_MAIN)) |
159 | #endif | 197 | #endif |
160 | skin_update(&sb_skin[i], force? | 198 | skin_update(&sb_skin[i], force? |
161 | WPS_REFRESH_ALL : WPS_REFRESH_NON_STATIC); | 199 | SKIN_REFRESH_ALL : SKIN_REFRESH_NON_STATIC); |
162 | next_update[i] = current_tick + update_delay; /* don't update too often */ | 200 | next_update[i] = current_tick + update_delay; /* don't update too often */ |
163 | sb_skin[SCREEN_MAIN].sync_data->do_full_update = false; | 201 | sb_skin[SCREEN_MAIN].sync_data->do_full_update = false; |
164 | } | 202 | } |
@@ -216,7 +254,30 @@ void sb_create_from_settings(enum screen_type screen) | |||
216 | 254 | ||
217 | if (ptr2[0] && ptr2[0] != '-') /* from ui viewport setting */ | 255 | if (ptr2[0] && ptr2[0] != '-') /* from ui viewport setting */ |
218 | { | 256 | { |
257 | char *comma = ptr; | ||
258 | int param_count = 0; | ||
219 | len = snprintf(ptr, remaining, "%%ax%%Vi(-,%s)\n", ptr2); | 259 | len = snprintf(ptr, remaining, "%%ax%%Vi(-,%s)\n", ptr2); |
260 | /* The config put the colours at the end of the viewport, | ||
261 | * they need to be stripped for the skin code though */ | ||
262 | do { | ||
263 | param_count++; | ||
264 | comma = strchr(comma+1, ','); | ||
265 | |||
266 | } while (comma && param_count < 6); | ||
267 | if (comma) | ||
268 | { | ||
269 | char *end = comma; | ||
270 | char fg[8], bg[8]; | ||
271 | int i = 0; | ||
272 | comma++; | ||
273 | while (*comma != ',') | ||
274 | fg[i++] = *comma++; | ||
275 | fg[i] = '\0'; comma++; i=0; | ||
276 | while (*comma != ')') | ||
277 | bg[i++] = *comma++; | ||
278 | bg[i] = '\0'; | ||
279 | len += snprintf(end, remaining-len, ") %%Vf(%s) %%Vb(%s)\n", fg, bg); | ||
280 | } | ||
220 | } | 281 | } |
221 | else | 282 | else |
222 | { | 283 | { |
diff --git a/apps/gui/theme_settings.c b/apps/gui/theme_settings.c index f3628f60db..e9862eda3a 100644 --- a/apps/gui/theme_settings.c +++ b/apps/gui/theme_settings.c | |||
@@ -30,14 +30,21 @@ | |||
30 | #include "settings.h" | 30 | #include "settings.h" |
31 | #include "wps.h" | 31 | #include "wps.h" |
32 | #include "file.h" | 32 | #include "file.h" |
33 | #include "buffer.h" | ||
33 | #if CONFIG_TUNER | 34 | #if CONFIG_TUNER |
34 | #include "radio.h" | 35 | #include "radio.h" |
35 | #endif | 36 | #endif |
36 | #include "skin_engine/skin_engine.h" | 37 | #include "skin_engine/skin_engine.h" |
37 | #include "skin_engine/skin_fonts.h" | 38 | #include "skin_buffer.h" |
38 | #include "statusbar-skinned.h" | 39 | #include "statusbar-skinned.h" |
39 | #include "bootchart.h" | 40 | #include "bootchart.h" |
40 | 41 | ||
42 | static char *skin_buffer = NULL; | ||
43 | void theme_init_buffer(void) | ||
44 | { | ||
45 | skin_buffer = buffer_alloc(SKIN_BUFFER_SIZE); | ||
46 | } | ||
47 | |||
41 | 48 | ||
42 | /* call this after loading a .wps/.rwps or other skin files, so that the | 49 | /* call this after loading a .wps/.rwps or other skin files, so that the |
43 | * skin buffer is reset properly | 50 | * skin buffer is reset properly |
@@ -71,9 +78,10 @@ void settings_apply_skins(void) | |||
71 | { | 78 | { |
72 | char buf[MAX_PATH]; | 79 | char buf[MAX_PATH]; |
73 | /* re-initialize the skin buffer before we start reloading skins */ | 80 | /* re-initialize the skin buffer before we start reloading skins */ |
74 | skin_buffer_init(); | ||
75 | enum screen_type screen = SCREEN_MAIN; | 81 | enum screen_type screen = SCREEN_MAIN; |
76 | unsigned int i; | 82 | unsigned int i; |
83 | |||
84 | skin_buffer_init(skin_buffer, SKIN_BUFFER_SIZE); | ||
77 | #ifdef HAVE_LCD_BITMAP | 85 | #ifdef HAVE_LCD_BITMAP |
78 | skin_backdrop_init(); | 86 | skin_backdrop_init(); |
79 | skin_font_init(); | 87 | skin_font_init(); |
diff --git a/apps/gui/viewport.c b/apps/gui/viewport.c index 7d79e5f04a..2b1cc9eb05 100644 --- a/apps/gui/viewport.c +++ b/apps/gui/viewport.c | |||
@@ -310,13 +310,6 @@ static void set_default_align_flags(struct viewport *vp) | |||
310 | #endif /* HAVE_LCD_BITMAP */ | 310 | #endif /* HAVE_LCD_BITMAP */ |
311 | #endif /* __PCTOOL__ */ | 311 | #endif /* __PCTOOL__ */ |
312 | 312 | ||
313 | #ifdef HAVE_LCD_COLOR | ||
314 | #define ARG_STRING(_depth) ((_depth) == 2 ? "dddddgg":"dddddcc") | ||
315 | #else | ||
316 | #define ARG_STRING(_depth) "dddddgg" | ||
317 | #endif | ||
318 | |||
319 | |||
320 | void viewport_set_fullscreen(struct viewport *vp, | 313 | void viewport_set_fullscreen(struct viewport *vp, |
321 | const enum screen_type screen) | 314 | const enum screen_type screen) |
322 | { | 315 | { |
@@ -416,81 +409,4 @@ int get_viewport_default_colour(enum screen_type screen, bool fgcolour) | |||
416 | #endif /* LCD_DEPTH > 1 || LCD_REMOTE_DEPTH > 1 */ | 409 | #endif /* LCD_DEPTH > 1 || LCD_REMOTE_DEPTH > 1 */ |
417 | } | 410 | } |
418 | 411 | ||
419 | const char* viewport_parse_viewport(struct viewport *vp, | ||
420 | enum screen_type screen, | ||
421 | const char *bufptr, | ||
422 | const char separator) | ||
423 | { | ||
424 | /* parse the list to the viewport struct */ | ||
425 | const char *ptr = bufptr; | ||
426 | uint32_t set = 0; | ||
427 | |||
428 | enum { | ||
429 | PL_X = 0, | ||
430 | PL_Y, | ||
431 | PL_WIDTH, | ||
432 | PL_HEIGHT, | ||
433 | PL_FONT, | ||
434 | }; | ||
435 | |||
436 | if (!(ptr = parse_list("ddddd", &set, separator, ptr, | ||
437 | &vp->x, &vp->y, &vp->width, &vp->height, &vp->font))) | ||
438 | return NULL; | ||
439 | |||
440 | /* X and Y *must* be set */ | ||
441 | if (!LIST_VALUE_PARSED(set, PL_X) || !LIST_VALUE_PARSED(set, PL_Y)) | ||
442 | return NULL; | ||
443 | /* check for negative values */ | ||
444 | if (vp->x < 0) | ||
445 | vp->x += screens[screen].lcdwidth; | ||
446 | if (vp->y < 0) | ||
447 | vp->y += screens[screen].lcdheight; | ||
448 | |||
449 | /* fix defaults, | ||
450 | * and negative width/height which means "extend to edge minus value */ | ||
451 | if (!LIST_VALUE_PARSED(set, PL_WIDTH)) | ||
452 | vp->width = screens[screen].lcdwidth - vp->x; | ||
453 | else if (vp->width < 0) | ||
454 | vp->width = (vp->width + screens[screen].lcdwidth) - vp->x; | ||
455 | if (!LIST_VALUE_PARSED(set, PL_HEIGHT)) | ||
456 | vp->height = screens[screen].lcdheight - vp->y; | ||
457 | else if (vp->height < 0) | ||
458 | vp->height = (vp->height + screens[screen].lcdheight) - vp->y; | ||
459 | |||
460 | #if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1) | ||
461 | vp->fg_pattern = get_viewport_default_colour(screen, true); | ||
462 | vp->bg_pattern = get_viewport_default_colour(screen, false); | ||
463 | #endif /* LCD_DEPTH > 1 || LCD_REMOTE_DEPTH > 1 */ | ||
464 | |||
465 | #ifdef HAVE_LCD_COLOR | ||
466 | vp->lss_pattern = global_settings.lss_color; | ||
467 | vp->lse_pattern = global_settings.lse_color; | ||
468 | vp->lst_pattern = global_settings.lst_color; | ||
469 | #endif | ||
470 | |||
471 | /* Validate the viewport dimensions - we know that the numbers are | ||
472 | non-negative integers, ignore bars and assume the viewport takes them | ||
473 | * into account */ | ||
474 | if ((vp->x >= screens[screen].lcdwidth) || | ||
475 | ((vp->x + vp->width) > screens[screen].lcdwidth) || | ||
476 | (vp->y >= screens[screen].lcdheight) || | ||
477 | ((vp->y + vp->height) > screens[screen].lcdheight)) | ||
478 | { | ||
479 | return NULL; | ||
480 | } | ||
481 | |||
482 | /* Default to using the user font if the font was an invalid number or '-' | ||
483 | * font 1 is *always* the UI font for the current screen | ||
484 | * 2 is always the first extra font */ | ||
485 | if (!LIST_VALUE_PARSED(set, PL_FONT)) | ||
486 | vp->font = FONT_UI; | ||
487 | |||
488 | /* Set the defaults for fields not user-specified */ | ||
489 | vp->drawmode = DRMODE_SOLID; | ||
490 | #ifndef __PCTOOL__ | ||
491 | set_default_align_flags(vp); | ||
492 | #endif | ||
493 | |||
494 | return ptr; | ||
495 | } | ||
496 | #endif | 412 | #endif |
diff --git a/apps/gui/viewport.h b/apps/gui/viewport.h index 943cac2451..51ab35e575 100644 --- a/apps/gui/viewport.h +++ b/apps/gui/viewport.h | |||
@@ -74,25 +74,4 @@ bool viewport_point_within_vp(const struct viewport *vp, | |||
74 | 74 | ||
75 | #endif /* __PCTOOL__ */ | 75 | #endif /* __PCTOOL__ */ |
76 | 76 | ||
77 | #ifdef HAVE_LCD_BITMAP | ||
78 | |||
79 | /* | ||
80 | * Parse a viewport definition (vp_def), which looks like: | ||
81 | * | ||
82 | * Screens with depth > 1: | ||
83 | * X|Y|width|height|font|foregorund color|background color | ||
84 | * Screens with depth = 1: | ||
85 | * X|Y|width|height|font | ||
86 | * | ||
87 | * | is a separator and can be specified via the parameter | ||
88 | * | ||
89 | * Returns the pointer to the char after the last character parsed | ||
90 | * if everything went OK or NULL if an error happened (some values | ||
91 | * not specified in the definition) | ||
92 | */ | ||
93 | const char* viewport_parse_viewport(struct viewport *vp, | ||
94 | enum screen_type screen, | ||
95 | const char *vp_def, | ||
96 | const char separator); | ||
97 | #endif /* HAVE_LCD_BITMAP */ | ||
98 | #endif /* __VIEWPORT_H__ */ | 77 | #endif /* __VIEWPORT_H__ */ |
diff --git a/apps/gui/wps.c b/apps/gui/wps.c index a582afa76b..7dca6454e0 100644 --- a/apps/gui/wps.c +++ b/apps/gui/wps.c | |||
@@ -175,7 +175,7 @@ void fade(bool fade_in, bool updatewps) | |||
175 | if (updatewps) | 175 | if (updatewps) |
176 | { | 176 | { |
177 | FOR_NB_SCREENS(i) | 177 | FOR_NB_SCREENS(i) |
178 | skin_update(&gui_wps[i], WPS_REFRESH_NON_STATIC); | 178 | skin_update(&gui_wps[i], SKIN_REFRESH_NON_STATIC); |
179 | } | 179 | } |
180 | sleep(1); | 180 | sleep(1); |
181 | } | 181 | } |
@@ -191,7 +191,7 @@ void fade(bool fade_in, bool updatewps) | |||
191 | if (updatewps) | 191 | if (updatewps) |
192 | { | 192 | { |
193 | FOR_NB_SCREENS(i) | 193 | FOR_NB_SCREENS(i) |
194 | skin_update(&gui_wps[i], WPS_REFRESH_NON_STATIC); | 194 | skin_update(&gui_wps[i], SKIN_REFRESH_NON_STATIC); |
195 | } | 195 | } |
196 | sleep(1); | 196 | sleep(1); |
197 | } | 197 | } |
@@ -212,7 +212,7 @@ void fade(bool fade_in, bool updatewps) | |||
212 | 212 | ||
213 | static bool update_onvol_change(struct gui_wps * gwps) | 213 | static bool update_onvol_change(struct gui_wps * gwps) |
214 | { | 214 | { |
215 | skin_update(gwps, WPS_REFRESH_NON_STATIC); | 215 | skin_update(gwps, SKIN_REFRESH_NON_STATIC); |
216 | 216 | ||
217 | #ifdef HAVE_LCD_CHARCELLS | 217 | #ifdef HAVE_LCD_CHARCELLS |
218 | splashf(0, "Vol: %3d dB", | 218 | splashf(0, "Vol: %3d dB", |
@@ -372,8 +372,8 @@ bool ffwd_rew(int button) | |||
372 | FOR_NB_SCREENS(i) | 372 | FOR_NB_SCREENS(i) |
373 | { | 373 | { |
374 | skin_update(&gui_wps[i], | 374 | skin_update(&gui_wps[i], |
375 | WPS_REFRESH_PLAYER_PROGRESS | | 375 | SKIN_REFRESH_PLAYER_PROGRESS | |
376 | WPS_REFRESH_DYNAMIC); | 376 | SKIN_REFRESH_DYNAMIC); |
377 | } | 377 | } |
378 | 378 | ||
379 | break; | 379 | break; |
@@ -390,7 +390,7 @@ bool ffwd_rew(int button) | |||
390 | #endif | 390 | #endif |
391 | #ifdef HAVE_LCD_CHARCELLS | 391 | #ifdef HAVE_LCD_CHARCELLS |
392 | FOR_NB_SCREENS(i) | 392 | FOR_NB_SCREENS(i) |
393 | skin_update(&gui_wps[i], WPS_REFRESH_ALL); | 393 | skin_update(&gui_wps[i], SKIN_REFRESH_ALL); |
394 | #endif | 394 | #endif |
395 | exit = true; | 395 | exit = true; |
396 | break; | 396 | break; |
@@ -662,7 +662,7 @@ static void gwps_enter_wps(void) | |||
662 | display->backdrop_show(gwps->data->backdrop); | 662 | display->backdrop_show(gwps->data->backdrop); |
663 | #endif | 663 | #endif |
664 | display->clear_display(); | 664 | display->clear_display(); |
665 | skin_update(gwps, WPS_REFRESH_ALL); | 665 | skin_update(gwps, SKIN_REFRESH_ALL); |
666 | 666 | ||
667 | #ifdef HAVE_TOUCHSCREEN | 667 | #ifdef HAVE_TOUCHSCREEN |
668 | skin_disarm_touchregions(gui_wps[i].data); | 668 | skin_disarm_touchregions(gui_wps[i].data); |
@@ -1116,7 +1116,7 @@ long gui_wps_show(void) | |||
1116 | #endif | 1116 | #endif |
1117 | { | 1117 | { |
1118 | skin_update(&gui_wps[i], wps_sync_data.do_full_update ? | 1118 | skin_update(&gui_wps[i], wps_sync_data.do_full_update ? |
1119 | WPS_REFRESH_ALL : WPS_REFRESH_NON_STATIC); | 1119 | SKIN_REFRESH_ALL : SKIN_REFRESH_NON_STATIC); |
1120 | } | 1120 | } |
1121 | } | 1121 | } |
1122 | wps_sync_data.do_full_update = false; | 1122 | wps_sync_data.do_full_update = false; |