summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
Diffstat (limited to 'apps')
-rw-r--r--apps/filetree.c4
-rw-r--r--apps/gui/gwps-common.c237
-rw-r--r--apps/gui/gwps.h28
-rw-r--r--apps/gui/wps_debug.c55
-rw-r--r--apps/gui/wps_parser.c179
-rw-r--r--apps/recorder/peakmeter.c8
-rw-r--r--apps/settings.c4
7 files changed, 355 insertions, 160 deletions
diff --git a/apps/filetree.c b/apps/filetree.c
index edd421cad9..34bed71499 100644
--- a/apps/filetree.c
+++ b/apps/filetree.c
@@ -478,7 +478,7 @@ int ft_enter(struct tree_context* c)
478#if LCD_DEPTH > 1 478#if LCD_DEPTH > 1
479 unload_wps_backdrop(); 479 unload_wps_backdrop();
480#endif 480#endif
481 wps_data_load(gui_wps[0].data, buf, true); 481 wps_data_load(gui_wps[0].data, &screens[0], buf, true);
482 set_file(buf, (char *)global_settings.wps_file, 482 set_file(buf, (char *)global_settings.wps_file,
483 MAX_FILENAME); 483 MAX_FILENAME);
484 break; 484 break;
@@ -490,7 +490,7 @@ int ft_enter(struct tree_context* c)
490#if defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1 490#if defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1
491 unload_remote_wps_backdrop(); 491 unload_remote_wps_backdrop();
492#endif 492#endif
493 wps_data_load(gui_wps[1].data, buf, true); 493 wps_data_load(gui_wps[1].data, &screens[1], buf, true);
494 set_file(buf, (char *)global_settings.rwps_file, 494 set_file(buf, (char *)global_settings.rwps_file,
495 MAX_FILENAME); 495 MAX_FILENAME);
496 break; 496 break;
diff --git a/apps/gui/gwps-common.c b/apps/gui/gwps-common.c
index cfaabafe90..ae5492a66c 100644
--- a/apps/gui/gwps-common.c
+++ b/apps/gui/gwps-common.c
@@ -295,6 +295,19 @@ bool gui_wps_display(void)
295 { 295 {
296 FOR_NB_SCREENS(i) 296 FOR_NB_SCREENS(i)
297 { 297 {
298 /* Update the values in the first (default) viewport - in case the user
299 has modified the statusbar or colour settings */
300#ifdef HAVE_LCD_BITMAP
301 gui_wps[i].data->viewports[0].vp.ymargin = gui_wps[i].display->getymargin();
302#if LCD_DEPTH > 1
303 if (gui_wps[i].display->depth > 1)
304 {
305 gui_wps[i].data->viewports[0].vp.fg_pattern = gui_wps[i].display->get_foreground();
306 gui_wps[i].data->viewports[0].vp.bg_pattern = gui_wps[i].display->get_background();
307 }
308#endif
309#endif
310
298 gui_wps[i].display->clear_display(); 311 gui_wps[i].display->clear_display();
299 if (!gui_wps[i].data->wps_loaded) { 312 if (!gui_wps[i].data->wps_loaded) {
300 if ( !gui_wps[i].data->num_tokens ) { 313 if ( !gui_wps[i].data->num_tokens ) {
@@ -306,6 +319,7 @@ bool gui_wps_display(void)
306 unload_wps_backdrop(); 319 unload_wps_backdrop();
307#endif 320#endif
308 wps_data_load(gui_wps[i].data, 321 wps_data_load(gui_wps[i].data,
322 gui_wps[i].display,
309 "%s%?it<%?in<%in. |>%it|%fn>\n" 323 "%s%?it<%?in<%in. |>%it|%fn>\n"
310 "%s%?ia<%ia|%?d2<%d2|(root)>>\n" 324 "%s%?ia<%ia|%?d2<%d2|(root)>>\n"
311 "%s%?id<%id|%?d1<%d1|(root)>> %?iy<(%iy)|>\n" 325 "%s%?id<%id|%?d1<%d1|(root)>> %?iy<(%iy)|>\n"
@@ -316,6 +330,7 @@ bool gui_wps_display(void)
316 "%pm\n", false); 330 "%pm\n", false);
317#else 331#else
318 wps_data_load(gui_wps[i].data, 332 wps_data_load(gui_wps[i].data,
333 gui_wps[i].display,
319 "%s%pp/%pe: %?it<%it|%fn> - %?ia<%ia|%d2> - %?id<%id|%d1>\n" 334 "%s%pp/%pe: %?it<%it|%fn> - %?ia<%ia|%d2> - %?id<%id|%d1>\n"
320 "%pc%?ps<*|/>%pt\n", false); 335 "%pc%?ps<*|/>%pt\n", false);
321#endif 336#endif
@@ -328,6 +343,7 @@ bool gui_wps_display(void)
328 unload_remote_wps_backdrop(); 343 unload_remote_wps_backdrop();
329#endif 344#endif
330 wps_data_load(gui_wps[i].data, 345 wps_data_load(gui_wps[i].data,
346 gui_wps[i].display,
331 "%s%?ia<%ia|%?d2<%d2|(root)>>\n" 347 "%s%?ia<%ia|%?d2<%d2|(root)>>\n"
332 "%s%?it<%?in<%in. |>%it|%fn>\n" 348 "%s%?it<%?in<%in. |>%it|%fn>\n"
333 "%al%pc/%pt%ar[%pp:%pe]\n" 349 "%al%pc/%pt%ar[%pp:%pe]\n"
@@ -448,7 +464,7 @@ static void draw_progressbar(struct gui_wps *gwps, int line)
448 struct wps_data *data = gwps->data; 464 struct wps_data *data = gwps->data;
449 struct screen *display = gwps->display; 465 struct screen *display = gwps->display;
450 struct wps_state *state = gwps->state; 466 struct wps_state *state = gwps->state;
451 int h = font_get(FONT_UI)->height; 467 int h = font_get(display->getfont())->height;
452 468
453 int sb_y; 469 int sb_y;
454 if (data->progress_top < 0) 470 if (data->progress_top < 0)
@@ -459,7 +475,7 @@ static void draw_progressbar(struct gui_wps *gwps, int line)
459 sb_y = data->progress_top; 475 sb_y = data->progress_top;
460 476
461 if (!data->progress_end) 477 if (!data->progress_end)
462 data->progress_end=display->width; 478 data->progress_end=display->getwidth();
463 479
464 if (gwps->data->progressbar.have_bitmap_pb) 480 if (gwps->data->progressbar.have_bitmap_pb)
465 gui_bitmap_scrollbar_draw(display, data->progressbar.bm, 481 gui_bitmap_scrollbar_draw(display, data->progressbar.bm,
@@ -529,7 +545,7 @@ static void wps_draw_image(struct gui_wps *gwps, int n)
529#endif 545#endif
530} 546}
531 547
532static void wps_display_images(struct gui_wps *gwps) 548static void wps_display_images(struct gui_wps *gwps, struct viewport* vp)
533{ 549{
534 if(!gwps || !gwps->data || !gwps->display) 550 if(!gwps || !gwps->data || !gwps->display)
535 return; 551 return;
@@ -541,7 +557,8 @@ static void wps_display_images(struct gui_wps *gwps)
541 for (n = 0; n < MAX_IMAGES; n++) 557 for (n = 0; n < MAX_IMAGES; n++)
542 { 558 {
543 if (data->img[n].loaded && 559 if (data->img[n].loaded &&
544 (data->img[n].display || data->img[n].always_display)) 560 (data->img[n].display ||
561 (data->img[n].always_display && data->img[n].vp == vp)))
545 { 562 {
546 wps_draw_image(gwps, n); 563 wps_draw_image(gwps, n);
547 } 564 }
@@ -1449,7 +1466,7 @@ static bool evaluate_conditional(struct gui_wps *gwps, int *token_index)
1449 The return value indicates whether the line needs to be updated. 1466 The return value indicates whether the line needs to be updated.
1450*/ 1467*/
1451static bool get_line(struct gui_wps *gwps, 1468static bool get_line(struct gui_wps *gwps,
1452 int line, int subline, 1469 int v, int line, int subline,
1453 struct align_pos *align, 1470 struct align_pos *align,
1454 char *linebuf, 1471 char *linebuf,
1455 int linebuf_size) 1472 int linebuf_size)
@@ -1477,8 +1494,8 @@ static bool get_line(struct gui_wps *gwps,
1477#endif 1494#endif
1478 1495
1479 /* Process all tokens of the desired subline */ 1496 /* Process all tokens of the desired subline */
1480 last_token_idx = wps_last_token_index(data, line, subline); 1497 last_token_idx = wps_last_token_index(data, v, line, subline);
1481 for (i = wps_first_token_index(data, line, subline); 1498 for (i = wps_first_token_index(data, v, line, subline);
1482 i <= last_token_idx; i++) 1499 i <= last_token_idx; i++)
1483 { 1500 {
1484 switch(data->tokens[i].type) 1501 switch(data->tokens[i].type)
@@ -1577,16 +1594,16 @@ static bool get_line(struct gui_wps *gwps,
1577 return update; 1594 return update;
1578} 1595}
1579 1596
1580static void get_subline_timeout(struct gui_wps *gwps, int line, int subline) 1597static void get_subline_timeout(struct gui_wps *gwps, int v, int line, int subline)
1581{ 1598{
1582 struct wps_data *data = gwps->data; 1599 struct wps_data *data = gwps->data;
1583 int i; 1600 int i;
1584 int subline_idx = wps_subline_index(data, line, subline); 1601 int subline_idx = wps_subline_index(data, v, line, subline);
1585 int last_token_idx = wps_last_token_index(data, line, subline); 1602 int last_token_idx = wps_last_token_index(data, v, line, subline);
1586 1603
1587 data->sublines[subline_idx].time_mult = DEFAULT_SUBLINE_TIME_MULTIPLIER; 1604 data->sublines[subline_idx].time_mult = DEFAULT_SUBLINE_TIME_MULTIPLIER;
1588 1605
1589 for (i = wps_first_token_index(data, line, subline); 1606 for (i = wps_first_token_index(data, v, line, subline);
1590 i <= last_token_idx; i++) 1607 i <= last_token_idx; i++)
1591 { 1608 {
1592 switch(data->tokens[i].type) 1609 switch(data->tokens[i].type)
@@ -1614,7 +1631,7 @@ static void get_subline_timeout(struct gui_wps *gwps, int line, int subline)
1614 1631
1615/* Calculates which subline should be displayed for the specified line 1632/* Calculates which subline should be displayed for the specified line
1616 Returns true iff the subline must be refreshed */ 1633 Returns true iff the subline must be refreshed */
1617static bool update_curr_subline(struct gui_wps *gwps, int line) 1634static bool update_curr_subline(struct gui_wps *gwps, int v, int line)
1618{ 1635{
1619 struct wps_data *data = gwps->data; 1636 struct wps_data *data = gwps->data;
1620 1637
@@ -1623,13 +1640,13 @@ static bool update_curr_subline(struct gui_wps *gwps, int line)
1623 bool new_subline_refresh; 1640 bool new_subline_refresh;
1624 bool only_one_subline; 1641 bool only_one_subline;
1625 1642
1626 num_sublines = data->lines[line].num_sublines; 1643 num_sublines = data->viewports[v].lines[line].num_sublines;
1627 reset_subline = (data->lines[line].curr_subline == SUBLINE_RESET); 1644 reset_subline = (data->viewports[v].lines[line].curr_subline == SUBLINE_RESET);
1628 new_subline_refresh = false; 1645 new_subline_refresh = false;
1629 only_one_subline = false; 1646 only_one_subline = false;
1630 1647
1631 /* if time to advance to next sub-line */ 1648 /* if time to advance to next sub-line */
1632 if (TIME_AFTER(current_tick, data->lines[line].subline_expire_time - 1) || 1649 if (TIME_AFTER(current_tick, data->viewports[v].lines[line].subline_expire_time - 1) ||
1633 reset_subline) 1650 reset_subline)
1634 { 1651 {
1635 /* search all sublines until the next subline with time > 0 1652 /* search all sublines until the next subline with time > 0
@@ -1637,46 +1654,46 @@ static bool update_curr_subline(struct gui_wps *gwps, int line)
1637 if (reset_subline) 1654 if (reset_subline)
1638 search_start = 0; 1655 search_start = 0;
1639 else 1656 else
1640 search_start = data->lines[line].curr_subline; 1657 search_start = data->viewports[v].lines[line].curr_subline;
1641 1658
1642 for (search = 0; search < num_sublines; search++) 1659 for (search = 0; search < num_sublines; search++)
1643 { 1660 {
1644 data->lines[line].curr_subline++; 1661 data->viewports[v].lines[line].curr_subline++;
1645 1662
1646 /* wrap around if beyond last defined subline or WPS_MAX_SUBLINES */ 1663 /* wrap around if beyond last defined subline or WPS_MAX_SUBLINES */
1647 if (data->lines[line].curr_subline == num_sublines) 1664 if (data->viewports[v].lines[line].curr_subline == num_sublines)
1648 { 1665 {
1649 if (data->lines[line].curr_subline == 1) 1666 if (data->viewports[v].lines[line].curr_subline == 1)
1650 only_one_subline = true; 1667 only_one_subline = true;
1651 data->lines[line].curr_subline = 0; 1668 data->viewports[v].lines[line].curr_subline = 0;
1652 } 1669 }
1653 1670
1654 /* if back where we started after search or 1671 /* if back where we started after search or
1655 only one subline is defined on the line */ 1672 only one subline is defined on the line */
1656 if (((search > 0) && 1673 if (((search > 0) &&
1657 (data->lines[line].curr_subline == search_start)) || 1674 (data->viewports[v].lines[line].curr_subline == search_start)) ||
1658 only_one_subline) 1675 only_one_subline)
1659 { 1676 {
1660 /* no other subline with a time > 0 exists */ 1677 /* no other subline with a time > 0 exists */
1661 data->lines[line].subline_expire_time = (reset_subline ? 1678 data->viewports[v].lines[line].subline_expire_time = (reset_subline ?
1662 current_tick : 1679 current_tick :
1663 data->lines[line].subline_expire_time) + 100 * HZ; 1680 data->viewports[v].lines[line].subline_expire_time) + 100 * HZ;
1664 break; 1681 break;
1665 } 1682 }
1666 else 1683 else
1667 { 1684 {
1668 /* get initial time multiplier for this subline */ 1685 /* get initial time multiplier for this subline */
1669 get_subline_timeout(gwps, line, data->lines[line].curr_subline); 1686 get_subline_timeout(gwps, v, line, data->viewports[v].lines[line].curr_subline);
1670 1687
1671 int subline_idx = wps_subline_index(data, line, 1688 int subline_idx = wps_subline_index(data, v, line,
1672 data->lines[line].curr_subline); 1689 data->viewports[v].lines[line].curr_subline);
1673 1690
1674 /* only use this subline if subline time > 0 */ 1691 /* only use this subline if subline time > 0 */
1675 if (data->sublines[subline_idx].time_mult > 0) 1692 if (data->sublines[subline_idx].time_mult > 0)
1676 { 1693 {
1677 new_subline_refresh = true; 1694 new_subline_refresh = true;
1678 data->lines[line].subline_expire_time = (reset_subline ? 1695 data->viewports[v].lines[line].subline_expire_time = (reset_subline ?
1679 current_tick : data->lines[line].subline_expire_time) + 1696 current_tick : data->viewports[v].lines[line].subline_expire_time) +
1680 BASE_SUBLINE_TIME*data->sublines[subline_idx].time_mult; 1697 BASE_SUBLINE_TIME*data->sublines[subline_idx].time_mult;
1681 break; 1698 break;
1682 } 1699 }
@@ -1724,10 +1741,10 @@ static void write_line(struct screen *display,
1724 } 1741 }
1725 1742
1726 left_xpos = display->getxmargin(); 1743 left_xpos = display->getxmargin();
1727 right_xpos = (display->width - right_width); 1744 right_xpos = (display->getwidth() - right_width);
1728 center_xpos = (display->width + left_xpos - center_width) / 2; 1745 center_xpos = (display->getwidth() + left_xpos - center_width) / 2;
1729 1746
1730 scroll_width = display->width - left_xpos; 1747 scroll_width = display->getwidth() - left_xpos;
1731 1748
1732 /* Checks for overlapping strings. 1749 /* Checks for overlapping strings.
1733 If needed the overlapping strings will be merged, separated by a 1750 If needed the overlapping strings will be merged, separated by a
@@ -1767,7 +1784,7 @@ static void write_line(struct screen *display,
1767 format_align->right = format_align->center; 1784 format_align->right = format_align->center;
1768 /* calculate the new width and position of the merged string */ 1785 /* calculate the new width and position of the merged string */
1769 right_width = center_width + space_width + right_width; 1786 right_width = center_width + space_width + right_width;
1770 right_xpos = (display->width - right_width); 1787 right_xpos = (display->getwidth() - right_width);
1771 /* there is no centered string anymore */ 1788 /* there is no centered string anymore */
1772 center_width = 0; 1789 center_width = 0;
1773 } 1790 }
@@ -1778,7 +1795,7 @@ static void write_line(struct screen *display,
1778 format_align->right = format_align->center; 1795 format_align->right = format_align->center;
1779 /* calculate the new width and position of the string */ 1796 /* calculate the new width and position of the string */
1780 right_width = center_width; 1797 right_width = center_width;
1781 right_xpos = (display->width - right_width); 1798 right_xpos = (display->getwidth() - right_width);
1782 /* there is no centered string anymore */ 1799 /* there is no centered string anymore */
1783 center_width = 0; 1800 center_width = 0;
1784 } 1801 }
@@ -1823,7 +1840,7 @@ static void write_line(struct screen *display,
1823#ifdef HAVE_LCD_BITMAP 1840#ifdef HAVE_LCD_BITMAP
1824 /* clear the line first */ 1841 /* clear the line first */
1825 display->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); 1842 display->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
1826 display->fillrect(left_xpos, ypos, display->width, string_height); 1843 display->fillrect(left_xpos, ypos, display->getwidth(), string_height);
1827 display->set_drawmode(DRMODE_SOLID); 1844 display->set_drawmode(DRMODE_SOLID);
1828#endif 1845#endif
1829 1846
@@ -1862,7 +1879,7 @@ bool gui_wps_refresh(struct gui_wps *gwps,
1862 if(!gwps || !data || !state || !display) 1879 if(!gwps || !data || !state || !display)
1863 return false; 1880 return false;
1864 1881
1865 int line, i, subline_idx; 1882 int v, line, i, subline_idx;
1866 unsigned char flags; 1883 unsigned char flags;
1867 char linebuf[MAX_PATH]; 1884 char linebuf[MAX_PATH];
1868 1885
@@ -1885,19 +1902,19 @@ bool gui_wps_refresh(struct gui_wps *gwps,
1885 */ 1902 */
1886 bool enable_pm = false; 1903 bool enable_pm = false;
1887 1904
1888 /* Set images to not to be displayed */
1889 for (i = 0; i < MAX_IMAGES; i++)
1890 {
1891 data->img[i].display = false;
1892 }
1893#endif 1905#endif
1894 1906
1895 /* reset to first subline if refresh all flag is set */ 1907 /* reset to first subline if refresh all flag is set */
1896 if (refresh_mode == WPS_REFRESH_ALL) 1908 if (refresh_mode == WPS_REFRESH_ALL)
1897 { 1909 {
1898 for (i = 0; i < data->num_lines; i++) 1910 display->clear_display();
1911
1912 for (v = 0; v < data->num_viewports; v++)
1899 { 1913 {
1900 data->lines[i].curr_subline = SUBLINE_RESET; 1914 for (i = 0; i < data->viewports[v].num_lines; i++)
1915 {
1916 data->viewports[v].lines[i].curr_subline = SUBLINE_RESET;
1917 }
1901 } 1918 }
1902 } 1919 }
1903 1920
@@ -1917,88 +1934,114 @@ bool gui_wps_refresh(struct gui_wps *gwps,
1917 1934
1918 state->ff_rewind_count = ffwd_offset; 1935 state->ff_rewind_count = ffwd_offset;
1919 1936
1920 for (line = 0; line < data->num_lines; line++) 1937 for (v = 0; v < data->num_viewports; v++)
1921 { 1938 {
1922 memset(linebuf, 0, sizeof(linebuf)); 1939 display->set_viewport(&data->viewports[v].vp);
1923 update_line = false;
1924
1925 /* get current subline for the line */
1926 new_subline_refresh = update_curr_subline(gwps, line);
1927
1928 subline_idx = wps_subline_index(data, line,
1929 data->lines[line].curr_subline);
1930 flags = data->sublines[subline_idx].line_type;
1931 1940
1932 if (refresh_mode == WPS_REFRESH_ALL || (flags & refresh_mode) 1941 if (refresh_mode == WPS_REFRESH_ALL)
1933 || new_subline_refresh)
1934 { 1942 {
1935 /* get_line tells us if we need to update the line */ 1943 display->clear_viewport();
1936 update_line = get_line(gwps, line, data->lines[line].curr_subline,
1937 &align, linebuf, sizeof(linebuf));
1938 } 1944 }
1939 1945
1940#ifdef HAVE_LCD_BITMAP 1946#ifdef HAVE_LCD_BITMAP
1941 /* progressbar */ 1947 /* Set images to not to be displayed */
1942 if (flags & refresh_mode & WPS_REFRESH_PLAYER_PROGRESS) 1948 for (i = 0; i < MAX_IMAGES; i++)
1943 { 1949 {
1944 /* the progressbar should be alone on its line */ 1950 data->img[i].display = false;
1945 update_line = false;
1946 draw_progressbar(gwps, line);
1947 } 1951 }
1952#endif
1948 1953
1949 /* peakmeter */ 1954 for (line = 0; line < data->viewports[v].num_lines; line++)
1950 if (flags & refresh_mode & WPS_REFRESH_PEAK_METER)
1951 { 1955 {
1952 /* the peakmeter should be alone on its line */ 1956 memset(linebuf, 0, sizeof(linebuf));
1953 update_line = false; 1957 update_line = false;
1954 1958
1955 int h = font_get(FONT_UI)->height; 1959 /* get current subline for the line */
1956 int peak_meter_y = display->getymargin() + line * h; 1960 new_subline_refresh = update_curr_subline(gwps, v, line);
1957 1961
1958 /* The user might decide to have the peak meter in the last 1962 subline_idx = wps_subline_index(data, v, line,
1959 line so that it is only displayed if no status bar is 1963 data->viewports[v].lines[line].curr_subline);
1960 visible. If so we neither want do draw nor enable the 1964 flags = data->sublines[subline_idx].line_type;
1961 peak meter. */ 1965
1962 if (peak_meter_y + h <= display->height) { 1966 if (refresh_mode == WPS_REFRESH_ALL || (flags & refresh_mode)
1963 /* found a line with a peak meter -> remember that we must 1967 || new_subline_refresh)
1964 enable it later */ 1968 {
1965 enable_pm = true; 1969 /* get_line tells us if we need to update the line */
1966 peak_meter_screen(gwps->display, 0, peak_meter_y, 1970 update_line = get_line(gwps, v, line, data->viewports[v].lines[line].curr_subline,
1967 MIN(h, display->height - peak_meter_y)); 1971 &align, linebuf, sizeof(linebuf));
1972 }
1973
1974#ifdef HAVE_LCD_BITMAP
1975 /* progressbar */
1976 if (flags & refresh_mode & WPS_REFRESH_PLAYER_PROGRESS)
1977 {
1978 /* the progressbar should be alone on its line */
1979 update_line = false;
1980 draw_progressbar(gwps, line);
1981 }
1982
1983 /* peakmeter */
1984 if (flags & refresh_mode & WPS_REFRESH_PEAK_METER)
1985 {
1986 /* the peakmeter should be alone on its line */
1987 update_line = false;
1988
1989 int h = font_get(display->getfont())->height;
1990 int peak_meter_y = display->getymargin() + line * h;
1991
1992 /* The user might decide to have the peak meter in the last
1993 line so that it is only displayed if no status bar is
1994 visible. If so we neither want do draw nor enable the
1995 peak meter. */
1996 if (peak_meter_y + h <= display->getheight()) {
1997 /* found a line with a peak meter -> remember that we must
1998 enable it later */
1999 enable_pm = true;
2000 peak_meter_screen(gwps->display, 0, peak_meter_y,
2001 MIN(h, display->getheight() - peak_meter_y));
2002 }
1968 } 2003 }
1969 }
1970 2004
1971#else /* HAVE_LCD_CHARCELL */ 2005#else /* HAVE_LCD_CHARCELL */
1972 2006
1973 /* progressbar */ 2007 /* progressbar */
1974 if (flags & refresh_mode & WPS_REFRESH_PLAYER_PROGRESS) 2008 if (flags & refresh_mode & WPS_REFRESH_PLAYER_PROGRESS)
1975 { 2009 {
1976 if (data->full_line_progressbar) 2010 if (data->full_line_progressbar)
1977 draw_player_fullbar(gwps, linebuf, sizeof(linebuf)); 2011 draw_player_fullbar(gwps, linebuf, sizeof(linebuf));
1978 else 2012 else
1979 draw_player_progress(gwps); 2013 draw_player_progress(gwps);
1980 } 2014 }
1981#endif 2015#endif
1982 2016
1983 if (update_line) 2017 if (update_line)
1984 {
1985 if (flags & WPS_REFRESH_SCROLL)
1986 { 2018 {
1987 /* if the line is a scrolling one we don't want to update 2019 if (flags & WPS_REFRESH_SCROLL)
1988 too often, so that it has the time to scroll */ 2020 {
1989 if ((refresh_mode & WPS_REFRESH_SCROLL) || new_subline_refresh) 2021 /* if the line is a scrolling one we don't want to update
1990 write_line(display, &align, line, true); 2022 too often, so that it has the time to scroll */
2023 if ((refresh_mode & WPS_REFRESH_SCROLL) || new_subline_refresh)
2024 write_line(display, &align, line, true);
2025 }
2026 else
2027 write_line(display, &align, line, false);
1991 } 2028 }
1992 else 2029
1993 write_line(display, &align, line, false);
1994 } 2030 }
2031
2032#ifdef HAVE_LCD_BITMAP
2033 /* Now display any images in this viewport */
2034 wps_display_images(gwps, &data->viewports[v].vp);
2035#endif
1995 } 2036 }
1996 2037
1997#ifdef HAVE_LCD_BITMAP 2038#ifdef HAVE_LCD_BITMAP
1998 data->peak_meter_enabled = enable_pm; 2039 data->peak_meter_enabled = enable_pm;
1999 wps_display_images(gwps);
2000#endif 2040#endif
2001 2041
2042 /* Restore the default viewport */
2043 display->set_viewport(NULL);
2044
2002 display->update(); 2045 display->update();
2003 2046
2004#ifdef HAVE_BACKLIGHT 2047#ifdef HAVE_BACKLIGHT
diff --git a/apps/gui/gwps.h b/apps/gui/gwps.h
index 70f4c560c6..d31471c2a4 100644
--- a/apps/gui/gwps.h
+++ b/apps/gui/gwps.h
@@ -61,6 +61,7 @@
61#ifdef HAVE_LCD_BITMAP 61#ifdef HAVE_LCD_BITMAP
62struct gui_img{ 62struct gui_img{
63 struct bitmap bm; 63 struct bitmap bm;
64 struct viewport* vp; /* The viewport to display this image in */
64 int x; /* x-pos */ 65 int x; /* x-pos */
65 int y; /* y-pos */ 66 int y; /* y-pos */
66 bool loaded; /* load state */ 67 bool loaded; /* load state */
@@ -86,6 +87,7 @@ struct align_pos {
86#define IMG_BUFSIZE ((LCD_HEIGHT*LCD_WIDTH*LCD_DEPTH/8) \ 87#define IMG_BUFSIZE ((LCD_HEIGHT*LCD_WIDTH*LCD_DEPTH/8) \
87 + (2*LCD_HEIGHT*LCD_WIDTH/8)) 88 + (2*LCD_HEIGHT*LCD_WIDTH/8))
88 89
90#define WPS_MAX_VIEWPORTS 16
89#define WPS_MAX_LINES (LCD_HEIGHT/5+1) 91#define WPS_MAX_LINES (LCD_HEIGHT/5+1)
90#define WPS_MAX_SUBLINES (WPS_MAX_LINES*3) 92#define WPS_MAX_SUBLINES (WPS_MAX_LINES*3)
91#define WPS_MAX_TOKENS 1024 93#define WPS_MAX_TOKENS 1024
@@ -95,6 +97,7 @@ struct align_pos {
95 97
96#else 98#else
97 99
100#define WPS_MAX_VIEWPORTS 2
98#define WPS_MAX_LINES 2 101#define WPS_MAX_LINES 2
99#define WPS_MAX_SUBLINES 12 102#define WPS_MAX_SUBLINES 12
100#define WPS_MAX_TOKENS 64 103#define WPS_MAX_TOKENS 64
@@ -315,6 +318,14 @@ struct wps_line {
315 long subline_expire_time; 318 long subline_expire_time;
316}; 319};
317 320
321struct wps_viewport {
322 struct viewport vp; /* The LCD viewport struct */
323
324 /* Number of lines in this viewport. During WPS parsing, this is
325 the index of the line being parsed. */
326 int num_lines;
327 struct wps_line lines[WPS_MAX_LINES];
328};
318 329
319/* wps_data 330/* wps_data
320 this struct holds all necessary data which describes the 331 this struct holds all necessary data which describes the
@@ -360,10 +371,9 @@ struct wps_data
360 bool remote_wps; 371 bool remote_wps;
361#endif 372#endif
362 373
363 /* Number of lines in the WPS. During WPS parsing, this is 374 /* Number of viewports in the WPS */
364 the index of the line being parsed. */ 375 int num_viewports;
365 int num_lines; 376 struct wps_viewport viewports[WPS_MAX_VIEWPORTS];
366 struct wps_line lines[WPS_MAX_LINES];
367 377
368 /* Total number of sublines in the WPS. During WPS parsing, this is 378 /* Total number of sublines in the WPS. During WPS parsing, this is
369 the index of the subline where the parsed tokens are added to. */ 379 the index of the subline where the parsed tokens are added to. */
@@ -388,26 +398,30 @@ void wps_data_init(struct wps_data *wps_data);
388/* to setup up the wps-data from a format-buffer (isfile = false) 398/* to setup up the wps-data from a format-buffer (isfile = false)
389 from a (wps-)file (isfile = true)*/ 399 from a (wps-)file (isfile = true)*/
390bool wps_data_load(struct wps_data *wps_data, 400bool wps_data_load(struct wps_data *wps_data,
401 struct screen *display,
391 const char *buf, 402 const char *buf,
392 bool isfile); 403 bool isfile);
393 404
394/* Returns the index of the subline in the subline array 405/* Returns the index of the subline in the subline array
406 v - 0-based viewport number
395 line - 0-based line number 407 line - 0-based line number
396 subline - 0-based subline number within the line 408 subline - 0-based subline number within the line
397 */ 409 */
398int wps_subline_index(struct wps_data *wps_data, int line, int subline); 410int wps_subline_index(struct wps_data *wps_data, int v, int line, int subline);
399 411
400/* Returns the index of the first subline's token in the token array 412/* Returns the index of the first subline's token in the token array
413 v - 0-based viewport number
401 line - 0-based line number 414 line - 0-based line number
402 subline - 0-based subline number within the line 415 subline - 0-based subline number within the line
403 */ 416 */
404int wps_first_token_index(struct wps_data *data, int line, int subline); 417int wps_first_token_index(struct wps_data *data, int v, int line, int subline);
405 418
406/* Returns the index of the last subline's token in the token array. 419/* Returns the index of the last subline's token in the token array.
420 v - 0-based viewport number
407 line - 0-based line number 421 line - 0-based line number
408 subline - 0-based subline number within the line 422 subline - 0-based subline number within the line
409 */ 423 */
410int wps_last_token_index(struct wps_data *data, int line, int subline); 424int wps_last_token_index(struct wps_data *data, int v, int line, int subline);
411 425
412/* wps_data end */ 426/* wps_data end */
413 427
diff --git a/apps/gui/wps_debug.c b/apps/gui/wps_debug.c
index 0f69c76938..0c13fd2c22 100644
--- a/apps/gui/wps_debug.c
+++ b/apps/gui/wps_debug.c
@@ -493,40 +493,51 @@ static void dump_wps_tokens(struct wps_data *data)
493 493
494static void print_line_info(struct wps_data *data) 494static void print_line_info(struct wps_data *data)
495{ 495{
496 int i, j; 496 int i, j, v;
497 struct wps_line *line; 497 struct wps_line *line;
498 struct wps_subline *subline; 498 struct wps_subline *subline;
499 499
500 if (wps_verbose_level > 0) 500 if (wps_verbose_level > 0)
501 { 501 {
502 DEBUGF("Number of lines : %d\n", data->num_lines); 502 DEBUGF("Number of viewports : %d\n", data->num_viewports);
503 DEBUGF("Number of sublines: %d\n", data->num_sublines); 503 for (v = 0; v < data->num_viewports; v++)
504 DEBUGF("Number of tokens : %d\n", data->num_tokens); 504 {
505 DEBUGF("vp %d: Number of lines: %d\n", v, data->viewports[v].num_lines);
506 }
507 DEBUGF("Number of sublines : %d\n", data->num_sublines);
508 DEBUGF("Number of tokens : %d\n", data->num_tokens);
505 DEBUGF("\n"); 509 DEBUGF("\n");
506 } 510 }
507 511
508 if (wps_verbose_level > 1) 512 if (wps_verbose_level > 1)
509 { 513 {
510 for (i = 0, line = data->lines; i < data->num_lines; i++,line++) 514 for (v = 0; v < data->num_viewports; v++)
511 { 515 {
512 DEBUGF("Line %2d (num_sublines=%d, first_subline=%d)\n", 516 DEBUGF("Viewport %d - +%d+%d (%dx%d)\n",v,data->viewports[v].vp.x,
513 i, line->num_sublines, line->first_subline_idx); 517 data->viewports[v].vp.y,
514 518 data->viewports[v].vp.width,
515 for (j = 0, subline = data->sublines + line->first_subline_idx; 519 data->viewports[v].vp.height);
516 j < line->num_sublines; j++, subline++) 520 for (i = 0, line = data->viewports[v].lines; i < data->viewports[v].num_lines; i++,line++)
517 { 521 {
518 DEBUGF(" Subline %d: first_token=%3d, last_token=%3d", 522 DEBUGF("Line %2d (num_sublines=%d, first_subline=%d)\n",
519 j, subline->first_token_idx, 523 i, line->num_sublines, line->first_subline_idx);
520 wps_last_token_index(data, i, j)); 524
521 525 for (j = 0, subline = data->sublines + line->first_subline_idx;
522 if (subline->line_type & WPS_REFRESH_SCROLL) 526 j < line->num_sublines; j++, subline++)
523 DEBUGF(", scrolled"); 527 {
524 else if (subline->line_type & WPS_REFRESH_PLAYER_PROGRESS) 528 DEBUGF(" Subline %d: first_token=%3d, last_token=%3d",
525 DEBUGF(", progressbar"); 529 j, subline->first_token_idx,
526 else if (subline->line_type & WPS_REFRESH_PEAK_METER) 530 wps_last_token_index(data, v, i, j));
527 DEBUGF(", peakmeter"); 531
528 532 if (subline->line_type & WPS_REFRESH_SCROLL)
529 DEBUGF("\n"); 533 DEBUGF(", scrolled");
534 else if (subline->line_type & WPS_REFRESH_PLAYER_PROGRESS)
535 DEBUGF(", progressbar");
536 else if (subline->line_type & WPS_REFRESH_PEAK_METER)
537 DEBUGF(", peakmeter");
538
539 DEBUGF("\n");
540 }
530 } 541 }
531 } 542 }
532 543
diff --git a/apps/gui/wps_parser.c b/apps/gui/wps_parser.c
index 307fa2ad7f..c641f2c247 100644
--- a/apps/gui/wps_parser.c
+++ b/apps/gui/wps_parser.c
@@ -69,13 +69,13 @@ static int line;
69#ifdef HAVE_LCD_BITMAP 69#ifdef HAVE_LCD_BITMAP
70 70
71#if LCD_DEPTH > 1 71#if LCD_DEPTH > 1
72#define MAX_BITMAPS MAX_IMAGES+2 /* WPS images + pbar bitmap + backdrop */ 72#define MAX_BITMAPS (MAX_IMAGES+2) /* WPS images + pbar bitmap + backdrop */
73#else 73#else
74#define MAX_BITMAPS MAX_IMAGES+1 /* WPS images + pbar bitmap */ 74#define MAX_BITMAPS (MAX_IMAGES+1) /* WPS images + pbar bitmap */
75#endif 75#endif
76 76
77#define PROGRESSBAR_BMP MAX_IMAGES 77#define PROGRESSBAR_BMP MAX_IMAGES
78#define BACKDROP_BMP MAX_IMAGES+1 78#define BACKDROP_BMP (MAX_IMAGES+1)
79 79
80/* pointers to the bitmap filenames in the WPS source */ 80/* pointers to the bitmap filenames in the WPS source */
81static const char *bmp_names[MAX_BITMAPS]; 81static const char *bmp_names[MAX_BITMAPS];
@@ -118,6 +118,8 @@ static int parse_dir_level(const char *wps_bufptr,
118 struct wps_token *token, struct wps_data *wps_data); 118 struct wps_token *token, struct wps_data *wps_data);
119 119
120#ifdef HAVE_LCD_BITMAP 120#ifdef HAVE_LCD_BITMAP
121static int parse_viewport(const char *wps_bufptr,
122 struct wps_token *token, struct wps_data *wps_data);
121static int parse_leftmargin(const char *wps_bufptr, 123static int parse_leftmargin(const char *wps_bufptr,
122 struct wps_token *token, struct wps_data *wps_data); 124 struct wps_token *token, struct wps_data *wps_data);
123static int parse_image_special(const char *wps_bufptr, 125static int parse_image_special(const char *wps_bufptr,
@@ -131,7 +133,6 @@ static int parse_image_display(const char *wps_bufptr,
131static int parse_image_load(const char *wps_bufptr, 133static int parse_image_load(const char *wps_bufptr,
132 struct wps_token *token, struct wps_data *wps_data); 134 struct wps_token *token, struct wps_data *wps_data);
133#endif /*HAVE_LCD_BITMAP */ 135#endif /*HAVE_LCD_BITMAP */
134
135#ifdef HAVE_ALBUMART 136#ifdef HAVE_ALBUMART
136static int parse_albumart_load(const char *wps_bufptr, 137static int parse_albumart_load(const char *wps_bufptr,
137 struct wps_token *token, struct wps_data *wps_data); 138 struct wps_token *token, struct wps_data *wps_data);
@@ -311,6 +312,9 @@ static const struct wps_tag all_tags[] = {
311 { WPS_TOKEN_ALBUMART_DISPLAY, "C", WPS_REFRESH_STATIC, 312 { WPS_TOKEN_ALBUMART_DISPLAY, "C", WPS_REFRESH_STATIC,
312 parse_albumart_conditional }, 313 parse_albumart_conditional },
313#endif 314#endif
315
316 { WPS_NO_TOKEN, "V", 0, parse_viewport },
317
314#if (LCD_DEPTH > 1) || (defined(HAVE_LCD_REMOTE) && (LCD_REMOTE_DEPTH > 1)) 318#if (LCD_DEPTH > 1) || (defined(HAVE_LCD_REMOTE) && (LCD_REMOTE_DEPTH > 1))
315 { WPS_TOKEN_IMAGE_BACKDROP, "X", 0, parse_image_special }, 319 { WPS_TOKEN_IMAGE_BACKDROP, "X", 0, parse_image_special },
316#endif 320#endif
@@ -334,9 +338,11 @@ static int skip_end_of_line(const char *wps_bufptr)
334/* Starts a new subline in the current line during parsing */ 338/* Starts a new subline in the current line during parsing */
335static void wps_start_new_subline(struct wps_data *data) 339static void wps_start_new_subline(struct wps_data *data)
336{ 340{
341 struct wps_viewport* vp = &data->viewports[data->num_viewports];
342
337 data->num_sublines++; 343 data->num_sublines++;
338 data->sublines[data->num_sublines].first_token_idx = data->num_tokens; 344 data->sublines[data->num_sublines].first_token_idx = data->num_tokens;
339 data->lines[data->num_lines].num_sublines++; 345 vp->lines[vp->num_lines].num_sublines++;
340} 346}
341 347
342#ifdef HAVE_LCD_BITMAP 348#ifdef HAVE_LCD_BITMAP
@@ -482,6 +488,9 @@ static int parse_image_load(const char *wps_bufptr,
482 wps_data->img[n].x = x; 488 wps_data->img[n].x = x;
483 wps_data->img[n].y = y; 489 wps_data->img[n].y = y;
484 490
491 /* save current viewport */
492 wps_data->img[n].vp = &wps_data->viewports[wps_data->num_viewports].vp;
493
485 if (token->type == WPS_TOKEN_IMAGE_DISPLAY) 494 if (token->type == WPS_TOKEN_IMAGE_DISPLAY)
486 wps_data->img[n].always_display = true; 495 wps_data->img[n].always_display = true;
487 496
@@ -489,6 +498,110 @@ static int parse_image_load(const char *wps_bufptr,
489 return skip_end_of_line(wps_bufptr); 498 return skip_end_of_line(wps_bufptr);
490} 499}
491 500
501static int parse_viewport(const char *wps_bufptr,
502 struct wps_token *token,
503 struct wps_data *wps_data)
504{
505 const char *ptr = wps_bufptr;
506 struct viewport* vp;
507 int depth;
508
509 (void)token; /* Kill warnings */
510
511 if (*wps_bufptr != '|')
512 return WPS_ERROR_INVALID_PARAM; /* malformed token: e.g. %Cl7 */
513
514 ptr = wps_bufptr + 1;
515 /* format: %V|x|y|width|height|fg_pattern|bg_pattern| */
516
517 if (wps_data->num_viewports >= WPS_MAX_VIEWPORTS)
518 return WPS_ERROR_INVALID_PARAM;
519
520 wps_data->num_viewports++;
521 vp = &wps_data->viewports[wps_data->num_viewports].vp;
522
523 /* Set the defaults for fields not user-specified */
524 vp->drawmode = DRMODE_SOLID;
525 vp->xmargin = 0;
526 vp->ymargin = 0;
527
528 /* Work out the depth of this display */
529#ifdef HAVE_REMOTE_LCD
530 depth = (wps_data->remote_wps ? LCD_REMOTE_DEPTH : LCD_DEPTH);
531#else
532 depth = LCD_DEPTH;
533#endif
534
535#ifdef HAVE_LCD_COLOR
536 if (depth == 16)
537 {
538 parse_list("dddddcc", '|', ptr, &vp->x, &vp->y, &vp->width,
539 &vp->height, &vp->font, &vp->fg_pattern,&vp->bg_pattern);
540 }
541 else
542#endif
543#if (LCD_DEPTH == 2) || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH == 2)
544 if (depth == 2) {
545 parse_list("dddddgg", '|', ptr, &vp->x, &vp->y, &vp->width,
546 &vp->height, &vp->font, &vp->fg_pattern, &vp->bg_pattern);
547 }
548 else
549#endif
550#if (LCD_DEPTH == 1) || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH == 1)
551 if (depth == 1)
552 {
553 parse_list("ddddd", '|', ptr, &vp->x, &vp->y, &vp->width, &vp->height,
554 &vp->font);
555 }
556 else
557#endif
558 {}
559
560 /* Default to using the user font if the font was an invalid number */
561 if ((vp->font != FONT_SYSFIXED) && (vp->font != FONT_UI))
562 vp->font = FONT_UI;
563
564 /* Validate the viewport dimensions - we know that the numbers are
565 non-negative integers */
566#ifdef HAVE_REMOTE_LCD
567 if (wps_data->remote_wps)
568 {
569 if ((vp->x >= LCD_REMOTE_WIDTH) ||
570 ((vp->x + vp->width) >= LCD_REMOTE_WIDTH) ||
571 (vp->y >= LCD_REMOTE_HEIGHT) ||
572 ((vp->y + vp->height) >= LCD_REMOTE_HEIGHT))
573 {
574 return WPS_ERROR_INVALID_PARAM;
575 }
576 }
577 else
578#else
579 {
580 if ((vp->x >= LCD_WIDTH) ||
581 (vp->y >= LCD_HEIGHT) ||
582 ((vp->y + vp->height) >= LCD_HEIGHT))
583 {
584 return WPS_ERROR_INVALID_PARAM;
585 }
586 }
587#endif
588
589 wps_data->viewports[wps_data->num_viewports].num_lines = 0;
590
591 if (wps_data->num_sublines < WPS_MAX_SUBLINES)
592 {
593 wps_data->viewports[wps_data->num_viewports].lines[0].first_subline_idx =
594 wps_data->num_sublines;
595
596 wps_data->sublines[wps_data->num_sublines].first_token_idx =
597 wps_data->num_tokens;
598 }
599
600 /* Skip the rest of the line */
601 return skip_end_of_line(wps_bufptr);
602 }
603
604
492static int parse_image_special(const char *wps_bufptr, 605static int parse_image_special(const char *wps_bufptr,
493 struct wps_token *token, 606 struct wps_token *token,
494 struct wps_data *wps_data) 607 struct wps_data *wps_data)
@@ -958,7 +1071,8 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr)
958 level = -1; 1071 level = -1;
959 1072
960 while(*wps_bufptr && !fail && data->num_tokens < WPS_MAX_TOKENS - 1 1073 while(*wps_bufptr && !fail && data->num_tokens < WPS_MAX_TOKENS - 1
961 && data->num_lines < WPS_MAX_LINES) 1074 && data->num_viewports < WPS_MAX_VIEWPORTS
1075 && data->viewports[data->num_viewports].num_lines < WPS_MAX_LINES)
962 { 1076 {
963 switch(*wps_bufptr++) 1077 switch(*wps_bufptr++)
964 { 1078 {
@@ -1066,12 +1180,12 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr)
1066 1180
1067 line++; 1181 line++;
1068 wps_start_new_subline(data); 1182 wps_start_new_subline(data);
1069 data->num_lines++; /* Start a new line */ 1183 data->viewports[data->num_viewports].num_lines++; /* Start a new line */
1070 1184
1071 if ((data->num_lines < WPS_MAX_LINES) && 1185 if ((data->viewports[data->num_viewports].num_lines < WPS_MAX_LINES) &&
1072 (data->num_sublines < WPS_MAX_SUBLINES)) 1186 (data->num_sublines < WPS_MAX_SUBLINES))
1073 { 1187 {
1074 data->lines[data->num_lines].first_subline_idx = 1188 data->viewports[data->num_viewports].lines[data->viewports[data->num_viewports].num_lines].first_subline_idx =
1075 data->num_sublines; 1189 data->num_sublines;
1076 1190
1077 data->sublines[data->num_sublines].first_token_idx = 1191 data->sublines[data->num_sublines].first_token_idx =
@@ -1148,6 +1262,9 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr)
1148 if (!fail && level >= 0) /* there are unclosed conditionals */ 1262 if (!fail && level >= 0) /* there are unclosed conditionals */
1149 fail = PARSE_FAIL_UNCLOSED_COND; 1263 fail = PARSE_FAIL_UNCLOSED_COND;
1150 1264
1265 /* We have finished with the last viewport, so increment count */
1266 data->num_viewports++;
1267
1151#ifdef DEBUG 1268#ifdef DEBUG
1152 print_debug_info(data, fail, line); 1269 print_debug_info(data, fail, line);
1153#endif 1270#endif
@@ -1212,16 +1329,6 @@ static void wps_reset(struct wps_data *data)
1212 1329
1213#ifdef HAVE_LCD_BITMAP 1330#ifdef HAVE_LCD_BITMAP
1214 1331
1215
1216static void clear_bmp_names(void)
1217{
1218 int n;
1219 for (n = 0; n < MAX_BITMAPS; n++)
1220 {
1221 bmp_names[n] = NULL;
1222 }
1223}
1224
1225static void load_wps_bitmaps(struct wps_data *wps_data, char *bmpdir) 1332static void load_wps_bitmaps(struct wps_data *wps_data, char *bmpdir)
1226{ 1333{
1227 char img_path[MAX_PATH]; 1334 char img_path[MAX_PATH];
@@ -1291,6 +1398,7 @@ static char *skip_utf8_bom(char *buf)
1291/* to setup up the wps-data from a format-buffer (isfile = false) 1398/* to setup up the wps-data from a format-buffer (isfile = false)
1292 from a (wps-)file (isfile = true)*/ 1399 from a (wps-)file (isfile = true)*/
1293bool wps_data_load(struct wps_data *wps_data, 1400bool wps_data_load(struct wps_data *wps_data,
1401 struct screen *display,
1294 const char *buf, 1402 const char *buf,
1295 bool isfile) 1403 bool isfile)
1296{ 1404{
@@ -1299,6 +1407,24 @@ bool wps_data_load(struct wps_data *wps_data,
1299 1407
1300 wps_reset(wps_data); 1408 wps_reset(wps_data);
1301 1409
1410 /* Initialise the first (default) viewport */
1411 wps_data->viewports[0].vp.x = 0;
1412 wps_data->viewports[0].vp.y = 0;
1413 wps_data->viewports[0].vp.width = display->width;
1414 wps_data->viewports[0].vp.height = display->height;
1415#ifdef HAVE_LCD_BITMAP
1416 wps_data->viewports[0].vp.font = FONT_UI;
1417 wps_data->viewports[0].vp.drawmode = DRMODE_SOLID;
1418#endif
1419 wps_data->viewports[0].vp.xmargin = display->getxmargin();
1420 wps_data->viewports[0].vp.ymargin = display->getymargin();
1421#if LCD_DEPTH > 1
1422 if (display->depth > 1)
1423 {
1424 wps_data->viewports[0].vp.fg_pattern = display->get_foreground();
1425 wps_data->viewports[0].vp.bg_pattern = display->get_background();
1426 }
1427#endif
1302 if (!isfile) 1428 if (!isfile)
1303 { 1429 {
1304 return wps_parse(wps_data, buf); 1430 return wps_parse(wps_data, buf);
@@ -1357,7 +1483,8 @@ bool wps_data_load(struct wps_data *wps_data,
1357 return false; 1483 return false;
1358 1484
1359#ifdef HAVE_LCD_BITMAP 1485#ifdef HAVE_LCD_BITMAP
1360 clear_bmp_names(); 1486 /* Set all filename pointers to NULL */
1487 memset(bmp_names, sizeof(bmp_names), 0);
1361#endif 1488#endif
1362 1489
1363 /* Skip leading UTF-8 BOM, if present. */ 1490 /* Skip leading UTF-8 BOM, if present. */
@@ -1385,20 +1512,20 @@ bool wps_data_load(struct wps_data *wps_data,
1385 } 1512 }
1386} 1513}
1387 1514
1388int wps_subline_index(struct wps_data *data, int line, int subline) 1515int wps_subline_index(struct wps_data *data, int v, int line, int subline)
1389{ 1516{
1390 return data->lines[line].first_subline_idx + subline; 1517 return data->viewports[v].lines[line].first_subline_idx + subline;
1391} 1518}
1392 1519
1393int wps_first_token_index(struct wps_data *data, int line, int subline) 1520int wps_first_token_index(struct wps_data *data, int v, int line, int subline)
1394{ 1521{
1395 int first_subline_idx = data->lines[line].first_subline_idx; 1522 int first_subline_idx = data->viewports[v].lines[line].first_subline_idx;
1396 return data->sublines[first_subline_idx + subline].first_token_idx; 1523 return data->sublines[first_subline_idx + subline].first_token_idx;
1397} 1524}
1398 1525
1399int wps_last_token_index(struct wps_data *data, int line, int subline) 1526int wps_last_token_index(struct wps_data *data, int v, int line, int subline)
1400{ 1527{
1401 int first_subline_idx = data->lines[line].first_subline_idx; 1528 int first_subline_idx = data->viewports[v].lines[line].first_subline_idx;
1402 int idx = first_subline_idx + subline; 1529 int idx = first_subline_idx + subline;
1403 if (idx < data->num_sublines - 1) 1530 if (idx < data->num_sublines - 1)
1404 { 1531 {
diff --git a/apps/recorder/peakmeter.c b/apps/recorder/peakmeter.c
index 541101cb80..fb2e465006 100644
--- a/apps/recorder/peakmeter.c
+++ b/apps/recorder/peakmeter.c
@@ -915,14 +915,14 @@ unsigned short peak_meter_scale_value(unsigned short val, int meterwidth)
915void peak_meter_screen(struct screen *display, int x, int y, int height) 915void peak_meter_screen(struct screen *display, int x, int y, int height)
916{ 916{
917 peak_meter_draw(display, &scales[display->screen_type], x, y, 917 peak_meter_draw(display, &scales[display->screen_type], x, y,
918 display->width - x, height); 918 display->getwidth() - x, height);
919} 919}
920/** 920/**
921 * Draws a peak meter in the specified size at the specified position. 921 * Draws a peak meter in the specified size at the specified position.
922 * @param int x - The x coordinate. 922 * @param int x - The x coordinate.
923 * Make sure that 0 <= x and x + width < display->width 923 * Make sure that 0 <= x and x + width < display->getwidth()
924 * @param int y - The y coordinate. 924 * @param int y - The y coordinate.
925 * Make sure that 0 <= y and y + height < display->height 925 * Make sure that 0 <= y and y + height < display->getheight()
926 * @param int width - The width of the peak meter. Note that for display 926 * @param int width - The width of the peak meter. Note that for display
927 * of clips a 3 pixel wide area is used -> 927 * of clips a 3 pixel wide area is used ->
928 * width > 3 928 * width > 3
@@ -1111,7 +1111,7 @@ static void peak_meter_draw(struct screen *display, struct meter_scales *scales,
1111 start_trigx = x+peak_meter_scale_value(trig_strt_threshold,meterwidth); 1111 start_trigx = x+peak_meter_scale_value(trig_strt_threshold,meterwidth);
1112 display->vline(start_trigx, ycenter - 2, ycenter); 1112 display->vline(start_trigx, ycenter - 2, ycenter);
1113 start_trigx ++; 1113 start_trigx ++;
1114 if (start_trigx < display->width ) display->drawpixel(start_trigx, ycenter - 1); 1114 if (start_trigx < display->getwidth() ) display->drawpixel(start_trigx, ycenter - 1);
1115 1115
1116 stop_trigx = x + peak_meter_scale_value(trig_stp_threshold,meterwidth); 1116 stop_trigx = x + peak_meter_scale_value(trig_stp_threshold,meterwidth);
1117 display->vline(stop_trigx, ycenter - 2, ycenter); 1117 display->vline(stop_trigx, ycenter - 2, ycenter);
diff --git a/apps/settings.c b/apps/settings.c
index 6fb5e3ee47..449a38b96f 100644
--- a/apps/settings.c
+++ b/apps/settings.c
@@ -806,7 +806,7 @@ void settings_apply(bool read_disk)
806 global_settings.wps_file[0] != 0xff ) { 806 global_settings.wps_file[0] != 0xff ) {
807 snprintf(buf, sizeof buf, WPS_DIR "/%s.wps", 807 snprintf(buf, sizeof buf, WPS_DIR "/%s.wps",
808 global_settings.wps_file); 808 global_settings.wps_file);
809 wps_data_load(gui_wps[0].data, buf, true); 809 wps_data_load(gui_wps[0].data, &screens[0], buf, true);
810 } 810 }
811 else 811 else
812 { 812 {
@@ -835,7 +835,7 @@ void settings_apply(bool read_disk)
835 if ( global_settings.rwps_file[0]) { 835 if ( global_settings.rwps_file[0]) {
836 snprintf(buf, sizeof buf, WPS_DIR "/%s.rwps", 836 snprintf(buf, sizeof buf, WPS_DIR "/%s.rwps",
837 global_settings.rwps_file); 837 global_settings.rwps_file);
838 wps_data_load(gui_wps[1].data, buf, true); 838 wps_data_load(gui_wps[1].data, &screens[1], buf, true);
839 } 839 }
840 else 840 else
841 { 841 {