summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorNicolas Pennequin <nicolas.pennequin@free.fr>2007-04-08 04:01:06 +0000
committerNicolas Pennequin <nicolas.pennequin@free.fr>2007-04-08 04:01:06 +0000
commit07696c10b10a051af3cb680b06c422e13c42aa76 (patch)
tree1dd2b0e7ae675978052c4a9ae7f067e6a4983176 /apps
parentfad3ad6894bf0c8024f2925ac1d6f535170ae3b0 (diff)
downloadrockbox-07696c10b10a051af3cb680b06c422e13c42aa76.tar.gz
rockbox-07696c10b10a051af3cb680b06c422e13c42aa76.zip
FS#6991. Patch by Alexander Levin, modified by me:
* Reorganisation of the WPS data structure with line and subline structs. This allows us to use sublines more sparingly, so it should save some memory. Also it removes the need for the "End Of Line" token. Overall, the data structure and the code are simplified and gain in clarity. * Some code improvements and added comments. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13065 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps')
-rw-r--r--apps/gui/gwps-common.c135
-rw-r--r--apps/gui/gwps.h122
-rw-r--r--apps/gui/wps_debug.c232
-rw-r--r--apps/gui/wps_parser.c207
4 files changed, 408 insertions, 288 deletions
diff --git a/apps/gui/gwps-common.c b/apps/gui/gwps-common.c
index c96b830cf2..078e20ba44 100644
--- a/apps/gui/gwps-common.c
+++ b/apps/gui/gwps-common.c
@@ -81,12 +81,10 @@ void gui_wps_statusbar_draw(struct gui_wps *wps, bool force)
81{ 81{
82 bool draw = global_settings.statusbar; 82 bool draw = global_settings.statusbar;
83 83
84 if(wps->data->wps_sb_tag 84 if (wps->data->wps_sb_tag)
85 && wps->data->show_sb_on_wps) 85 draw = wps->data->show_sb_on_wps;
86 draw = true; 86
87 else if(wps->data->wps_sb_tag) 87 if (draw)
88 draw = false;
89 if(draw)
90 gui_statusbar_draw(wps->statusbar, force); 88 gui_statusbar_draw(wps->statusbar, force);
91} 89}
92#else 90#else
@@ -1012,15 +1010,13 @@ static char *get_tag(struct gui_wps *gwps,
1012 } 1010 }
1013 } 1011 }
1014#endif 1012#endif
1015
1016 case WPS_TOKEN_BATTERY_SLEEPTIME: 1013 case WPS_TOKEN_BATTERY_SLEEPTIME:
1017 { 1014 {
1018 if (get_sleep_timer() == 0) 1015 if (get_sleep_timer() == 0)
1019 return NULL; 1016 return NULL;
1020 else 1017 else
1021 { 1018 {
1022 format_time(buf, buf_size, \ 1019 format_time(buf, buf_size, get_sleep_timer() * 1000);
1023 get_sleep_timer() * 1000);
1024 return buf; 1020 return buf;
1025 } 1021 }
1026 } 1022 }
@@ -1377,6 +1373,7 @@ static bool get_line(struct gui_wps *gwps,
1377 char temp_buf[128]; 1373 char temp_buf[128];
1378 char *buf = linebuf; /* will always point to the writing position */ 1374 char *buf = linebuf; /* will always point to the writing position */
1379 char *linebuf_end = linebuf + linebuf_size - 1; 1375 char *linebuf_end = linebuf + linebuf_size - 1;
1376 int i, last_token_idx;
1380 bool update = false; 1377 bool update = false;
1381 1378
1382 /* alignment-related variables */ 1379 /* alignment-related variables */
@@ -1384,16 +1381,14 @@ static bool get_line(struct gui_wps *gwps,
1384 char* cur_align_start; 1381 char* cur_align_start;
1385 cur_align_start = buf; 1382 cur_align_start = buf;
1386 cur_align = WPS_ALIGN_LEFT; 1383 cur_align = WPS_ALIGN_LEFT;
1387 align->left = 0; 1384 align->left = NULL;
1388 align->center = 0; 1385 align->center = NULL;
1389 align->right = 0; 1386 align->right = NULL;
1390 1387
1391 /* start at the beginning of the current (sub)line */ 1388 /* Process all tokens of the desired subline */
1392 int i = data->format_lines[line][subline]; 1389 last_token_idx = wps_last_token_index(data, line, subline);
1393 1390 for (i = wps_first_token_index(data, line, subline);
1394 while (data->tokens[i].type != WPS_TOKEN_EOL 1391 i <= last_token_idx; i++)
1395 && data->tokens[i].type != WPS_TOKEN_SUBLINE_SEPARATOR
1396 && i < data->num_tokens)
1397 { 1392 {
1398 switch(data->tokens[i].type) 1393 switch(data->tokens[i].type)
1399 { 1394 {
@@ -1460,8 +1455,7 @@ static bool get_line(struct gui_wps *gwps,
1460 default: 1455 default:
1461 { 1456 {
1462 /* get the value of the tag and copy it to the buffer */ 1457 /* get the value of the tag and copy it to the buffer */
1463 char *value = get_tag(gwps, i, temp_buf, 1458 char *value = get_tag(gwps,i,temp_buf,sizeof(temp_buf),NULL);
1464 sizeof(temp_buf), NULL);
1465 if (value) 1459 if (value)
1466 { 1460 {
1467 update = true; 1461 update = true;
@@ -1471,7 +1465,6 @@ static bool get_line(struct gui_wps *gwps,
1471 break; 1465 break;
1472 } 1466 }
1473 } 1467 }
1474 i++;
1475 } 1468 }
1476 1469
1477 /* close the current alignment */ 1470 /* close the current alignment */
@@ -1496,13 +1489,14 @@ static bool get_line(struct gui_wps *gwps,
1496static void get_subline_timeout(struct gui_wps *gwps, int line, int subline) 1489static void get_subline_timeout(struct gui_wps *gwps, int line, int subline)
1497{ 1490{
1498 struct wps_data *data = gwps->data; 1491 struct wps_data *data = gwps->data;
1499 int i = data->format_lines[line][subline]; 1492 int i;
1493 int subline_idx = wps_subline_index(data, line, subline);
1494 int last_token_idx = wps_last_token_index(data, line, subline);
1500 1495
1501 data->time_mult[line][subline] = DEFAULT_SUBLINE_TIME_MULTIPLIER; 1496 data->sublines[subline_idx].time_mult = DEFAULT_SUBLINE_TIME_MULTIPLIER;
1502 1497
1503 while (data->tokens[i].type != WPS_TOKEN_EOL 1498 for (i = wps_first_token_index(data, line, subline);
1504 && data->tokens[i].type != WPS_TOKEN_SUBLINE_SEPARATOR 1499 i <= last_token_idx; i++)
1505 && i < data->num_tokens)
1506 { 1500 {
1507 switch(data->tokens[i].type) 1501 switch(data->tokens[i].type)
1508 { 1502 {
@@ -1518,32 +1512,33 @@ static void get_subline_timeout(struct gui_wps *gwps, int line, int subline)
1518 break; 1512 break;
1519 1513
1520 case WPS_TOKEN_SUBLINE_TIMEOUT: 1514 case WPS_TOKEN_SUBLINE_TIMEOUT:
1521 data->time_mult[line][subline] = data->tokens[i].value.i; 1515 data->sublines[subline_idx].time_mult = data->tokens[i].value.i;
1522 break; 1516 break;
1523 1517
1524 default: 1518 default:
1525 break; 1519 break;
1526 } 1520 }
1527 i++;
1528 } 1521 }
1529} 1522}
1530 1523
1531/* Calculate which subline should be displayed for each line */ 1524/* Calculates which subline should be displayed for the specified line
1532static bool get_curr_subline(struct gui_wps *gwps, int line) 1525 Returns true iff the subline must be refreshed */
1526static bool update_curr_subline(struct gui_wps *gwps, int line)
1533{ 1527{
1534 struct wps_data *data = gwps->data; 1528 struct wps_data *data = gwps->data;
1535 1529
1536 int search, search_start; 1530 int search, search_start, num_sublines;
1537 bool reset_subline; 1531 bool reset_subline;
1538 bool new_subline_refresh; 1532 bool new_subline_refresh;
1539 bool only_one_subline; 1533 bool only_one_subline;
1540 1534
1541 reset_subline = (data->curr_subline[line] == SUBLINE_RESET); 1535 num_sublines = data->lines[line].num_sublines;
1536 reset_subline = (data->lines[line].curr_subline == SUBLINE_RESET);
1542 new_subline_refresh = false; 1537 new_subline_refresh = false;
1543 only_one_subline = false; 1538 only_one_subline = false;
1544 1539
1545 /* if time to advance to next sub-line */ 1540 /* if time to advance to next sub-line */
1546 if (TIME_AFTER(current_tick, data->subline_expire_time[line] - 1) || 1541 if (TIME_AFTER(current_tick, data->lines[line].subline_expire_time - 1) ||
1547 reset_subline) 1542 reset_subline)
1548 { 1543 {
1549 /* search all sublines until the next subline with time > 0 1544 /* search all sublines until the next subline with time > 0
@@ -1551,43 +1546,45 @@ static bool get_curr_subline(struct gui_wps *gwps, int line)
1551 if (reset_subline) 1546 if (reset_subline)
1552 search_start = 0; 1547 search_start = 0;
1553 else 1548 else
1554 search_start = data->curr_subline[line]; 1549 search_start = data->lines[line].curr_subline;
1555 1550
1556 for (search = 0; search < WPS_MAX_SUBLINES; search++) 1551 for (search = 0; search < num_sublines; search++)
1557 { 1552 {
1558 data->curr_subline[line]++; 1553 data->lines[line].curr_subline++;
1559 1554
1560 /* wrap around if beyond last defined subline or WPS_MAX_SUBLINES */ 1555 /* wrap around if beyond last defined subline or WPS_MAX_SUBLINES */
1561 if ((!data->format_lines[line][data->curr_subline[line]]) || 1556 if (data->lines[line].curr_subline == num_sublines)
1562 (data->curr_subline[line] == WPS_MAX_SUBLINES))
1563 { 1557 {
1564 if (data->curr_subline[line] == 1) 1558 if (data->lines[line].curr_subline == 1)
1565 only_one_subline = true; 1559 only_one_subline = true;
1566 data->curr_subline[line] = 0; 1560 data->lines[line].curr_subline = 0;
1567 } 1561 }
1568 1562
1569 /* if back where we started after search or 1563 /* if back where we started after search or
1570 only one subline is defined on the line */ 1564 only one subline is defined on the line */
1571 if (((search > 0) && (data->curr_subline[line] == search_start)) || 1565 if (((search > 0) && (data->lines[line].curr_subline == search_start)) ||
1572 only_one_subline) 1566 only_one_subline)
1573 { 1567 {
1574 /* no other subline with a time > 0 exists */ 1568 /* no other subline with a time > 0 exists */
1575 data->subline_expire_time[line] = (reset_subline? 1569 data->lines[line].subline_expire_time = (reset_subline ?
1576 current_tick : data->subline_expire_time[line]) + 100 * HZ; 1570 current_tick : data->lines[line].subline_expire_time) + 100 * HZ;
1577 break; 1571 break;
1578 } 1572 }
1579 else 1573 else
1580 { 1574 {
1581 /* get initial time multiplier for this subline */ 1575 /* get initial time multiplier for this subline */
1582 get_subline_timeout(gwps, line, data->curr_subline[line]); 1576 get_subline_timeout(gwps, line, data->lines[line].curr_subline);
1577
1578 int subline_idx = wps_subline_index(data, line,
1579 data->lines[line].curr_subline);
1583 1580
1584 /* only use this subline if subline time > 0 */ 1581 /* only use this subline if subline time > 0 */
1585 if (data->time_mult[line][data->curr_subline[line]] > 0) 1582 if (data->sublines[subline_idx].time_mult > 0)
1586 { 1583 {
1587 new_subline_refresh = true; 1584 new_subline_refresh = true;
1588 data->subline_expire_time[line] = (reset_subline ? 1585 data->lines[line].subline_expire_time = (reset_subline ?
1589 current_tick : data->subline_expire_time[line]) + 1586 current_tick : data->lines[line].subline_expire_time) +
1590 BASE_SUBLINE_TIME * data->time_mult[line][data->curr_subline[line]]; 1587 BASE_SUBLINE_TIME * data->sublines[subline_idx].time_mult;
1591 break; 1588 break;
1592 } 1589 }
1593 } 1590 }
@@ -1779,7 +1776,7 @@ bool gui_wps_refresh(struct gui_wps *gwps,
1779 if(!gwps || !data || !state || !display) 1776 if(!gwps || !data || !state || !display)
1780 return false; 1777 return false;
1781 1778
1782 int line, i; 1779 int line, i, subline_idx;
1783 unsigned char flags; 1780 unsigned char flags;
1784 char linebuf[MAX_PATH]; 1781 char linebuf[MAX_PATH];
1785 1782
@@ -1814,7 +1811,7 @@ bool gui_wps_refresh(struct gui_wps *gwps,
1814 { 1811 {
1815 for (i = 0; i < data->num_lines; i++) 1812 for (i = 0; i < data->num_lines; i++)
1816 { 1813 {
1817 data->curr_subline[i] = SUBLINE_RESET; 1814 data->lines[i].curr_subline = SUBLINE_RESET;
1818 } 1815 }
1819 } 1816 }
1820 1817
@@ -1840,15 +1837,16 @@ bool gui_wps_refresh(struct gui_wps *gwps,
1840 update_line = false; 1837 update_line = false;
1841 1838
1842 /* get current subline for the line */ 1839 /* get current subline for the line */
1843 new_subline_refresh = get_curr_subline(gwps, line); 1840 new_subline_refresh = update_curr_subline(gwps, line);
1844 1841
1845 flags = data->line_type[line][data->curr_subline[line]]; 1842 subline_idx = wps_subline_index(data, line, data->lines[line].curr_subline);
1843 flags = data->sublines[subline_idx].line_type;
1846 1844
1847 if (refresh_mode == WPS_REFRESH_ALL || flags & refresh_mode 1845 if (refresh_mode == WPS_REFRESH_ALL || (flags & refresh_mode)
1848 || new_subline_refresh) 1846 || new_subline_refresh)
1849 { 1847 {
1850 /* get_line tells us if we need to update the line */ 1848 /* get_line tells us if we need to update the line */
1851 update_line = get_line(gwps, line, data->curr_subline[line], 1849 update_line = get_line(gwps, line, data->lines[line].curr_subline,
1852 &align, linebuf, sizeof(linebuf)); 1850 &align, linebuf, sizeof(linebuf));
1853 } 1851 }
1854 1852
@@ -1947,3 +1945,30 @@ bool gui_wps_refresh(struct gui_wps *gwps,
1947 1945
1948 return true; 1946 return true;
1949} 1947}
1948
1949int wps_subline_index(struct wps_data *data, int line, int subline)
1950{
1951 return data->lines[line].first_subline_idx + subline;
1952}
1953
1954int wps_first_token_index(struct wps_data *data, int line, int subline)
1955{
1956 int first_subline_idx = data->lines[line].first_subline_idx;
1957 return data->sublines[first_subline_idx + subline].first_token_idx;
1958}
1959
1960int wps_last_token_index(struct wps_data *data, int line, int subline)
1961{
1962 int first_subline_idx = data->lines[line].first_subline_idx;
1963 int idx = first_subline_idx + subline;
1964 if (idx < data->num_sublines - 1)
1965 {
1966 /* This subline ends where the next begins */
1967 return data->sublines[idx+1].first_token_idx - 1;
1968 }
1969 else
1970 {
1971 /* The last subline goes to the end */
1972 return data->num_tokens - 1;
1973 }
1974}
diff --git a/apps/gui/gwps.h b/apps/gui/gwps.h
index 02a83085b9..f012b3b304 100644
--- a/apps/gui/gwps.h
+++ b/apps/gui/gwps.h
@@ -71,23 +71,25 @@ struct align_pos {
71#define MAX_IMAGES (26*2) /* a-z and A-Z */ 71#define MAX_IMAGES (26*2) /* a-z and A-Z */
72#define IMG_BUFSIZE ((LCD_HEIGHT*LCD_WIDTH*LCD_DEPTH/8) \ 72#define IMG_BUFSIZE ((LCD_HEIGHT*LCD_WIDTH*LCD_DEPTH/8) \
73 + (2*LCD_HEIGHT*LCD_WIDTH/8)) 73 + (2*LCD_HEIGHT*LCD_WIDTH/8))
74#define WPS_MAX_LINES (LCD_HEIGHT/5+1) 74
75#define WPS_MAX_TOKENS 1024 75#define WPS_MAX_LINES (LCD_HEIGHT/5+1)
76#define WPS_MAX_STRINGS 128 76#define WPS_MAX_SUBLINES (WPS_MAX_LINES*3)
77#define STRING_BUFFER_SIZE 512 77#define WPS_MAX_TOKENS 1024
78#define WPS_MAX_COND_LEVEL 10 78#define WPS_MAX_STRINGS 128
79#define STRING_BUFFER_SIZE 512
80#define WPS_MAX_COND_LEVEL 10
79 81
80#else 82#else
81 83
82#define WPS_MAX_LINES 2 84#define WPS_MAX_LINES 2
83#define WPS_MAX_TOKENS 64 85#define WPS_MAX_SUBLINES 12
84#define WPS_MAX_STRINGS 32 86#define WPS_MAX_TOKENS 64
85#define STRING_BUFFER_SIZE 64 87#define WPS_MAX_STRINGS 32
86#define WPS_MAX_COND_LEVEL 5 88#define STRING_BUFFER_SIZE 64
89#define WPS_MAX_COND_LEVEL 5
87 90
88#endif 91#endif
89 92
90#define WPS_MAX_SUBLINES 12
91#define DEFAULT_SUBLINE_TIME_MULTIPLIER 20 /* (10ths of sec) */ 93#define DEFAULT_SUBLINE_TIME_MULTIPLIER 20 /* (10ths of sec) */
92#define BASE_SUBLINE_TIME 10 /* base time that multiplier is applied to 94#define BASE_SUBLINE_TIME 10 /* base time that multiplier is applied to
93 (1/HZ sec, or 100ths of sec) */ 95 (1/HZ sec, or 100ths of sec) */
@@ -100,18 +102,13 @@ enum wps_token_type {
100 /* Markers */ 102 /* Markers */
101 WPS_TOKEN_CHARACTER, 103 WPS_TOKEN_CHARACTER,
102 WPS_TOKEN_STRING, 104 WPS_TOKEN_STRING,
103 WPS_TOKEN_EOL,
104 105
105 /* Alignment */ 106 /* Alignment */
106 WPS_TOKEN_ALIGN_LEFT, 107 WPS_TOKEN_ALIGN_LEFT,
107 WPS_TOKEN_ALIGN_CENTER, 108 WPS_TOKEN_ALIGN_CENTER,
108 WPS_TOKEN_ALIGN_RIGHT, 109 WPS_TOKEN_ALIGN_RIGHT,
109 110
110 /* Scrolling */ 111 /* Sublines */
111 WPS_TOKEN_SCROLL,
112
113 /* Alternating sublines */
114 WPS_TOKEN_SUBLINE_SEPARATOR,
115 WPS_TOKEN_SUBLINE_TIMEOUT, 112 WPS_TOKEN_SUBLINE_TIMEOUT,
116 113
117 /* Battery */ 114 /* Battery */
@@ -228,12 +225,6 @@ enum wps_token_type {
228 WPS_TOKEN_PLAYLIST_POSITION, 225 WPS_TOKEN_PLAYLIST_POSITION,
229 WPS_TOKEN_PLAYLIST_SHUFFLE, 226 WPS_TOKEN_PLAYLIST_SHUFFLE,
230 227
231#ifdef HAVE_LCD_BITMAP
232 /* Statusbar */
233 WPS_TOKEN_STATUSBAR_ENABLED,
234 WPS_TOKEN_STATUSBAR_DISABLED,
235#endif
236
237#if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD) 228#if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
238 /* Virtual LED */ 229 /* Virtual LED */
239 WPS_TOKEN_VLED_HDD 230 WPS_TOKEN_VLED_HDD
@@ -242,13 +233,52 @@ enum wps_token_type {
242 233
243struct wps_token { 234struct wps_token {
244 enum wps_token_type type; 235 enum wps_token_type type;
236
237 /* Whether the tag (e.g. track name or the album) refers the
238 current or the next song (false=current, true=next) */
245 bool next; 239 bool next;
240
246 union { 241 union {
247 char c; 242 char c;
248 unsigned short i; 243 unsigned short i;
249 } value; 244 } value;
250}; 245};
251 246
247/* Description of a subline on the WPS */
248struct wps_subline {
249
250 /* Index of the first token for this subline in the token array.
251 Tokens of this subline end where tokens for the next subline
252 begin. */
253 unsigned short first_token_idx;
254
255 /* Bit or'ed WPS_REFRESH_xxx */
256 unsigned char line_type;
257
258 /* How long the subline should be displayed, in 10ths of sec */
259 unsigned char time_mult;
260};
261
262/* Description of a line on the WPS. A line is a set of sublines.
263 A subline is displayed for a certain amount of time. After that,
264 the next subline of the line is displayed. And so on. */
265struct wps_line {
266
267 /* Number of sublines in this line */
268 signed char num_sublines;
269
270 /* Number (0-based) of the subline within this line currently being displayed */
271 signed char curr_subline;
272
273 /* Index of the first subline of this line in the subline array.
274 Sublines for this line end where sublines for the next line begin. */
275 unsigned short first_subline_idx;
276
277 /* When the next subline of this line should be displayed
278 (absolute time value in ticks) */
279 long subline_expire_time;
280};
281
252 282
253/* wps_data 283/* wps_data
254 this struct holds all necessary data which describes the 284 this struct holds all necessary data which describes the
@@ -273,20 +303,24 @@ struct wps_data
273 unsigned short wps_progress_pat[8]; 303 unsigned short wps_progress_pat[8];
274 bool full_line_progressbar; 304 bool full_line_progressbar;
275#endif 305#endif
276 unsigned short format_lines[WPS_MAX_LINES][WPS_MAX_SUBLINES]; 306 /* Number of lines in the WPS. During WPS parsing, this is
277 unsigned char num_lines; 307 the index of the line being parsed. */
278 unsigned char line_type[WPS_MAX_LINES][WPS_MAX_SUBLINES]; 308 int num_lines;
279 unsigned short time_mult[WPS_MAX_LINES][WPS_MAX_SUBLINES]; 309 struct wps_line lines[WPS_MAX_LINES];
280 long subline_expire_time[WPS_MAX_LINES]; 310
281 short curr_subline[WPS_MAX_LINES]; 311 /* Total number of sublines in the WPS. During WPS parsing, this is
282 unsigned char num_sublines[WPS_MAX_LINES]; 312 the index of the subline where the parsed tokens are added to. */
283 313 int num_sublines;
314 struct wps_subline sublines[WPS_MAX_SUBLINES];
315
316 /* Total number of tokens in the WPS. During WPS parsing, this is
317 the index of the token being parsed. */
318 int num_tokens;
284 struct wps_token tokens[WPS_MAX_TOKENS]; 319 struct wps_token tokens[WPS_MAX_TOKENS];
285 unsigned short num_tokens;
286 320
287 char string_buffer[STRING_BUFFER_SIZE]; 321 char string_buffer[STRING_BUFFER_SIZE];
288 char *strings[WPS_MAX_STRINGS]; 322 char *strings[WPS_MAX_STRINGS];
289 unsigned char num_strings; 323 int num_strings;
290 324
291 bool wps_loaded; 325 bool wps_loaded;
292}; 326};
@@ -300,6 +334,24 @@ bool wps_data_load(struct wps_data *wps_data,
300 const char *buf, 334 const char *buf,
301 bool isfile); 335 bool isfile);
302 336
337/* Returns the index of the subline in the subline array
338 line - 0-based line number
339 subline - 0-based subline number within the line
340 */
341int wps_subline_index(struct wps_data *wps_data, int line, int subline);
342
343/* Returns the index of the first subline's token in the token array
344 line - 0-based line number
345 subline - 0-based subline number within the line
346 */
347int wps_first_token_index(struct wps_data *data, int line, int subline);
348
349/* Returns the index of the last subline's token in the token array.
350 line - 0-based line number
351 subline - 0-based subline number within the line
352 */
353int wps_last_token_index(struct wps_data *data, int line, int subline);
354
303/* wps_data end */ 355/* wps_data end */
304 356
305/* wps_state 357/* wps_state
@@ -329,11 +381,11 @@ struct wps_state
329/* wps_state end*/ 381/* wps_state end*/
330 382
331/* gui_wps 383/* gui_wps
332 defines a wps with it's data, state, 384 defines a wps with its data, state,
333 and the screen on which the wps-content should be drawn */ 385 and the screen on which the wps-content should be drawn */
334struct gui_wps 386struct gui_wps
335{ 387{
336 struct screen * display; 388 struct screen *display;
337 struct wps_data *data; 389 struct wps_data *data;
338 struct wps_state *state; 390 struct wps_state *state;
339 struct gui_statusbar *statusbar; 391 struct gui_statusbar *statusbar;
diff --git a/apps/gui/wps_debug.c b/apps/gui/wps_debug.c
index bcb05e0902..0e2b151551 100644
--- a/apps/gui/wps_debug.c
+++ b/apps/gui/wps_debug.c
@@ -24,107 +24,122 @@
24#include "gwps.h" 24#include "gwps.h"
25#include "debug.h" 25#include "debug.h"
26 26
27static char *next_str(bool next) {
28 return next ? "next" : "";
29}
30
27void dump_wps_tokens(struct wps_data *data) 31void dump_wps_tokens(struct wps_data *data)
28{ 32{
33 struct wps_token *token;
29 int i, j; 34 int i, j;
30 int indent = 0; 35 int indent = 0;
31 char buf[64]; 36 char buf[64];
32 bool next; 37 bool next;
33 38
34 /* Dump parsed WPS */ 39 if (data->num_tokens > WPS_MAX_TOKENS) {
35 for(i = 0; i < data->num_tokens && i < WPS_MAX_TOKENS; i++) { 40 DEBUGF("Number of tokens is too high (%d)!!!\n", data->num_tokens);
41 return;
42 }
36 43
37 next = data->tokens[i].next; 44 /* Dump parsed WPS */
45 for (i = 0, token = data->tokens; i < data->num_tokens; i++, token++) {
46 next = token->next;
38 47
39 switch(data->tokens[i].type) { 48 switch(token->type) {
40 case WPS_TOKEN_UNKNOWN: 49 case WPS_TOKEN_UNKNOWN:
41 snprintf(buf, sizeof(buf), "Unknown token"); 50 snprintf(buf, sizeof(buf), "Unknown token");
42 break; 51 break;
43 case WPS_TOKEN_CHARACTER: 52 case WPS_TOKEN_CHARACTER:
44 snprintf(buf, sizeof(buf), "Character '%c'", 53 snprintf(buf, sizeof(buf), "Character '%c'",
45 data->tokens[i].value.c); 54 token->value.c);
46 break; 55 break;
47 56
48 case WPS_TOKEN_STRING: 57 case WPS_TOKEN_STRING:
49 snprintf(buf, sizeof(buf), "String '%s'", 58 snprintf(buf, sizeof(buf), "String '%s'",
50 data->strings[data->tokens[i].value.i]); 59 data->strings[token->value.i]);
51 break;
52
53 case WPS_TOKEN_EOL:
54 snprintf(buf, sizeof(buf), "%s", "EOL");
55 break; 60 break;
56 61
57#ifdef HAVE_LCD_BITMAP 62#ifdef HAVE_LCD_BITMAP
58 case WPS_TOKEN_ALIGN_LEFT: 63 case WPS_TOKEN_ALIGN_LEFT:
59 snprintf(buf, sizeof(buf), "%s", "align left"); 64 snprintf(buf, sizeof(buf), "align left");
60 break; 65 break;
61 66
62 case WPS_TOKEN_ALIGN_CENTER: 67 case WPS_TOKEN_ALIGN_CENTER:
63 snprintf(buf, sizeof(buf), "%s", "align center"); 68 snprintf(buf, sizeof(buf), "align center");
64 break; 69 break;
65 70
66 case WPS_TOKEN_ALIGN_RIGHT: 71 case WPS_TOKEN_ALIGN_RIGHT:
67 snprintf(buf, sizeof(buf), "%s", "align right"); 72 snprintf(buf, sizeof(buf), "align right");
68 break; 73 break;
69#endif 74#endif
70 75
76 case WPS_TOKEN_SUBLINE_TIMEOUT:
77 snprintf(buf, sizeof(buf), "subline timeout value: %d",
78 token->value.i);
79 break;
80
71 case WPS_TOKEN_CONDITIONAL: 81 case WPS_TOKEN_CONDITIONAL:
72 snprintf(buf, sizeof(buf), "%s, %d options", "conditional", 82 snprintf(buf, sizeof(buf), "conditional, %d options",
73 data->tokens[i].value.i); 83 token->value.i);
74 break; 84 break;
75 85
76 case WPS_TOKEN_CONDITIONAL_START: 86 case WPS_TOKEN_CONDITIONAL_START:
77 snprintf(buf, sizeof(buf), "%s, next cond: %d", 87 snprintf(buf, sizeof(buf), "conditional start, next cond: %d",
78 "conditional start", data->tokens[i].value.i); 88 token->value.i);
79 indent++; 89 indent++;
80 break; 90 break;
81 91
82 case WPS_TOKEN_CONDITIONAL_OPTION: 92 case WPS_TOKEN_CONDITIONAL_OPTION:
83 snprintf(buf, sizeof(buf), "%s, next cond: %d", 93 snprintf(buf, sizeof(buf), "conditional option, next cond: %d",
84 "conditional option", data->tokens[i].value.i); 94 token->value.i);
85 break; 95 break;
86 96
87 case WPS_TOKEN_CONDITIONAL_END: 97 case WPS_TOKEN_CONDITIONAL_END:
88 snprintf(buf, sizeof(buf), "%s", "conditional end"); 98 snprintf(buf, sizeof(buf), "conditional end");
89 indent--; 99 indent--;
90 break; 100 break;
91 101
92#ifdef HAVE_LCD_BITMAP 102#ifdef HAVE_LCD_BITMAP
93 case WPS_TOKEN_IMAGE_PRELOAD: 103 case WPS_TOKEN_IMAGE_PRELOAD:
94 snprintf(buf, sizeof(buf), "%s", "preload image"); 104 snprintf(buf, sizeof(buf), "preload image");
95 break; 105 break;
96 106
97 case WPS_TOKEN_IMAGE_PRELOAD_DISPLAY: 107 case WPS_TOKEN_IMAGE_PRELOAD_DISPLAY:
98 snprintf(buf, sizeof(buf), "%s %d", "display preloaded image", 108 snprintf(buf, sizeof(buf), "display preloaded image %d",
99 data->tokens[i].value.i); 109 token->value.i);
100 break; 110 break;
101 111
102 case WPS_TOKEN_IMAGE_DISPLAY: 112 case WPS_TOKEN_IMAGE_DISPLAY:
103 snprintf(buf, sizeof(buf), "%s", "display image"); 113 snprintf(buf, sizeof(buf), "display image");
104 break; 114 break;
105#endif 115#endif
106 116
107#ifdef HAS_BUTTON_HOLD 117#ifdef HAS_BUTTON_HOLD
108 case WPS_TOKEN_MAIN_HOLD: 118 case WPS_TOKEN_MAIN_HOLD:
109 snprintf(buf, sizeof(buf), "%s", "mode hold"); 119 snprintf(buf, sizeof(buf), "mode hold");
110 break; 120 break;
111#endif 121#endif
112 122
113#ifdef HAS_REMOTE_BUTTON_HOLD 123#ifdef HAS_REMOTE_BUTTON_HOLD
114 case WPS_TOKEN_REMOTE_HOLD: 124 case WPS_TOKEN_REMOTE_HOLD:
115 snprintf(buf, sizeof(buf), "%s", "mode remote hold"); 125 snprintf(buf, sizeof(buf), "mode remote hold");
116 break; 126 break;
117#endif 127#endif
118 128
119 case WPS_TOKEN_REPEAT_MODE: 129 case WPS_TOKEN_REPEAT_MODE:
120 snprintf(buf, sizeof(buf), "%s", "mode repeat"); 130 snprintf(buf, sizeof(buf), "mode repeat");
121 break; 131 break;
122 132
123 case WPS_TOKEN_PLAYBACK_STATUS: 133 case WPS_TOKEN_PLAYBACK_STATUS:
124 snprintf(buf, sizeof(buf), "%s", "mode playback"); 134 snprintf(buf, sizeof(buf), "mode playback");
125 break; 135 break;
126 136
127#if CONFIG_RTC 137#if CONFIG_RTC
138 case WPS_TOKEN_RTC:
139 snprintf(buf, sizeof(buf), "real-time clock",
140 token->value.c);
141 break;
142
128 case WPS_TOKEN_RTC_DAY_OF_MONTH: 143 case WPS_TOKEN_RTC_DAY_OF_MONTH:
129 case WPS_TOKEN_RTC_DAY_OF_MONTH_BLANK_PADDED: 144 case WPS_TOKEN_RTC_DAY_OF_MONTH_BLANK_PADDED:
130 case WPS_TOKEN_RTC_HOUR_24_ZERO_PADDED: 145 case WPS_TOKEN_RTC_HOUR_24_ZERO_PADDED:
@@ -142,199 +157,159 @@ void dump_wps_tokens(struct wps_data *data)
142 case WPS_TOKEN_RTC_MONTH_NAME: 157 case WPS_TOKEN_RTC_MONTH_NAME:
143 case WPS_TOKEN_RTC_DAY_OF_WEEK_START_MON: 158 case WPS_TOKEN_RTC_DAY_OF_WEEK_START_MON:
144 case WPS_TOKEN_RTC_DAY_OF_WEEK_START_SUN: 159 case WPS_TOKEN_RTC_DAY_OF_WEEK_START_SUN:
145 case WPS_TOKEN_RTC: 160 snprintf(buf, sizeof(buf), "real-time clock tag: %c",
146 snprintf(buf, sizeof(buf), "%s %c", "real-time clock tag:", 161 token->value.c);
147 data->tokens[i].value.c);
148 break; 162 break;
149#endif 163#endif
150 164
151#ifdef HAVE_LCD_BITMAP 165#ifdef HAVE_LCD_BITMAP
152 case WPS_TOKEN_IMAGE_BACKDROP: 166 case WPS_TOKEN_IMAGE_BACKDROP:
153 snprintf(buf, sizeof(buf), "%s", "backdrop image"); 167 snprintf(buf, sizeof(buf), "backdrop image");
154 break; 168 break;
155 169
156 case WPS_TOKEN_IMAGE_PROGRESS_BAR: 170 case WPS_TOKEN_IMAGE_PROGRESS_BAR:
157 snprintf(buf, sizeof(buf), "%s", "progressbar bitmap"); 171 snprintf(buf, sizeof(buf), "progressbar bitmap");
158 break;
159
160
161 case WPS_TOKEN_STATUSBAR_ENABLED:
162 snprintf(buf, sizeof(buf), "%s", "statusbar enable");
163 break;
164
165 case WPS_TOKEN_STATUSBAR_DISABLED:
166 snprintf(buf, sizeof(buf), "%s", "statusbar disable");
167 break; 172 break;
168 173
169 case WPS_TOKEN_PEAKMETER: 174 case WPS_TOKEN_PEAKMETER:
170 snprintf(buf, sizeof(buf), "%s", "peakmeter"); 175 snprintf(buf, sizeof(buf), "peakmeter");
171 break; 176 break;
172#endif 177#endif
173 178
174 case WPS_TOKEN_PROGRESSBAR: 179 case WPS_TOKEN_PROGRESSBAR:
175 snprintf(buf, sizeof(buf), "%s", "progressbar"); 180 snprintf(buf, sizeof(buf), "progressbar");
176 break; 181 break;
177 182
178#ifdef HAVE_LCD_CHARCELLS 183#ifdef HAVE_LCD_CHARCELLS
179 case WPS_TOKEN_PLAYER_PROGRESSBAR: 184 case WPS_TOKEN_PLAYER_PROGRESSBAR:
180 snprintf(buf, sizeof(buf), "%s", "full line progressbar"); 185 snprintf(buf, sizeof(buf), "full line progressbar");
181 break; 186 break;
182#endif 187#endif
183 188
184 case WPS_TOKEN_TRACK_TIME_ELAPSED: 189 case WPS_TOKEN_TRACK_TIME_ELAPSED:
185 snprintf(buf, sizeof(buf), "%s", "time elapsed in track"); 190 snprintf(buf, sizeof(buf), "time elapsed in track");
186 break; 191 break;
187 192
188 case WPS_TOKEN_PLAYLIST_ENTRIES: 193 case WPS_TOKEN_PLAYLIST_ENTRIES:
189 snprintf(buf, sizeof(buf), "%s", "number of entries in playlist"); 194 snprintf(buf, sizeof(buf), "number of entries in playlist");
190 break; 195 break;
191 196
192 case WPS_TOKEN_PLAYLIST_NAME: 197 case WPS_TOKEN_PLAYLIST_NAME:
193 snprintf(buf, sizeof(buf), "%s", "playlist name"); 198 snprintf(buf, sizeof(buf), "playlist name");
194 break; 199 break;
195 200
196 case WPS_TOKEN_PLAYLIST_POSITION: 201 case WPS_TOKEN_PLAYLIST_POSITION:
197 snprintf(buf, sizeof(buf), "%s", "position in playlist"); 202 snprintf(buf, sizeof(buf), "position in playlist");
198 break; 203 break;
199 204
200 case WPS_TOKEN_TRACK_TIME_REMAINING: 205 case WPS_TOKEN_TRACK_TIME_REMAINING:
201 snprintf(buf, sizeof(buf), "%s", "time remaining in track"); 206 snprintf(buf, sizeof(buf), "time remaining in track");
202 break; 207 break;
203 208
204 case WPS_TOKEN_PLAYLIST_SHUFFLE: 209 case WPS_TOKEN_PLAYLIST_SHUFFLE:
205 snprintf(buf, sizeof(buf), "%s", "playlist shuffle mode"); 210 snprintf(buf, sizeof(buf), "playlist shuffle mode");
206 break; 211 break;
207 212
208 case WPS_TOKEN_TRACK_LENGTH: 213 case WPS_TOKEN_TRACK_LENGTH:
209 snprintf(buf, sizeof(buf), "%s", "track length"); 214 snprintf(buf, sizeof(buf), "track length");
210 break; 215 break;
211 216
212 case WPS_TOKEN_VOLUME: 217 case WPS_TOKEN_VOLUME:
213 snprintf(buf, sizeof(buf), "%s", "volume"); 218 snprintf(buf, sizeof(buf), "volume");
214 break; 219 break;
215 220
216 case WPS_TOKEN_METADATA_ARTIST: 221 case WPS_TOKEN_METADATA_ARTIST:
217 snprintf(buf, sizeof(buf), "%s%s", next ? "next " : "", 222 snprintf(buf, sizeof(buf), "%strack artist", next_str(next));
218 "track artist");
219 break; 223 break;
220 224
221 case WPS_TOKEN_METADATA_COMPOSER: 225 case WPS_TOKEN_METADATA_COMPOSER:
222 snprintf(buf, sizeof(buf), "%s%s", next ? "next " : "", 226 snprintf(buf, sizeof(buf), "%strack composer", next_str(next));
223 "track composer");
224 break; 227 break;
225 228
226 case WPS_TOKEN_METADATA_ALBUM: 229 case WPS_TOKEN_METADATA_ALBUM:
227 snprintf(buf, sizeof(buf), "%s%s", next ? "next " : "", 230 snprintf(buf, sizeof(buf), "%strack album", next_str(next));
228 "track album");
229 break; 231 break;
230 232
231 case WPS_TOKEN_METADATA_GENRE: 233 case WPS_TOKEN_METADATA_GENRE:
232 snprintf(buf, sizeof(buf), "%s%s", next ? "next " : "", 234 snprintf(buf, sizeof(buf), "%strack genre", next_str(next));
233 "track genre");
234 break; 235 break;
235 236
236 case WPS_TOKEN_METADATA_TRACK_NUMBER: 237 case WPS_TOKEN_METADATA_TRACK_NUMBER:
237 snprintf(buf, sizeof(buf), "%s%s", next ? "next " : "", 238 snprintf(buf, sizeof(buf), "%strack number", next_str(next));
238 "track number");
239 break; 239 break;
240 240
241 case WPS_TOKEN_METADATA_TRACK_TITLE: 241 case WPS_TOKEN_METADATA_TRACK_TITLE:
242 snprintf(buf, sizeof(buf), "%s%s", next ? "next " : "", 242 snprintf(buf, sizeof(buf), "%strack title", next_str(next));
243 "track title");
244 break; 243 break;
245 244
246 case WPS_TOKEN_METADATA_VERSION: 245 case WPS_TOKEN_METADATA_VERSION:
247 snprintf(buf, sizeof(buf), "%s%s", next ? "next " : "", 246 snprintf(buf, sizeof(buf), "%strack ID3 version", next_str(next));
248 "track ID3 version");
249 break; 247 break;
250 248
251 case WPS_TOKEN_METADATA_YEAR: 249 case WPS_TOKEN_METADATA_YEAR:
252 snprintf(buf, sizeof(buf), "%s%s", next ? "next " : "", 250 snprintf(buf, sizeof(buf), "%strack year", next_str(next));
253 "track year");
254 break; 251 break;
255 252
256 case WPS_TOKEN_BATTERY_PERCENT: 253 case WPS_TOKEN_BATTERY_PERCENT:
257 snprintf(buf, sizeof(buf), "%s", "battery percentage"); 254 snprintf(buf, sizeof(buf), "battery percentage");
258 break; 255 break;
259 256
260 case WPS_TOKEN_BATTERY_VOLTS: 257 case WPS_TOKEN_BATTERY_VOLTS:
261 snprintf(buf, sizeof(buf), "%s", "battery voltage"); 258 snprintf(buf, sizeof(buf), "battery voltage");
262 break; 259 break;
263 260
264 case WPS_TOKEN_BATTERY_TIME: 261 case WPS_TOKEN_BATTERY_TIME:
265 snprintf(buf, sizeof(buf), "%s", "battery time left"); 262 snprintf(buf, sizeof(buf), "battery time left");
266 break; 263 break;
267 264
268 case WPS_TOKEN_BATTERY_CHARGER_CONNECTED: 265 case WPS_TOKEN_BATTERY_CHARGER_CONNECTED:
269 snprintf(buf, sizeof(buf), "%s", "battery charger connected"); 266 snprintf(buf, sizeof(buf), "battery charger connected");
270 break; 267 break;
271 268
272 case WPS_TOKEN_BATTERY_CHARGING: 269 case WPS_TOKEN_BATTERY_CHARGING:
273 snprintf(buf, sizeof(buf), "%s", "battery charging"); 270 snprintf(buf, sizeof(buf), "battery charging");
274 break; 271 break;
275 272
276 case WPS_TOKEN_FILE_BITRATE: 273 case WPS_TOKEN_FILE_BITRATE:
277 snprintf(buf, sizeof(buf), "%s%s", next ? "next " : "", 274 snprintf(buf, sizeof(buf), "%sfile bitrate", next_str(next));
278 "file bitrate");
279 break; 275 break;
280 276
281 case WPS_TOKEN_FILE_CODEC: 277 case WPS_TOKEN_FILE_CODEC:
282 snprintf(buf, sizeof(buf), "%s%s", next ? "next " : "", 278 snprintf(buf, sizeof(buf), "%sfile codec", next_str(next));
283 "file codec");
284 break; 279 break;
285 280
286 case WPS_TOKEN_FILE_FREQUENCY: 281 case WPS_TOKEN_FILE_FREQUENCY:
287 snprintf(buf, sizeof(buf), "%s%s", next ? "next " : "", 282 snprintf(buf, sizeof(buf), "%sfile audio frequency", next_str(next));
288 "file audio frequency");
289 break; 283 break;
290 284
291 case WPS_TOKEN_FILE_NAME: 285 case WPS_TOKEN_FILE_NAME:
292 snprintf(buf, sizeof(buf), "%s%s", next ? "next " : "", 286 snprintf(buf, sizeof(buf), "%sfile name", next_str(next));
293 "file name");
294 break; 287 break;
295 288
296 case WPS_TOKEN_FILE_NAME_WITH_EXTENSION: 289 case WPS_TOKEN_FILE_NAME_WITH_EXTENSION:
297 snprintf(buf, sizeof(buf), "%s%s", next ? "next " : "", 290 snprintf(buf, sizeof(buf), "%sfile name with extension", next_str(next));
298 "file name with extension");
299 break; 291 break;
300 292
301 case WPS_TOKEN_FILE_PATH: 293 case WPS_TOKEN_FILE_PATH:
302 snprintf(buf, sizeof(buf), "%s%s", next ? "next " : "", 294 snprintf(buf, sizeof(buf), "%sfile path", next_str(next));
303 "file path");
304 break; 295 break;
305 296
306 case WPS_TOKEN_FILE_SIZE: 297 case WPS_TOKEN_FILE_SIZE:
307 snprintf(buf, sizeof(buf), "%s%s", next ? "next " : "", 298 snprintf(buf, sizeof(buf), "%sfile size", next_str(next));
308 "file size");
309 break; 299 break;
310 300
311 case WPS_TOKEN_FILE_VBR: 301 case WPS_TOKEN_FILE_VBR:
312 snprintf(buf, sizeof(buf), "%s%s", next ? "next " : "", 302 snprintf(buf, sizeof(buf), "%sfile is vbr", next_str(next));
313 "file is vbr");
314 break; 303 break;
315 304
316 case WPS_TOKEN_FILE_DIRECTORY: 305 case WPS_TOKEN_FILE_DIRECTORY:
317 snprintf(buf, sizeof(buf), "%s%s: %d", next ? "next " : "", 306 snprintf(buf, sizeof(buf), "%sfile directory, level: %d", next_str(next),
318 "file directory, level", 307 token->value.i);
319 data->tokens[i].value.i);
320 break;
321
322 case WPS_TOKEN_SCROLL:
323 snprintf(buf, sizeof(buf), "%s", "scrolling line");
324 break;
325
326 case WPS_TOKEN_SUBLINE_TIMEOUT:
327 snprintf(buf, sizeof(buf), "%s: %d", "subline timeout value",
328 data->tokens[i].value.i);
329 break;
330
331 case WPS_TOKEN_SUBLINE_SEPARATOR:
332 snprintf(buf, sizeof(buf), "%s", "subline separator");
333 break; 308 break;
334 309
335 default: 310 default:
336 snprintf(buf, sizeof(buf), "%s (code: %d)", "FIXME", 311 snprintf(buf, sizeof(buf), "FIXME (code: %d)",
337 data->tokens[i].type); 312 token->type);
338 break; 313 break;
339 } 314 }
340 315
@@ -342,24 +317,43 @@ void dump_wps_tokens(struct wps_data *data)
342 DEBUGF("\t"); 317 DEBUGF("\t");
343 } 318 }
344 319
345 DEBUGF("[%03d] = %s\n", i, buf); 320 DEBUGF("[%3d] = (%2d) %s\n", i, token->type, buf);
346 } 321 }
347 DEBUGF("\n"); 322 DEBUGF("\n");
348} 323}
349 324
350void print_line_info(struct wps_data *data) 325void print_line_info(struct wps_data *data)
351{ 326{
352 int line, subline; 327 int i, j;
328 struct wps_line *line;
329 struct wps_subline *subline;
353 330
354 DEBUGF("line/subline start indexes :\n"); 331 DEBUGF("Number of lines : %d\n", data->num_lines);
355 for (line = 0; line < data->num_lines; line++) 332 DEBUGF("Number of sublines: %d\n", data->num_sublines);
333 DEBUGF("Number of tokens : %d\n", data->num_tokens);
334 DEBUGF("\n");
335
336 for (i = 0, line = data->lines; i < data->num_lines; i++,line++)
356 { 337 {
357 DEBUGF("%2d. ", line); 338 DEBUGF("Line %2d (num_sublines=%d, first_subline=%d)\n",
358 for (subline = 0; subline < data->num_sublines[line]; subline++) 339 i, line->num_sublines, line->first_subline_idx);
340
341 for (j = 0, subline = data->sublines + line->first_subline_idx;
342 j < line->num_sublines; j++, subline++)
359 { 343 {
360 DEBUGF("%3d ", data->format_lines[line][subline]); 344 DEBUGF(" Subline %d: first_token=%3d, last_token=%3d",
345 j, subline->first_token_idx,
346 wps_last_token_index(data, i, j));
347
348 if (subline->line_type & WPS_REFRESH_SCROLL)
349 DEBUGF(", scrolled");
350 else if (subline->line_type & WPS_REFRESH_PLAYER_PROGRESS)
351 DEBUGF(", progressbar");
352 else if (subline->line_type & WPS_REFRESH_PEAK_METER)
353 DEBUGF(", peakmeter");
354
355 DEBUGF("\n");
361 } 356 }
362 DEBUGF("\n");
363 } 357 }
364 358
365 DEBUGF("\n"); 359 DEBUGF("\n");
@@ -367,21 +361,21 @@ void print_line_info(struct wps_data *data)
367 361
368void print_wps_strings(struct wps_data *data) 362void print_wps_strings(struct wps_data *data)
369{ 363{
370 DEBUGF("strings :\n"); 364 DEBUGF("Strings:\n");
371 int i, len = 0; 365 int i, len = 0;
372 for (i=0; i < data->num_strings; i++) 366 for (i=0; i < data->num_strings; i++)
373 { 367 {
374 len += strlen(data->strings[i]); 368 len += strlen(data->strings[i]);
375 DEBUGF("%2d: '%s'\n", i, data->strings[i]); 369 DEBUGF("%2d: '%s'\n", i, data->strings[i]);
376 } 370 }
377 DEBUGF("total length : %d\n", len); 371 DEBUGF("Total length: %d\n", len);
378 DEBUGF("\n"); 372 DEBUGF("\n");
379} 373}
380 374
381#ifdef HAVE_LCD_BITMAP 375#ifdef HAVE_LCD_BITMAP
382void print_img_cond_indexes(struct wps_data *data) 376void print_img_cond_indexes(struct wps_data *data)
383{ 377{
384 DEBUGF("image conditional indexes :\n"); 378 DEBUGF("Image conditional indexes:\n");
385 int i; 379 int i;
386 for (i=0; i < MAX_IMAGES; i++) 380 for (i=0; i < MAX_IMAGES; i++)
387 { 381 {
diff --git a/apps/gui/wps_parser.c b/apps/gui/wps_parser.c
index 2a610bdb8c..65f33447fc 100644
--- a/apps/gui/wps_parser.c
+++ b/apps/gui/wps_parser.c
@@ -69,10 +69,18 @@ extern void print_img_cond_indexes(struct wps_data *data);
69extern void print_wps_strings(struct wps_data *data); 69extern void print_wps_strings(struct wps_data *data);
70#endif 70#endif
71 71
72/* special parsing function. 72/* Function for parsing of details for a token. At the moment the
73 wps_bufptr points to the char following the tag. 73 function is called, the token type has already been set. The
74 The return value is the number of chars read. */ 74 function must fill in the details and possibly add more tokens
75typedef int (*wps_tag_parse_func)(const char *wps_bufptr, struct wps_data *wps_data); 75 to the token array. It should return the number of chars that
76 has been consumed.
77
78 wps_bufptr points to the char following the tag (i.e. where
79 details begin).
80 token is the pointer to the 'main' token being parsed
81 */
82typedef int (*wps_tag_parse_func)(const char *wps_bufptr,
83 struct wps_token *token, struct wps_data *wps_data);
76 84
77struct wps_tag { 85struct wps_tag {
78 enum wps_token_type type; 86 enum wps_token_type type;
@@ -82,17 +90,27 @@ struct wps_tag {
82}; 90};
83 91
84/* prototypes of all special parse functions : */ 92/* prototypes of all special parse functions : */
85static int parse_subline_timeout(const char *wps_bufptr, struct wps_data *wps_data); 93static int parse_subline_timeout(const char *wps_bufptr,
86static int parse_progressbar(const char *wps_bufptr, struct wps_data *wps_data); 94 struct wps_token *token, struct wps_data *wps_data);
87static int parse_dir_level(const char *wps_bufptr, struct wps_data *wps_data); 95static int parse_progressbar(const char *wps_bufptr,
96 struct wps_token *token, struct wps_data *wps_data);
97static int parse_dir_level(const char *wps_bufptr,
98 struct wps_token *token, struct wps_data *wps_data);
88#ifdef HAVE_LCD_BITMAP 99#ifdef HAVE_LCD_BITMAP
89static int parse_image_special(const char *wps_bufptr, struct wps_data *wps_data); 100static int parse_image_special(const char *wps_bufptr,
90static int parse_statusbar(const char *wps_bufptr, struct wps_data *wps_data); 101 struct wps_token *token, struct wps_data *wps_data);
91static int parse_image_display(const char *wps_bufptr, struct wps_data *wps_data); 102static int parse_statusbar_enable(const char *wps_bufptr,
92static int parse_image_load(const char *wps_bufptr, struct wps_data *wps_data); 103 struct wps_token *token, struct wps_data *wps_data);
104static int parse_statusbar_disable(const char *wps_bufptr,
105 struct wps_token *token, struct wps_data *wps_data);
106static int parse_image_display(const char *wps_bufptr,
107 struct wps_token *token, struct wps_data *wps_data);
108static int parse_image_load(const char *wps_bufptr,
109 struct wps_token *token, struct wps_data *wps_data);
93#endif /*HAVE_LCD_BITMAP */ 110#endif /*HAVE_LCD_BITMAP */
94#if CONFIG_RTC 111#if CONFIG_RTC
95static int parse_rtc_format(const char *wps_bufptr, struct wps_data *wps_data); 112static int parse_rtc_format(const char *wps_bufptr,
113 struct wps_token *token, struct wps_data *wps_data);
96 114
97/* RTC tokens array */ 115/* RTC tokens array */
98static const struct wps_tag rtc_tags[] = { 116static const struct wps_tag rtc_tags[] = {
@@ -113,8 +131,8 @@ static const struct wps_tag rtc_tags[] = {
113 { WPS_TOKEN_RTC_MONTH_NAME, "b", 0, NULL }, 131 { WPS_TOKEN_RTC_MONTH_NAME, "b", 0, NULL },
114 { WPS_TOKEN_RTC_DAY_OF_WEEK_START_MON, "u", 0, NULL }, 132 { WPS_TOKEN_RTC_DAY_OF_WEEK_START_MON, "u", 0, NULL },
115 { WPS_TOKEN_RTC_DAY_OF_WEEK_START_SUN, "w", 0, NULL }, 133 { WPS_TOKEN_RTC_DAY_OF_WEEK_START_SUN, "w", 0, NULL },
116 { WPS_TOKEN_CHARACTER, "\0",0, NULL } 134 { WPS_TOKEN_CHARACTER, "", 0, NULL }
117 /* the array MUST end with a "\0" token */ 135 /* the array MUST end with an empty string (first char is \0) */
118}; 136};
119#endif 137#endif
120 138
@@ -229,29 +247,30 @@ static const struct wps_tag all_tags[] = {
229 { WPS_TOKEN_REPLAYGAIN, "rg", WPS_REFRESH_STATIC, NULL }, 247 { WPS_TOKEN_REPLAYGAIN, "rg", WPS_REFRESH_STATIC, NULL },
230#endif 248#endif
231 249
232 { WPS_TOKEN_SCROLL, "s", WPS_REFRESH_SCROLL, NULL }, 250 { WPS_NO_TOKEN, "s", WPS_REFRESH_SCROLL, NULL },
233 { WPS_TOKEN_SUBLINE_TIMEOUT, "t", 0, parse_subline_timeout }, 251 { WPS_TOKEN_SUBLINE_TIMEOUT, "t", 0, parse_subline_timeout },
234 252
235#ifdef HAVE_LCD_BITMAP 253#ifdef HAVE_LCD_BITMAP
236 { WPS_TOKEN_STATUSBAR_ENABLED, "we", 0, parse_statusbar }, 254 { WPS_NO_TOKEN, "we", 0, parse_statusbar_enable },
237 { WPS_TOKEN_STATUSBAR_DISABLED, "wd", 0, parse_statusbar }, 255 { WPS_NO_TOKEN, "wd", 0, parse_statusbar_disable },
238 256
239 { WPS_NO_TOKEN, "xl", 0, parse_image_load }, 257 { WPS_NO_TOKEN, "xl", 0, parse_image_load },
240 258
241 { WPS_TOKEN_IMAGE_PRELOAD_DISPLAY, "xd", WPS_REFRESH_STATIC, parse_image_display }, 259 { WPS_TOKEN_IMAGE_PRELOAD_DISPLAY, "xd", WPS_REFRESH_STATIC, parse_image_display },
242 260
243 { WPS_TOKEN_IMAGE_DISPLAY, "x", 0, parse_image_load }, 261 { WPS_TOKEN_IMAGE_DISPLAY, "x", 0, parse_image_load },
244 { WPS_TOKEN_IMAGE_PROGRESS_BAR, "P", 0, parse_image_special }, 262 { WPS_TOKEN_IMAGE_PROGRESS_BAR, "P", 0, parse_image_special },
245#if LCD_DEPTH > 1 263#if LCD_DEPTH > 1
246 { WPS_TOKEN_IMAGE_BACKDROP, "X", 0, parse_image_special }, 264 { WPS_TOKEN_IMAGE_BACKDROP, "X", 0, parse_image_special },
247#endif 265#endif
248#endif 266#endif
249 267
250 { WPS_TOKEN_UNKNOWN, "\0", 0, NULL } 268 { WPS_TOKEN_UNKNOWN, "", 0, NULL }
251 /* the array MUST end with a "\0" token */ 269 /* the array MUST end with an empty string (first char is \0) */
252}; 270};
253 271
254 272/* Returns the number of chars that should be skipped to jump
273 immediately after the first eol, i.e. to the start of the next line */
255static int skip_end_of_line(const char *wps_bufptr) 274static int skip_end_of_line(const char *wps_bufptr)
256{ 275{
257 int skip = 0; 276 int skip = 0;
@@ -260,10 +279,20 @@ static int skip_end_of_line(const char *wps_bufptr)
260 return ++skip; 279 return ++skip;
261} 280}
262 281
282/* Starts a new subline in the current line during parsing */
283static void wps_start_new_subline(struct wps_data *data) {
284 data->num_sublines++;
285 data->sublines[data->num_sublines].first_token_idx = data->num_tokens;
286 data->lines[data->num_lines].num_sublines++;
287}
288
263#if CONFIG_RTC 289#if CONFIG_RTC
264static int parse_rtc_format(const char *wps_bufptr, struct wps_data *wps_data) 290static int parse_rtc_format(const char *wps_bufptr,
291 struct wps_token *token,
292 struct wps_data *wps_data)
265{ 293{
266 int skip = 0, i; 294 int skip = 0, i;
295 (void)token; /* kill the warning */
267 296
268 /* RTC tag format ends with a c or a newline */ 297 /* RTC tag format ends with a c or a newline */
269 while (wps_bufptr && *wps_bufptr != 'c' && *wps_bufptr != '\n') 298 while (wps_bufptr && *wps_bufptr != 'c' && *wps_bufptr != '\n')
@@ -276,7 +305,7 @@ static int parse_rtc_format(const char *wps_bufptr, struct wps_data *wps_data)
276 wps_data->num_tokens++; 305 wps_data->num_tokens++;
277 wps_data->tokens[wps_data->num_tokens].type = rtc_tags[i].type; 306 wps_data->tokens[wps_data->num_tokens].type = rtc_tags[i].type;
278 wps_data->tokens[wps_data->num_tokens].value.c = *wps_bufptr; 307 wps_data->tokens[wps_data->num_tokens].value.c = *wps_bufptr;
279 skip ++; 308 skip++;
280 wps_bufptr++; 309 wps_bufptr++;
281 } 310 }
282 311
@@ -290,16 +319,23 @@ static int parse_rtc_format(const char *wps_bufptr, struct wps_data *wps_data)
290 319
291#ifdef HAVE_LCD_BITMAP 320#ifdef HAVE_LCD_BITMAP
292 321
293static int parse_statusbar(const char *wps_bufptr, struct wps_data *wps_data) 322static int parse_statusbar_enable(const char *wps_bufptr,
323 struct wps_token *token,
324 struct wps_data *wps_data)
294{ 325{
326 (void)token; /* Kill warnings */
295 wps_data->wps_sb_tag = true; 327 wps_data->wps_sb_tag = true;
328 wps_data->show_sb_on_wps = true;
329 return skip_end_of_line(wps_bufptr);
330}
296 331
297 if (wps_data->tokens[wps_data->num_tokens].type == WPS_TOKEN_STATUSBAR_ENABLED) 332static int parse_statusbar_disable(const char *wps_bufptr,
298 wps_data->show_sb_on_wps = true; 333 struct wps_token *token,
299 else 334 struct wps_data *wps_data)
300 wps_data->show_sb_on_wps = false; 335{
301 336 (void)token; /* Kill warnings */
302 /* Skip the rest of the line */ 337 wps_data->wps_sb_tag = true;
338 wps_data->show_sb_on_wps = false;
303 return skip_end_of_line(wps_bufptr); 339 return skip_end_of_line(wps_bufptr);
304} 340}
305 341
@@ -357,10 +393,12 @@ static char *get_image_filename(const char *start, const char* bmpdir,
357 return buf; 393 return buf;
358} 394}
359 395
360static int parse_image_display(const char *wps_bufptr, struct wps_data *wps_data) 396static int parse_image_display(const char *wps_bufptr,
397 struct wps_token *token,
398 struct wps_data *wps_data)
361{ 399{
362 int n = get_image_id(*wps_bufptr); 400 int n = get_image_id(*wps_bufptr);
363 wps_data->tokens[wps_data->num_tokens].value.i = n; 401 token->value.i = n;
364 402
365 /* if the image is in a conditional, remember it */ 403 /* if the image is in a conditional, remember it */
366 if (level >= 0) 404 if (level >= 0)
@@ -369,7 +407,9 @@ static int parse_image_display(const char *wps_bufptr, struct wps_data *wps_data
369 return 1; 407 return 1;
370} 408}
371 409
372static int parse_image_load(const char *wps_bufptr, struct wps_data *wps_data) 410static int parse_image_load(const char *wps_bufptr,
411 struct wps_token *token,
412 struct wps_data *wps_data)
373{ 413{
374 int n; 414 int n;
375 const char *ptr = wps_bufptr; 415 const char *ptr = wps_bufptr;
@@ -421,7 +461,7 @@ static int parse_image_load(const char *wps_bufptr, struct wps_data *wps_data)
421 return skip_end_of_line(wps_bufptr); 461 return skip_end_of_line(wps_bufptr);
422 } 462 }
423 463
424 if (wps_data->tokens[wps_data->num_tokens].type == WPS_TOKEN_IMAGE_DISPLAY) 464 if (token->type == WPS_TOKEN_IMAGE_DISPLAY)
425 wps_data->img[n].always_display = true; 465 wps_data->img[n].always_display = true;
426 } 466 }
427 467
@@ -429,15 +469,17 @@ static int parse_image_load(const char *wps_bufptr, struct wps_data *wps_data)
429 return skip_end_of_line(wps_bufptr); 469 return skip_end_of_line(wps_bufptr);
430} 470}
431 471
432static int parse_image_special(const char *wps_bufptr, struct wps_data *wps_data) 472static int parse_image_special(const char *wps_bufptr,
473 struct wps_token *token,
474 struct wps_data *wps_data)
433{ 475{
434 if (wps_data->tokens[wps_data->num_tokens].type == WPS_TOKEN_IMAGE_PROGRESS_BAR) 476 if (token->type == WPS_TOKEN_IMAGE_PROGRESS_BAR)
435 { 477 {
436 /* format: %P|filename.bmp| */ 478 /* format: %P|filename.bmp| */
437 pb_bmp_name = wps_bufptr + 1; 479 pb_bmp_name = wps_bufptr + 1;
438 } 480 }
439#if LCD_DEPTH > 1 481#if LCD_DEPTH > 1
440 else if (wps_data->tokens[wps_data->num_tokens].type == WPS_TOKEN_IMAGE_BACKDROP) 482 else if (token->type == WPS_TOKEN_IMAGE_BACKDROP)
441 { 483 {
442 /* format: %X|filename.bmp| */ 484 /* format: %X|filename.bmp| */
443 backdrop_bmp_name = wps_bufptr + 1; 485 backdrop_bmp_name = wps_bufptr + 1;
@@ -452,20 +494,27 @@ static int parse_image_special(const char *wps_bufptr, struct wps_data *wps_data
452 494
453#endif /* HAVE_LCD_BITMAP */ 495#endif /* HAVE_LCD_BITMAP */
454 496
455static int parse_dir_level(const char *wps_bufptr, struct wps_data *wps_data) 497static int parse_dir_level(const char *wps_bufptr,
498 struct wps_token *token,
499 struct wps_data *wps_data)
456{ 500{
457 char val[] = { *wps_bufptr, '\0' }; 501 char val[] = { *wps_bufptr, '\0' };
458 wps_data->tokens[wps_data->num_tokens].value.i = atoi(val); 502 token->value.i = atoi(val);
503 (void)wps_data; /* Kill warnings */
459 return 1; 504 return 1;
460} 505}
461 506
462static int parse_subline_timeout(const char *wps_bufptr, struct wps_data *wps_data) 507static int parse_subline_timeout(const char *wps_bufptr,
508 struct wps_token *token,
509 struct wps_data *wps_data)
463{ 510{
464 int skip = 0; 511 int skip = 0;
465 int val = 0; 512 int val = 0;
466 bool have_point = false; 513 bool have_point = false;
467 bool have_tenth = false; 514 bool have_tenth = false;
468 515
516 (void)wps_data; /* Kill the warning */
517
469 while ( isdigit(*wps_bufptr) || *wps_bufptr == '.' ) 518 while ( isdigit(*wps_bufptr) || *wps_bufptr == '.' )
470 { 519 {
471 if (*wps_bufptr != '.') 520 if (*wps_bufptr != '.')
@@ -490,13 +539,16 @@ static int parse_subline_timeout(const char *wps_bufptr, struct wps_data *wps_da
490 if (have_tenth == false) 539 if (have_tenth == false)
491 val *= 10; 540 val *= 10;
492 541
493 wps_data->tokens[wps_data->num_tokens].value.i = val; 542 token->value.i = val;
494 543
495 return skip; 544 return skip;
496} 545}
497 546
498static int parse_progressbar(const char *wps_bufptr, struct wps_data *wps_data) 547static int parse_progressbar(const char *wps_bufptr,
548 struct wps_token *token,
549 struct wps_data *wps_data)
499{ 550{
551 (void)token; /* Kill warnings */
500#ifdef HAVE_LCD_BITMAP 552#ifdef HAVE_LCD_BITMAP
501 553
502 short *vals[] = { 554 short *vals[] = {
@@ -547,9 +599,8 @@ static int parse_progressbar(const char *wps_bufptr, struct wps_data *wps_data)
547static int parse_token(const char *wps_bufptr, struct wps_data *wps_data) 599static int parse_token(const char *wps_bufptr, struct wps_data *wps_data)
548{ 600{
549 int skip = 0, taglen = 0; 601 int skip = 0, taglen = 0;
550 int i = 0; 602 struct wps_token *token = wps_data->tokens + wps_data->num_tokens;
551 int line = wps_data->num_lines; 603 const struct wps_tag *tag;
552 int subline = wps_data->num_sublines[line];
553 604
554 switch(*wps_bufptr) 605 switch(*wps_bufptr)
555 { 606 {
@@ -560,47 +611,47 @@ static int parse_token(const char *wps_bufptr, struct wps_data *wps_data)
560 case '>': 611 case '>':
561 case ';': 612 case ';':
562 /* escaped characters */ 613 /* escaped characters */
563 wps_data->tokens[wps_data->num_tokens].type = WPS_TOKEN_CHARACTER; 614 token->type = WPS_TOKEN_CHARACTER;
564 wps_data->tokens[wps_data->num_tokens].value.c = *wps_bufptr; 615 token->value.c = *wps_bufptr;
565 wps_data->num_tokens++; 616 wps_data->num_tokens++;
566 skip++; 617 skip++;
567 break; 618 break;
568 619
569 case '?': 620 case '?':
570 /* conditional tag */ 621 /* conditional tag */
571 wps_data->tokens[wps_data->num_tokens].type = WPS_TOKEN_CONDITIONAL; 622 token->type = WPS_TOKEN_CONDITIONAL;
572 level++; 623 level++;
573 condindex[level] = wps_data->num_tokens; 624 condindex[level] = wps_data->num_tokens;
574 numoptions[level] = 1; 625 numoptions[level] = 1;
575 wps_data->num_tokens++; 626 wps_data->num_tokens++;
627 token++;
576 wps_bufptr++; 628 wps_bufptr++;
577 skip++; 629 skip++;
578 /* no "break" because a '?' is followed by a regular tag */ 630 /* no "break" because a '?' is followed by a regular tag */
579 631
580 default: 632 default:
581 /* find what tag we have */ 633 /* find what tag we have */
582 while (all_tags[i].name && 634 for (tag = all_tags;
583 strncmp(wps_bufptr, all_tags[i].name, strlen(all_tags[i].name))) 635 strncmp(wps_bufptr, tag->name, strlen(tag->name)) != 0;
584 i++; 636 tag++) ;
585 637
586 taglen = strlen(all_tags[i].name); 638 taglen = strlen(tag->name);
587 skip += taglen; 639 skip += taglen;
588 wps_data->tokens[wps_data->num_tokens].type = all_tags[i].type; 640 token->type = tag->type;
641 wps_data->sublines[wps_data->num_sublines].line_type |= tag->refresh_type;
589 642
590 /* if the tag has a special parsing function, we call it */ 643 /* if the tag has a special parsing function, we call it */
591 if (all_tags[i].parse_func) 644 if (tag->parse_func)
592 skip += all_tags[i].parse_func(wps_bufptr + taglen, wps_data); 645 skip += tag->parse_func(wps_bufptr + taglen, token, wps_data);
593 646
594 /* Some tags we don't want to save as tokens */ 647 /* Some tags we don't want to save as tokens */
595 if (all_tags[i].type == WPS_NO_TOKEN) 648 if (tag->type == WPS_NO_TOKEN)
596 break; 649 break;
597 650
598 /* tags that start with 'F', 'I' or 'D' are for the next file */ 651 /* tags that start with 'F', 'I' or 'D' are for the next file */
599 if ( *(all_tags[i].name) == 'I' || *(all_tags[i].name) == 'F' 652 if ( *(tag->name) == 'I' || *(tag->name) == 'F' || *(tag->name) == 'D')
600 || *(all_tags[i].name) == 'D') 653 token->next = true;
601 wps_data->tokens[wps_data->num_tokens].next = true;
602 654
603 wps_data->line_type[line][subline] |= all_tags[i].refresh_type;
604 wps_data->num_tokens++; 655 wps_data->num_tokens++;
605 break; 656 break;
606 } 657 }
@@ -608,17 +659,19 @@ static int parse_token(const char *wps_bufptr, struct wps_data *wps_data)
608 return skip; 659 return skip;
609} 660}
610 661
662/* Parses the WPS.
663 data is the pointer to the structure where the parsed WPS should be stored.
664 It is initialised.
665 wps_bufptr points to the string containing the WPS tags */
611static bool wps_parse(struct wps_data *data, const char *wps_bufptr) 666static bool wps_parse(struct wps_data *data, const char *wps_bufptr)
612{ 667{
613 if (!data || !wps_bufptr || !*wps_bufptr) 668 if (!data || !wps_bufptr || !*wps_bufptr)
614 return false; 669 return false;
615 670
616 int subline;
617 data->num_tokens = 0;
618 char *current_string = data->string_buffer; 671 char *current_string = data->string_buffer;
619 672
620 while(wps_bufptr && *wps_bufptr && data->num_tokens < WPS_MAX_TOKENS 673 while(*wps_bufptr && data->num_tokens < WPS_MAX_TOKENS - 1
621 && data->num_lines < WPS_MAX_LINES) 674 && data->num_lines < WPS_MAX_LINES)
622 { 675 {
623 switch(*wps_bufptr++) 676 switch(*wps_bufptr++)
624 { 677 {
@@ -630,12 +683,8 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr)
630 683
631 /* Alternating sublines separator */ 684 /* Alternating sublines separator */
632 case ';': 685 case ';':
633 if (data->num_sublines[data->num_lines]+1 < WPS_MAX_SUBLINES) 686 if (data->num_sublines+1 < WPS_MAX_SUBLINES)
634 { 687 wps_start_new_subline(data);
635 data->tokens[data->num_tokens++].type = WPS_TOKEN_SUBLINE_SEPARATOR;
636 subline = ++(data->num_sublines[data->num_lines]);
637 data->format_lines[data->num_lines][subline] = data->num_tokens;
638 }
639 else 688 else
640 wps_bufptr += skip_end_of_line(wps_bufptr); 689 wps_bufptr += skip_end_of_line(wps_bufptr);
641 690
@@ -694,13 +743,14 @@ condlistend: /* close a conditional. sometimes we want to close them even when
694 goto condlistend; 743 goto condlistend;
695 break; 744 break;
696 } 745 }
697 data->tokens[data->num_tokens++].type = WPS_TOKEN_EOL; 746 wps_start_new_subline(data);
698 (data->num_sublines[data->num_lines])++; 747 data->num_lines++; /* Start a new line */
699 data->num_lines++;
700 748
701 if (data->num_lines < WPS_MAX_LINES) 749 if ((data->num_lines < WPS_MAX_LINES) &&
750 (data->num_sublines < WPS_MAX_SUBLINES))
702 { 751 {
703 data->format_lines[data->num_lines][0] = data->num_tokens; 752 data->lines[data->num_lines].first_subline_idx = data->num_sublines;
753 data->sublines[data->num_sublines].first_token_idx = data->num_tokens;
704 } 754 }
705 755
706 break; 756 break;
@@ -777,8 +827,7 @@ void wps_data_init(struct wps_data *wps_data)
777 wps_data->img_buf_free = IMG_BUFSIZE; /* free space in image buffer */ 827 wps_data->img_buf_free = IMG_BUFSIZE; /* free space in image buffer */
778 wps_data->peak_meter_enabled = false; 828 wps_data->peak_meter_enabled = false;
779#else /* HAVE_LCD_CHARCELLS */ 829#else /* HAVE_LCD_CHARCELLS */
780 int i; 830 for (i = 0; i < 8; i++)
781 for(i = 0; i < 8; i++)
782 { 831 {
783 wps_data->wps_progress_pat[i] = 0; 832 wps_data->wps_progress_pat[i] = 0;
784 } 833 }