summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Chapman <dave@dchapman.com>2008-03-21 19:38:00 +0000
committerDave Chapman <dave@dchapman.com>2008-03-21 19:38:00 +0000
commitd02c79c03fed154e8cdf4cbef8670221dfe922aa (patch)
treeae519730d242d0b9daadcf9daa10154beab682d5
parent1544b36966c692e20d711b920eade06487996eb6 (diff)
Commit viewports-in-WPS patch (FS#8385). This adds the %V tag - see the CustomWPS page for details (shortly...). There is still some work to do - decide how to handle font references, decide how to handle conditionals. Plus checkwps is broken - I'll fix that in a separate commit.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@16733 a1c6a512-1295-4272-9138-f99709370657
-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)
#if LCD_DEPTH > 1
unload_wps_backdrop();
#endif
- wps_data_load(gui_wps[0].data, buf, true);
+ wps_data_load(gui_wps[0].data, &screens[0], buf, true);
set_file(buf, (char *)global_settings.wps_file,
MAX_FILENAME);
break;
@@ -490,7 +490,7 @@ int ft_enter(struct tree_context* c)
#if defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1
unload_remote_wps_backdrop();
#endif
- wps_data_load(gui_wps[1].data, buf, true);
+ wps_data_load(gui_wps[1].data, &screens[1], buf, true);
set_file(buf, (char *)global_settings.rwps_file,
MAX_FILENAME);
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)
{
FOR_NB_SCREENS(i)
{
+ /* Update the values in the first (default) viewport - in case the user
+ has modified the statusbar or colour settings */
+#ifdef HAVE_LCD_BITMAP
+ gui_wps[i].data->viewports[0].vp.ymargin = gui_wps[i].display->getymargin();
+#if LCD_DEPTH > 1
+ if (gui_wps[i].display->depth > 1)
+ {
+ gui_wps[i].data->viewports[0].vp.fg_pattern = gui_wps[i].display->get_foreground();
+ gui_wps[i].data->viewports[0].vp.bg_pattern = gui_wps[i].display->get_background();
+ }
+#endif
+#endif
+
gui_wps[i].display->clear_display();
if (!gui_wps[i].data->wps_loaded) {
if ( !gui_wps[i].data->num_tokens ) {
@@ -306,6 +319,7 @@ bool gui_wps_display(void)
unload_wps_backdrop();
#endif
wps_data_load(gui_wps[i].data,
+ gui_wps[i].display,
"%s%?it<%?in<%in. |>%it|%fn>\n"
"%s%?ia<%ia|%?d2<%d2|(root)>>\n"
"%s%?id<%id|%?d1<%d1|(root)>> %?iy<(%iy)|>\n"
@@ -316,6 +330,7 @@ bool gui_wps_display(void)
"%pm\n", false);
#else
wps_data_load(gui_wps[i].data,
+ gui_wps[i].display,
"%s%pp/%pe: %?it<%it|%fn> - %?ia<%ia|%d2> - %?id<%id|%d1>\n"
"%pc%?ps<*|/>%pt\n", false);
#endif
@@ -328,6 +343,7 @@ bool gui_wps_display(void)
unload_remote_wps_backdrop();
#endif
wps_data_load(gui_wps[i].data,
+ gui_wps[i].display,
"%s%?ia<%ia|%?d2<%d2|(root)>>\n"
"%s%?it<%?in<%in. |>%it|%fn>\n"
"%al%pc/%pt%ar[%pp:%pe]\n"
@@ -448,7 +464,7 @@ static void draw_progressbar(struct gui_wps *gwps, int line)
struct wps_data *data = gwps->data;
struct screen *display = gwps->display;
struct wps_state *state = gwps->state;
- int h = font_get(FONT_UI)->height;
+ int h = font_get(display->getfont())->height;
int sb_y;
if (data->progress_top < 0)
@@ -459,7 +475,7 @@ static void draw_progressbar(struct gui_wps *gwps, int line)
sb_y = data->progress_top;
if (!data->progress_end)
- data->progress_end=display->width;
+ data->progress_end=display->getwidth();
if (gwps->data->progressbar.have_bitmap_pb)
gui_bitmap_scrollbar_draw(display, data->progressbar.bm,
@@ -529,7 +545,7 @@ static void wps_draw_image(struct gui_wps *gwps, int n)
#endif
}
-static void wps_display_images(struct gui_wps *gwps)
+static void wps_display_images(struct gui_wps *gwps, struct viewport* vp)
{
if(!gwps || !gwps->data || !gwps->display)
return;
@@ -541,7 +557,8 @@ static void wps_display_images(struct gui_wps *gwps)
for (n = 0; n < MAX_IMAGES; n++)
{
if (data->img[n].loaded &&
- (data->img[n].display || data->img[n].always_display))
+ (data->img[n].display ||
+ (data->img[n].always_display && data->img[n].vp == vp)))
{
wps_draw_image(gwps, n);
}
@@ -1449,7 +1466,7 @@ static bool evaluate_conditional(struct gui_wps *gwps, int *token_index)
The return value indicates whether the line needs to be updated.
*/
static bool get_line(struct gui_wps *gwps,
- int line, int subline,
+ int v, int line, int subline,
struct align_pos *align,
char *linebuf,
int linebuf_size)
@@ -1477,8 +1494,8 @@ static bool get_line(struct gui_wps *gwps,
#endif
/* Process all tokens of the desired subline */
- last_token_idx = wps_last_token_index(data, line, subline);
- for (i = wps_first_token_index(data, line, subline);
+ last_token_idx = wps_last_token_index(data, v, line, subline);
+ for (i = wps_first_token_index(data, v, line, subline);
i <= last_token_idx; i++)
{
switch(data->tokens[i].type)
@@ -1577,16 +1594,16 @@ static bool get_line(struct gui_wps *gwps,
return update;
}
-static void get_subline_timeout(struct gui_wps *gwps, int line, int subline)
+static void get_subline_timeout(struct gui_wps *gwps, int v, int line, int subline)
{
struct wps_data *data = gwps->data;
int i;
- int subline_idx = wps_subline_index(data, line, subline);
- int last_token_idx = wps_last_token_index(data, line, subline);
+ int subline_idx = wps_subline_index(data, v, line, subline);
+ int last_token_idx = wps_last_token_index(data, v, line, subline);
data->sublines[subline_idx].time_mult = DEFAULT_SUBLINE_TIME_MULTIPLIER;
- for (i = wps_first_token_index(data, line, subline);
+ for (i = wps_first_token_index(data, v, line, subline);
i <= last_token_idx; i++)
{
switch(data->tokens[i].type)
@@ -1614,7 +1631,7 @@ static void get_subline_timeout(struct gui_wps *gwps, int line, int subline)
/* Calculates which subline should be displayed for the specified line
Returns true iff the subline must be refreshed */
-static bool update_curr_subline(struct gui_wps *gwps, int line)
+static bool update_curr_subline(struct gui_wps *gwps, int v, int line)
{
struct wps_data *data = gwps->data;
@@ -1623,13 +1640,13 @@ static bool update_curr_subline(struct gui_wps *gwps, int line)
bool new_subline_refresh;
bool only_one_subline;
- num_sublines = data->lines[line].num_sublines;
- reset_subline = (data->lines[line].curr_subline == SUBLINE_RESET);
+ num_sublines = data->viewports[v].lines[line].num_sublines;
+ reset_subline = (data->viewports[v].lines[line].curr_subline == SUBLINE_RESET);
new_subline_refresh = false;
only_one_subline = false;
/* if time to advance to next sub-line */
- if (TIME_AFTER(current_tick, data->lines[line].subline_expire_time - 1) ||
+ if (TIME_AFTER(current_tick, data->viewports[v].lines[line].subline_expire_time - 1) ||
reset_subline)
{
/* 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)
if (reset_subline)
search_start = 0;
else
- search_start = data->lines[line].curr_subline;
+ search_start = data->viewports[v].lines[line].curr_subline;
for (search = 0; search < num_sublines; search++)
{
- data->lines[line].curr_subline++;
+ data->viewports[v].lines[line].curr_subline++;
/* wrap around if beyond last defined subline or WPS_MAX_SUBLINES */
- if (data->lines[line].curr_subline == num_sublines)
+ if (data->viewports[v].lines[line].curr_subline == num_sublines)
{
- if (data->lines[line].curr_subline == 1)
+ if (data->viewports[v].lines[line].curr_subline == 1)
only_one_subline = true;
- data->lines[line].curr_subline = 0;
+ data->viewports[v].lines[line].curr_subline = 0;
}
/* if back where we started after search or
only one subline is defined on the line */
if (((search > 0) &&
- (data->lines[line].curr_subline == search_start)) ||
+ (data->viewports[v].lines[line].curr_subline == search_start)) ||
only_one_subline)
{
/* no other subline with a time > 0 exists */
- data->lines[line].subline_expire_time = (reset_subline ?
+ data->viewports[v].lines[line].subline_expire_time = (reset_subline ?
current_tick :
- data->lines[line].subline_expire_time) + 100 * HZ;
+ data->viewports[v].lines[line].subline_expire_time) + 100 * HZ;
break;
}
else
{
/* get initial time multiplier for this subline */
- get_subline_timeout(gwps, line, data->lines[line].curr_subline);
+ get_subline_timeout(gwps, v, line, data->viewports[v].lines[line].curr_subline);
- int subline_idx = wps_subline_index(data, line,
- data->lines[line].curr_subline);
+ int subline_idx = wps_subline_index(data, v, line,
+ data->viewports[v].lines[line].curr_subline);
/* only use this subline if subline time > 0 */
if (data->sublines[subline_idx].time_mult > 0)
{
new_subline_refresh = true;
- data->lines[line].subline_expire_time = (reset_subline ?
- current_tick : data->lines[line].subline_expire_time) +
+ data->viewports[v].lines[line].subline_expire_time = (reset_subline ?
+ current_tick : data->viewports[v].lines[line].subline_expire_time) +
BASE_SUBLINE_TIME*data->sublines[subline_idx].time_mult;
break;
}
@@ -1724,10 +1741,10 @@ static void write_line(struct screen *display,
}
left_xpos = display->getxmargin();
- right_xpos = (display->width - right_width);
- center_xpos = (display->width + left_xpos - center_width) / 2;
+ right_xpos = (display->getwidth() - right_width);
+ center_xpos = (display->getwidth() + left_xpos - center_width) / 2;
- scroll_width = display->width - left_xpos;
+ scroll_width = display->getwidth() - left_xpos;
/* Checks for overlapping strings.
If needed the overlapping strings will be merged, separated by a
@@ -1767,7 +1784,7 @@ static void write_line(struct screen *display,
format_align->right = format_align->center;
/* calculate the new width and position of the merged string */
right_width = center_width + space_width + right_width;
- right_xpos = (display->width - right_width);
+ right_xpos = (display->getwidth() - right_width);
/* there is no centered string anymore */
center_width = 0;
}
@@ -1778,7 +1795,7 @@ static void write_line(struct screen *display,
format_align->right = format_align->center;
/* calculate the new width and position of the string */
right_width = center_width;
- right_xpos = (display->width - right_width);
+ right_xpos = (display->getwidth() - right_width);
/* there is no centered string anymore */
center_width = 0;
}
@@ -1823,7 +1840,7 @@ static void write_line(struct screen *display,
#ifdef HAVE_LCD_BITMAP
/* clear the line first */
display->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
- display->fillrect(left_xpos, ypos, display->width, string_height);
+ display->fillrect(left_xpos, ypos, display->getwidth(), string_height);
display->set_drawmode(DRMODE_SOLID);
#endif
@@ -1862,7 +1879,7 @@ bool gui_wps_refresh(struct gui_wps *gwps,
if(!gwps || !data || !state || !display)
return false;
- int line, i, subline_idx;
+ int v, line, i, subline_idx;
unsigned char flags;
char linebuf[MAX_PATH];
@@ -1885,19 +1902,19 @@ bool gui_wps_refresh(struct gui_wps *gwps,
*/
bool enable_pm = false;
- /* Set images to not to be displayed */
- for (i = 0; i < MAX_IMAGES; i++)
- {
- data->img[i].display = false;
- }
#endif
/* reset to first subline if refresh all flag is set */
if (refresh_mode == WPS_REFRESH_ALL)
{
- for (i = 0; i < data->num_lines; i++)
+ display->clear_display();
+
+ for (v = 0; v < data->num_viewports; v++)
{
- data->lines[i].curr_subline = SUBLINE_RESET;
+ for (i = 0; i < data->viewports[v].num_lines; i++)
+ {
+ data->viewports[v].lines[i].curr_subline = SUBLINE_RESET;
+ }
}
}
@@ -1917,88 +1934,114 @@ bool gui_wps_refresh(struct gui_wps *gwps,
state->ff_rewind_count = ffwd_offset;
- for (line = 0; line < data->num_lines; line++)
+ for (v = 0; v < data->num_viewports; v++)
{
- memset(linebuf, 0, sizeof(linebuf));
- update_line = false;
-
- /* get current subline for the line */
- new_subline_refresh = update_curr_subline(gwps, line);
-
- subline_idx = wps_subline_index(data, line,
- data->lines[line].curr_subline);
- flags = data->sublines[subline_idx].line_type;
+ display->set_viewport(&data->viewports[v].vp);
- if (refresh_mode == WPS_REFRESH_ALL || (flags & refresh_mode)
- || new_subline_refresh)
+ if (refresh_mode == WPS_REFRESH_ALL)
{
- /* get_line tells us if we need to update the line */
- update_line = get_line(gwps, line, data->lines[line].curr_subline,
- &align, linebuf, sizeof(linebuf));
+ display->clear_viewport();
}
#ifdef HAVE_LCD_BITMAP
- /* progressbar */
- if (flags & refresh_mode & WPS_REFRESH_PLAYER_PROGRESS)
+ /* Set images to not to be displayed */
+ for (i = 0; i < MAX_IMAGES; i++)
{
- /* the progressbar should be alone on its line */
- update_line = false;
- draw_progressbar(gwps, line);
+ data->img[i].display = false;
}
+#endif
- /* peakmeter */
- if (flags & refresh_mode & WPS_REFRESH_PEAK_METER)
+ for (line = 0; line < data->viewports[v].num_lines; line++)
{
- /* the peakmeter should be alone on its line */
+ memset(linebuf, 0, sizeof(linebuf));
update_line = false;
- int h = font_get(FONT_UI)->height;
- int peak_meter_y = display->getymargin() + line * h;
-
- /* The user might decide to have the peak meter in the last
- line so that it is only displayed if no status bar is
- visible. If so we neither want do draw nor enable the
- peak meter. */
- if (peak_meter_y + h <= display->height) {
- /* found a line with a peak meter -> remember that we must
- enable it later */
- enable_pm = true;
- peak_meter_screen(gwps->display, 0, peak_meter_y,
- MIN(h, display->height - peak_meter_y));
+ /* get current subline for the line */
+ new_subline_refresh = update_curr_subline(gwps, v, line);
+
+ subline_idx = wps_subline_index(data, v, line,
+ data->viewports[v].lines[line].curr_subline);
+ flags = data->sublines[subline_idx].line_type;
+
+ if (refresh_mode == WPS_REFRESH_ALL || (flags & refresh_mode)
+ || new_subline_refresh)
+ {
+ /* get_line tells us if we need to update the line */
+ update_line = get_line(gwps, v, line, data->viewports[v].lines[line].curr_subline,
+ &align, linebuf, sizeof(linebuf));
+ }
+
+#ifdef HAVE_LCD_BITMAP
+ /* progressbar */
+ if (flags & refresh_mode & WPS_REFRESH_PLAYER_PROGRESS)
+ {
+ /* the progressbar should be alone on its line */
+ update_line = false;
+ draw_progressbar(gwps, line);
+ }
+
+ /* peakmeter */
+ if (flags & refresh_mode & WPS_REFRESH_PEAK_METER)
+ {
+ /* the peakmeter should be alone on its line */
+ update_line = false;
+
+ int h = font_get(display->getfont())->height;
+ int peak_meter_y = display->getymargin() + line * h;
+
+ /* The user might decide to have the peak meter in the last
+ line so that it is only displayed if no status bar is
+ visible. If so we neither want do draw nor enable the
+ peak meter. */
+ if (peak_meter_y + h <= display->getheight()) {
+ /* found a line with a peak meter -> remember that we must
+ enable it later */
+ enable_pm = true;
+ peak_meter_screen(gwps->display, 0, peak_meter_y,
+ MIN(h, display->getheight() - peak_meter_y));
+ }
}
- }
#else /* HAVE_LCD_CHARCELL */
- /* progressbar */
- if (flags & refresh_mode & WPS_REFRESH_PLAYER_PROGRESS)
- {
- if (data->full_line_progressbar)
- draw_player_fullbar(gwps, linebuf, sizeof(linebuf));
- else
- draw_player_progress(gwps);
- }
+ /* progressbar */
+ if (flags & refresh_mode & WPS_REFRESH_PLAYER_PROGRESS)
+ {
+ if (data->full_line_progressbar)
+ draw_player_fullbar(gwps, linebuf, sizeof(linebuf));
+ else
+ draw_player_progress(gwps);
+ }
#endif
- if (update_line)
- {
- if (flags & WPS_REFRESH_SCROLL)
+ if (update_line)
{
- /* if the line is a scrolling one we don't want to update
- too often, so that it has the time to scroll */
- if ((refresh_mode & WPS_REFRESH_SCROLL) || new_subline_refresh)
- write_line(display, &align, line, true);
+ if (flags & WPS_REFRESH_SCROLL)
+ {
+ /* if the line is a scrolling one we don't want to update
+ too often, so that it has the time to scroll */
+ if ((refresh_mode & WPS_REFRESH_SCROLL) || new_subline_refresh)
+ write_line(display, &align, line, true);
+ }
+ else
+ write_line(display, &align, line, false);
}
- else
- write_line(display, &align, line, false);
+
}
+
+#ifdef HAVE_LCD_BITMAP
+ /* Now display any images in this viewport */
+ wps_display_images(gwps, &data->viewports[v].vp);
+#endif
}
#ifdef HAVE_LCD_BITMAP
data->peak_meter_enabled = enable_pm;
- wps_display_images(gwps);
#endif
+ /* Restore the default viewport */
+ display->set_viewport(NULL);
+
display->update();
#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 @@
#ifdef HAVE_LCD_BITMAP
struct gui_img{
struct bitmap bm;
+ struct viewport* vp; /* The viewport to display this image in */
int x; /* x-pos */
int y; /* y-pos */
bool loaded; /* load state */
@@ -86,6 +87,7 @@ struct align_pos {
#define IMG_BUFSIZE ((LCD_HEIGHT*LCD_WIDTH*LCD_DEPTH/8) \
+ (2*LCD_HEIGHT*LCD_WIDTH/8))
+#define WPS_MAX_VIEWPORTS 16
#define WPS_MAX_LINES (LCD_HEIGHT/5+1)
#define WPS_MAX_SUBLINES (WPS_MAX_LINES*3)
#define WPS_MAX_TOKENS 1024
@@ -95,6 +97,7 @@ struct align_pos {
#else
+#define WPS_MAX_VIEWPORTS 2
#define WPS_MAX_LINES 2
#define WPS_MAX_SUBLINES 12
#define WPS_MAX_TOKENS 64
@@ -315,6 +318,14 @@ struct wps_line {
long subline_expire_time;
};
+struct wps_viewport {
+ struct viewport vp; /* The LCD viewport struct */
+
+ /* Number of lines in this viewport. During WPS parsing, this is
+ the index of the line being parsed. */
+ int num_lines;
+ struct wps_line lines[WPS_MAX_LINES];
+};
/* wps_data
this struct holds all necessary data which describes the
@@ -360,10 +371,9 @@ struct wps_data
bool remote_wps;
#endif
- /* Number of lines in the WPS. During WPS parsing, this is
- the index of the line being parsed. */
- int num_lines;
- struct wps_line lines[WPS_MAX_LINES];
+ /* Number of viewports in the WPS */
+ int num_viewports;
+ struct wps_viewport viewports[WPS_MAX_VIEWPORTS];
/* Total number of sublines in the WPS. During WPS parsing, this is
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);
/* to setup up the wps-data from a format-buffer (isfile = false)
from a (wps-)file (isfile = true)*/
bool wps_data_load(struct wps_data *wps_data,
+ struct screen *display,
const char *buf,
bool isfile);
/* Returns the index of the subline in the subline array
+ v - 0-based viewport number
line - 0-based line number
subline - 0-based subline number within the line
*/
-int wps_subline_index(struct wps_data *wps_data, int line, int subline);
+int wps_subline_index(struct wps_data *wps_data, int v, int line, int subline);
/* Returns the index of the first subline's token in the token array
+ v - 0-based viewport number
line - 0-based line number
subline - 0-based subline number within the line
*/
-int wps_first_token_index(struct wps_data *data, int line, int subline);
+int wps_first_token_index(struct wps_data *data, int v, int line, int subline);
/* Returns the index of the last subline's token in the token array.
+ v - 0-based viewport number
line - 0-based line number
subline - 0-based subline number within the line
*/
-int wps_last_token_index(struct wps_data *data, int line, int subline);
+int wps_last_token_index(struct wps_data *data, int v, int line, int subline);
/* wps_data end */
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)
static void print_line_info(struct wps_data *data)
{
- int i, j;
+ int i, j, v;
struct wps_line *line;
struct wps_subline *subline;
if (wps_verbose_level > 0)
{
- DEBUGF("Number of lines : %d\n", data->num_lines);
- DEBUGF("Number of sublines: %d\n", data->num_sublines);
- DEBUGF("Number of tokens : %d\n", data->num_tokens);
+ DEBUGF("Number of viewports : %d\n", data->num_viewports);
+ for (v = 0; v < data->num_viewports; v++)
+ {
+ DEBUGF("vp %d: Number of lines: %d\n", v, data->viewports[v].num_lines);
+ }
+ DEBUGF("Number of sublines : %d\n", data->num_sublines);
+ DEBUGF("Number of tokens : %d\n", data->num_tokens);
DEBUGF("\n");
}
if (wps_verbose_level > 1)
{
- for (i = 0, line = data->lines; i < data->num_lines; i++,line++)
+ for (v = 0; v < data->num_viewports; v++)
{
- DEBUGF("Line %2d (num_sublines=%d, first_subline=%d)\n",
- i, line->num_sublines, line->first_subline_idx);
-
- for (j = 0, subline = data->sublines + line->first_subline_idx;
- j < line->num_sublines; j++, subline++)
+ DEBUGF("Viewport %d - +%d+%d (%dx%d)\n",v,data->viewports[v].vp.x,
+ data->viewports[v].vp.y,
+ data->viewports[v].vp.width,
+ data->viewports[v].vp.height);
+ for (i = 0, line = data->viewports[v].lines; i < data->viewports[v].num_lines; i++,line++)
{
- DEBUGF(" Subline %d: first_token=%3d, last_token=%3d",
- j, subline->first_token_idx,
- wps_last_token_index(data, i, j));
-
- if (subline->line_type & WPS_REFRESH_SCROLL)
- DEBUGF(", scrolled");
- else if (subline->line_type & WPS_REFRESH_PLAYER_PROGRESS)
- DEBUGF(", progressbar");
- else if (subline->line_type & WPS_REFRESH_PEAK_METER)
- DEBUGF(", peakmeter");
-
- DEBUGF("\n");
+ DEBUGF("Line %2d (num_sublines=%d, first_subline=%d)\n",
+ i, line->num_sublines, line->first_subline_idx);
+
+ for (j = 0, subline = data->sublines + line->first_subline_idx;
+ j < line->num_sublines; j++, subline++)
+ {
+ DEBUGF(" Subline %d: first_token=%3d, last_token=%3d",
+ j, subline->first_token_idx,
+ wps_last_token_index(data, v, i, j));
+
+ if (subline->line_type & WPS_REFRESH_SCROLL)
+ DEBUGF(", scrolled");
+ else if (subline->line_type & WPS_REFRESH_PLAYER_PROGRESS)
+ DEBUGF(", progressbar");
+ else if (subline->line_type & WPS_REFRESH_PEAK_METER)
+ DEBUGF(", peakmeter");
+
+ DEBUGF("\n");
+ }
}
}
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;
#ifdef HAVE_LCD_BITMAP
#if LCD_DEPTH > 1
-#define MAX_BITMAPS MAX_IMAGES+2 /* WPS images + pbar bitmap + backdrop */
+#define MAX_BITMAPS (MAX_IMAGES+2) /* WPS images + pbar bitmap + backdrop */
#else
-#define MAX_BITMAPS MAX_IMAGES+1 /* WPS images + pbar bitmap */
+#define MAX_BITMAPS (MAX_IMAGES+1) /* WPS images + pbar bitmap */
#endif
#define PROGRESSBAR_BMP MAX_IMAGES
-#define BACKDROP_BMP MAX_IMAGES+1
+#define BACKDROP_BMP (MAX_IMAGES+1)
/* pointers to the bitmap filenames in the WPS source */
static const char *bmp_names[MAX_BITMAPS];
@@ -118,6 +118,8 @@ static int parse_dir_level(const char *wps_bufptr,
struct wps_token *token, struct wps_data *wps_data);
#ifdef HAVE_LCD_BITMAP
+static int parse_viewport(const char *wps_bufptr,
+ struct wps_token *token, struct wps_data *wps_data);
static int parse_leftmargin(const char *wps_bufptr,
struct wps_token *token, struct wps_data *wps_data);
static int parse_image_special(const char *wps_bufptr,
@@ -131,7 +133,6 @@ static int parse_image_display(const char *wps_bufptr,
static int parse_image_load(const char *wps_bufptr,
struct wps_token *token, struct wps_data *wps_data);
#endif /*HAVE_LCD_BITMAP */
-
#ifdef HAVE_ALBUMART
static int parse_albumart_load(const char *wps_bufptr,
struct wps_token *token, struct wps_data *wps_data);
@@ -311,6 +312,9 @@ static const struct wps_tag all_tags[] = {
{ WPS_TOKEN_ALBUMART_DISPLAY, "C", WPS_REFRESH_STATIC,
parse_albumart_conditional },
#endif
+
+ { WPS_NO_TOKEN, "V", 0, parse_viewport },
+
#if (LCD_DEPTH > 1) || (defined(HAVE_LCD_REMOTE) && (LCD_REMOTE_DEPTH > 1))
{ WPS_TOKEN_IMAGE_BACKDROP, "X", 0, parse_image_special },
#endif
@@ -334,9 +338,11 @@ static int skip_end_of_line(const char *wps_bufptr)
/* Starts a new subline in the current line during parsing */
static void wps_start_new_subline(struct wps_data *data)
{
+ struct wps_viewport* vp = &data->viewports[data->num_viewports];
+
data->num_sublines++;
data->sublines[data->num_sublines].first_token_idx = data->num_tokens;
- data->lines[data->num_lines].num_sublines++;
+ vp->lines[vp->num_lines].num_sublines++;
}
#ifdef HAVE_LCD_BITMAP
@@ -482,6 +488,9 @@ static int parse_image_load(const char *wps_bufptr,
wps_data->img[n].x = x;
wps_data->img[n].y = y;
+ /* save current viewport */
+ wps_data->img[n].vp = &wps_data->viewports[wps_data->num_viewports].vp;
+
if (token->type == WPS_TOKEN_IMAGE_DISPLAY)
wps_data->img[n].always_display = true;
@@ -489,6 +498,110 @@ static int parse_image_load(const char *wps_bufptr,
return skip_end_of_line(wps_bufptr);
}
+static int parse_viewport(const char *wps_bufptr,
+ struct wps_token *token,
+ struct wps_data *wps_data)
+{
+ const char *ptr = wps_bufptr;
+ struct viewport* vp;
+ int depth;
+
+ (void)token; /* Kill warnings */
+
+ if (*wps_bufptr != '|')
+ return WPS_ERROR_INVALID_PARAM; /* malformed token: e.g. %Cl7 */
+
+ ptr = wps_bufptr + 1;
+ /* format: %V|x|y|width|height|fg_pattern|bg_pattern| */
+
+ if (wps_data->num_viewports >= WPS_MAX_VIEWPORTS)
+ return WPS_ERROR_INVALID_PARAM;
+
+ wps_data->num_viewports++;
+ vp = &wps_data->viewports[wps_data->num_viewports].vp;
+
+ /* Set the defaults for fields not user-specified */
+ vp->drawmode = DRMODE_SOLID;
+ vp->xmargin = 0;
+ vp->ymargin = 0;
+
+ /* Work out the depth of this display */
+#ifdef HAVE_REMOTE_LCD
+ depth = (wps_data->remote_wps ? LCD_REMOTE_DEPTH : LCD_DEPTH);
+#else
+ depth = LCD_DEPTH;
+#endif
+
+#ifdef HAVE_LCD_COLOR
+ if (depth == 16)
+ {
+ parse_list("dddddcc", '|', ptr, &vp->x, &vp->y, &vp->width,
+ &vp->height, &vp->font, &vp->fg_pattern,&vp->bg_pattern);
+ }
+ else
+#endif
+#if (LCD_DEPTH == 2) || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH == 2)
+ if (depth == 2) {
+ parse_list("dddddgg", '|', ptr, &vp->x, &vp->y, &vp->width,
+ &vp->height, &vp->font, &vp->fg_pattern, &vp->bg_pattern);
+ }
+ else
+#endif
+#if (LCD_DEPTH == 1) || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH == 1)
+ if (depth == 1)
+ {
+ parse_list("ddddd", '|', ptr, &vp->x, &vp->y, &vp->width, &vp->height,
+ &vp->font);
+ }
+ else
+#endif
+ {}
+
+ /* Default to using the user font if the font was an invalid number */
+ if ((vp->font != FONT_SYSFIXED) && (vp->font != FONT_UI))
+ vp->font = FONT_UI;
+
+ /* Validate the viewport dimensions - we know that the numbers are
+ non-negative integers */
+#ifdef HAVE_REMOTE_LCD
+ if (wps_data->remote_wps)
+ {
+ if ((vp->x >= LCD_REMOTE_WIDTH) ||
+ ((vp->x + vp->width) >= LCD_REMOTE_WIDTH) ||
+ (vp->y >= LCD_REMOTE_HEIGHT) ||
+ ((vp->y + vp->height) >= LCD_REMOTE_HEIGHT))
+ {
+ return WPS_ERROR_INVALID_PARAM;
+ }
+ }
+ else
+#else
+ {
+ if ((vp->x >= LCD_WIDTH) ||
+ (vp->y >= LCD_HEIGHT) ||
+ ((vp->y + vp->height) >= LCD_HEIGHT))
+ {
+ return WPS_ERROR_INVALID_PARAM;
+ }
+ }
+#endif
+
+ wps_data->viewports[wps_data->num_viewports].num_lines = 0;
+
+ if (wps_data->num_sublines < WPS_MAX_SUBLINES)
+ {
+ wps_data->viewports[wps_data->num_viewports].lines[0].first_subline_idx =
+ wps_data->num_sublines;
+
+ wps_data->sublines[wps_data->num_sublines].first_token_idx =
+ wps_data->num_tokens;
+ }
+
+ /* Skip the rest of the line */
+ return skip_end_of_line(wps_bufptr);
+ }
+
+
static int parse_image_special(const char *wps_bufptr,
struct wps_token *token,
struct wps_data *wps_data)
@@ -958,7 +1071,8 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr)
level = -1;
while(*wps_bufptr && !fail && data->num_tokens < WPS_MAX_TOKENS - 1
- && data->num_lines < WPS_MAX_LINES)
+ && data->num_viewports < WPS_MAX_VIEWPORTS
+ && data->viewports[data->num_viewports].num_lines < WPS_MAX_LINES)
{
switch(*wps_bufptr++)
{
@@ -1066,12 +1180,12 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr)
line++;
wps_start_new_subline(data);
- data->num_lines++; /* Start a new line */
+ data->viewports[data->num_viewports].num_lines++; /* Start a new line */
- if ((data->num_lines < WPS_MAX_LINES) &&
+ if ((data->viewports[data->num_viewports].num_lines < WPS_MAX_LINES) &&
(data->num_sublines < WPS_MAX_SUBLINES))
{
- data->lines[data->num_lines].first_subline_idx =
+ data->viewports[data->num_viewports].lines[data->viewports[data->num_viewports].num_lines].first_subline_idx =
data->num_sublines;
data->sublines[data->num_sublines].first_token_idx =
@@ -1148,6 +1262,9 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr)
if (!fail && level >= 0) /* there are unclosed conditionals */
fail = PARSE_FAIL_UNCLOSED_COND;
+ /* We have finished with the last viewport, so increment count */
+ data->num_viewports++;
+
#ifdef DEBUG
print_debug_info(data, fail, line);
#endif
@@ -1212,16 +1329,6 @@ static void wps_reset(struct wps_data *data)
#ifdef HAVE_LCD_BITMAP
-
-static void clear_bmp_names(void)
-{
- int n;
- for (n = 0; n < MAX_BITMAPS; n++)
- {
- bmp_names[n] = NULL;
- }
-}
-
static void load_wps_bitmaps(struct wps_data *wps_data, char *bmpdir)
{
char img_path[MAX_PATH];
@@ -1291,6 +1398,7 @@ static char *skip_utf8_bom(char *buf)
/* to setup up the wps-data from a format-buffer (isfile = false)
from a (wps-)file (isfile = true)*/
bool wps_data_load(struct wps_data *wps_data,
+ struct screen *display,
const char *buf,
bool isfile)
{
@@ -1299,6 +1407,24 @@ bool wps_data_load(struct wps_data *wps_data,
wps_reset(wps_data);
+ /* Initialise the first (default) viewport */
+ wps_data->viewports[0].vp.x = 0;
+ wps_data->viewports[0].vp.y = 0;
+ wps_data->viewports[0].vp.width = display->width;
+ wps_data->viewports[0].vp.height = display->height;
+#ifdef HAVE_LCD_BITMAP
+ wps_data->viewports[0].vp.font = FONT_UI;
+ wps_data->viewports[0].vp.drawmode = DRMODE_SOLID;
+#endif
+ wps_data->viewports[0].vp.xmargin = display->getxmargin();
+ wps_data->viewports[0].vp.ymargin = display->getymargin();
+#if LCD_DEPTH > 1
+ if (display->depth > 1)
+ {
+ wps_data->viewports[0].vp.fg_pattern = display->get_foreground();
+ wps_data->viewports[0].vp.bg_pattern = display->get_background();
+ }
+#endif
if (!isfile)
{
return wps_parse(wps_data, buf);
@@ -1357,7 +1483,8 @@ bool wps_data_load(struct wps_data *wps_data,
return false;
#ifdef HAVE_LCD_BITMAP
- clear_bmp_names();
+ /* Set all filename pointers to NULL */
+ memset(bmp_names, sizeof(bmp_names), 0);
#endif
/* Skip leading UTF-8 BOM, if present. */
@@ -1385,20 +1512,20 @@ bool wps_data_load(struct wps_data *wps_data,
}
}
-int wps_subline_index(struct wps_data *data, int line, int subline)
+int wps_subline_index(struct wps_data *data, int v, int line, int subline)
{
- return data->lines[line].first_subline_idx + subline;
+ return data->viewports[v].lines[line].first_subline_idx + subline;
}
-int wps_first_token_index(struct wps_data *data, int line, int subline)
+int wps_first_token_index(struct wps_data *data, int v, int line, int subline)
{
- int first_subline_idx = data->lines[line].first_subline_idx;
+ int first_subline_idx = data->viewports[v].lines[line].first_subline_idx;
return data->sublines[first_subline_idx + subline].first_token_idx;
}
-int wps_last_token_index(struct wps_data *data, int line, int subline)
+int wps_last_token_index(struct wps_data *data, int v, int line, int subline)
{
- int first_subline_idx = data->lines[line].first_subline_idx;
+ int first_subline_idx = data->viewports[v].lines[line].first_subline_idx;
int idx = first_subline_idx + subline;
if (idx < data->num_sublines - 1)
{
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)
void peak_meter_screen(struct screen *display, int x, int y, int height)
{
peak_meter_draw(display, &scales[display->screen_type], x, y,
- display->width - x, height);
+ display->getwidth() - x, height);
}
/**
* Draws a peak meter in the specified size at the specified position.
* @param int x - The x coordinate.
- * Make sure that 0 <= x and x + width < display->width
+ * Make sure that 0 <= x and x + width < display->getwidth()
* @param int y - The y coordinate.
- * Make sure that 0 <= y and y + height < display->height
+ * Make sure that 0 <= y and y + height < display->getheight()
* @param int width - The width of the peak meter. Note that for display
* of clips a 3 pixel wide area is used ->
* width > 3
@@ -1111,7 +1111,7 @@ static void peak_meter_draw(struct screen *display, struct meter_scales *scales,
start_trigx = x+peak_meter_scale_value(trig_strt_threshold,meterwidth);
display->vline(start_trigx, ycenter - 2, ycenter);
start_trigx ++;
- if (start_trigx < display->width ) display->drawpixel(start_trigx, ycenter - 1);
+ if (start_trigx < display->getwidth() ) display->drawpixel(start_trigx, ycenter - 1);
stop_trigx = x + peak_meter_scale_value(trig_stp_threshold,meterwidth);
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)
global_settings.wps_file[0] != 0xff ) {
snprintf(buf, sizeof buf, WPS_DIR "/%s.wps",
global_settings.wps_file);
- wps_data_load(gui_wps[0].data, buf, true);
+ wps_data_load(gui_wps[0].data, &screens[0], buf, true);
}
else
{
@@ -835,7 +835,7 @@ void settings_apply(bool read_disk)
if ( global_settings.rwps_file[0]) {
snprintf(buf, sizeof buf, WPS_DIR "/%s.rwps",
global_settings.rwps_file);
- wps_data_load(gui_wps[1].data, buf, true);
+ wps_data_load(gui_wps[1].data, &screens[1], buf, true);
}
else
{