1
0
Fork 0
forked from len0rd/rockbox

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
This commit is contained in:
Dave Chapman 2008-03-21 19:38:00 +00:00
parent 1544b36966
commit d02c79c03f
7 changed files with 360 additions and 165 deletions

View file

@ -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;

View file

@ -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;
display->set_viewport(&data->viewports[v].vp);
/* 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;
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);
}
/* peakmeter */
if (flags & refresh_mode & WPS_REFRESH_PEAK_METER)
{
/* the peakmeter should be alone on its line */
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));
}
}
#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);
data->img[i].display = false;
}
#endif
if (update_line)
for (line = 0; line < data->viewports[v].num_lines; line++)
{
if (flags & WPS_REFRESH_SCROLL)
memset(linebuf, 0, sizeof(linebuf));
update_line = false;
/* 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)
{
/* 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);
/* 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));
}
else
write_line(display, &align, line, false);
#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);
}
#endif
if (update_line)
{
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);
}
}
#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

View file

@ -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 */

View file

@ -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));
DEBUGF("Line %2d (num_sublines=%d, first_subline=%d)\n",
i, line->num_sublines, line->first_subline_idx);
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");
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));
DEBUGF("\n");
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");
}
}
}

View file

@ -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)
{

View file

@ -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);

View file

@ -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
{