diff options
author | Nicolas Pennequin <nicolas.pennequin@free.fr> | 2007-04-08 04:01:06 +0000 |
---|---|---|
committer | Nicolas Pennequin <nicolas.pennequin@free.fr> | 2007-04-08 04:01:06 +0000 |
commit | 07696c10b10a051af3cb680b06c422e13c42aa76 (patch) | |
tree | 1dd2b0e7ae675978052c4a9ae7f067e6a4983176 /apps | |
parent | fad3ad6894bf0c8024f2925ac1d6f535170ae3b0 (diff) | |
download | rockbox-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.c | 135 | ||||
-rw-r--r-- | apps/gui/gwps.h | 122 | ||||
-rw-r--r-- | apps/gui/wps_debug.c | 232 | ||||
-rw-r--r-- | apps/gui/wps_parser.c | 207 |
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, | |||
1496 | static void get_subline_timeout(struct gui_wps *gwps, int line, int subline) | 1489 | static 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 |
1532 | static bool get_curr_subline(struct gui_wps *gwps, int line) | 1525 | Returns true iff the subline must be refreshed */ |
1526 | static 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 | |||
1949 | int wps_subline_index(struct wps_data *data, int line, int subline) | ||
1950 | { | ||
1951 | return data->lines[line].first_subline_idx + subline; | ||
1952 | } | ||
1953 | |||
1954 | int 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 | |||
1960 | int 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 | ||
243 | struct wps_token { | 234 | struct 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 */ | ||
248 | struct 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. */ | ||
265 | struct 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 | */ | ||
341 | int 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 | */ | ||
347 | int 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 | */ | ||
353 | int 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 */ |
334 | struct gui_wps | 386 | struct 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 | ||
27 | static char *next_str(bool next) { | ||
28 | return next ? "next" : ""; | ||
29 | } | ||
30 | |||
27 | void dump_wps_tokens(struct wps_data *data) | 31 | void 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 | ||
350 | void print_line_info(struct wps_data *data) | 325 | void 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 | ||
368 | void print_wps_strings(struct wps_data *data) | 362 | void 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 |
382 | void print_img_cond_indexes(struct wps_data *data) | 376 | void 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); | |||
69 | extern void print_wps_strings(struct wps_data *data); | 69 | extern 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 |
75 | typedef 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 | */ | ||
82 | typedef int (*wps_tag_parse_func)(const char *wps_bufptr, | ||
83 | struct wps_token *token, struct wps_data *wps_data); | ||
76 | 84 | ||
77 | struct wps_tag { | 85 | struct 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 : */ |
85 | static int parse_subline_timeout(const char *wps_bufptr, struct wps_data *wps_data); | 93 | static int parse_subline_timeout(const char *wps_bufptr, |
86 | static int parse_progressbar(const char *wps_bufptr, struct wps_data *wps_data); | 94 | struct wps_token *token, struct wps_data *wps_data); |
87 | static int parse_dir_level(const char *wps_bufptr, struct wps_data *wps_data); | 95 | static int parse_progressbar(const char *wps_bufptr, |
96 | struct wps_token *token, struct wps_data *wps_data); | ||
97 | static 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 |
89 | static int parse_image_special(const char *wps_bufptr, struct wps_data *wps_data); | 100 | static int parse_image_special(const char *wps_bufptr, |
90 | static int parse_statusbar(const char *wps_bufptr, struct wps_data *wps_data); | 101 | struct wps_token *token, struct wps_data *wps_data); |
91 | static int parse_image_display(const char *wps_bufptr, struct wps_data *wps_data); | 102 | static int parse_statusbar_enable(const char *wps_bufptr, |
92 | static int parse_image_load(const char *wps_bufptr, struct wps_data *wps_data); | 103 | struct wps_token *token, struct wps_data *wps_data); |
104 | static int parse_statusbar_disable(const char *wps_bufptr, | ||
105 | struct wps_token *token, struct wps_data *wps_data); | ||
106 | static int parse_image_display(const char *wps_bufptr, | ||
107 | struct wps_token *token, struct wps_data *wps_data); | ||
108 | static 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 |
95 | static int parse_rtc_format(const char *wps_bufptr, struct wps_data *wps_data); | 112 | static 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 */ |
98 | static const struct wps_tag rtc_tags[] = { | 116 | static 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 */ | ||
255 | static int skip_end_of_line(const char *wps_bufptr) | 274 | static 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 */ | ||
283 | static 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 |
264 | static int parse_rtc_format(const char *wps_bufptr, struct wps_data *wps_data) | 290 | static 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 | ||
293 | static int parse_statusbar(const char *wps_bufptr, struct wps_data *wps_data) | 322 | static 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) | 332 | static 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 | ||
360 | static int parse_image_display(const char *wps_bufptr, struct wps_data *wps_data) | 396 | static 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 | ||
372 | static int parse_image_load(const char *wps_bufptr, struct wps_data *wps_data) | 410 | static 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 | ||
432 | static int parse_image_special(const char *wps_bufptr, struct wps_data *wps_data) | 472 | static 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 | ||
455 | static int parse_dir_level(const char *wps_bufptr, struct wps_data *wps_data) | 497 | static 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 | ||
462 | static int parse_subline_timeout(const char *wps_bufptr, struct wps_data *wps_data) | 507 | static 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 | ||
498 | static int parse_progressbar(const char *wps_bufptr, struct wps_data *wps_data) | 547 | static 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) | |||
547 | static int parse_token(const char *wps_bufptr, struct wps_data *wps_data) | 599 | static 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 */ | ||
611 | static bool wps_parse(struct wps_data *data, const char *wps_bufptr) | 666 | static 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 | } |