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 #if LCD_DEPTH > 1
unload_wps_backdrop(); unload_wps_backdrop();
#endif #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, set_file(buf, (char *)global_settings.wps_file,
MAX_FILENAME); MAX_FILENAME);
break; break;
@ -490,7 +490,7 @@ int ft_enter(struct tree_context* c)
#if defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1 #if defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1
unload_remote_wps_backdrop(); unload_remote_wps_backdrop();
#endif #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, set_file(buf, (char *)global_settings.rwps_file,
MAX_FILENAME); MAX_FILENAME);
break; break;

View file

@ -295,6 +295,19 @@ bool gui_wps_display(void)
{ {
FOR_NB_SCREENS(i) 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(); gui_wps[i].display->clear_display();
if (!gui_wps[i].data->wps_loaded) { if (!gui_wps[i].data->wps_loaded) {
if ( !gui_wps[i].data->num_tokens ) { if ( !gui_wps[i].data->num_tokens ) {
@ -306,6 +319,7 @@ bool gui_wps_display(void)
unload_wps_backdrop(); unload_wps_backdrop();
#endif #endif
wps_data_load(gui_wps[i].data, wps_data_load(gui_wps[i].data,
gui_wps[i].display,
"%s%?it<%?in<%in. |>%it|%fn>\n" "%s%?it<%?in<%in. |>%it|%fn>\n"
"%s%?ia<%ia|%?d2<%d2|(root)>>\n" "%s%?ia<%ia|%?d2<%d2|(root)>>\n"
"%s%?id<%id|%?d1<%d1|(root)>> %?iy<(%iy)|>\n" "%s%?id<%id|%?d1<%d1|(root)>> %?iy<(%iy)|>\n"
@ -316,6 +330,7 @@ bool gui_wps_display(void)
"%pm\n", false); "%pm\n", false);
#else #else
wps_data_load(gui_wps[i].data, wps_data_load(gui_wps[i].data,
gui_wps[i].display,
"%s%pp/%pe: %?it<%it|%fn> - %?ia<%ia|%d2> - %?id<%id|%d1>\n" "%s%pp/%pe: %?it<%it|%fn> - %?ia<%ia|%d2> - %?id<%id|%d1>\n"
"%pc%?ps<*|/>%pt\n", false); "%pc%?ps<*|/>%pt\n", false);
#endif #endif
@ -328,6 +343,7 @@ bool gui_wps_display(void)
unload_remote_wps_backdrop(); unload_remote_wps_backdrop();
#endif #endif
wps_data_load(gui_wps[i].data, wps_data_load(gui_wps[i].data,
gui_wps[i].display,
"%s%?ia<%ia|%?d2<%d2|(root)>>\n" "%s%?ia<%ia|%?d2<%d2|(root)>>\n"
"%s%?it<%?in<%in. |>%it|%fn>\n" "%s%?it<%?in<%in. |>%it|%fn>\n"
"%al%pc/%pt%ar[%pp:%pe]\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 wps_data *data = gwps->data;
struct screen *display = gwps->display; struct screen *display = gwps->display;
struct wps_state *state = gwps->state; struct wps_state *state = gwps->state;
int h = font_get(FONT_UI)->height; int h = font_get(display->getfont())->height;
int sb_y; int sb_y;
if (data->progress_top < 0) if (data->progress_top < 0)
@ -459,7 +475,7 @@ static void draw_progressbar(struct gui_wps *gwps, int line)
sb_y = data->progress_top; sb_y = data->progress_top;
if (!data->progress_end) if (!data->progress_end)
data->progress_end=display->width; data->progress_end=display->getwidth();
if (gwps->data->progressbar.have_bitmap_pb) if (gwps->data->progressbar.have_bitmap_pb)
gui_bitmap_scrollbar_draw(display, data->progressbar.bm, gui_bitmap_scrollbar_draw(display, data->progressbar.bm,
@ -529,7 +545,7 @@ static void wps_draw_image(struct gui_wps *gwps, int n)
#endif #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) if(!gwps || !gwps->data || !gwps->display)
return; return;
@ -541,7 +557,8 @@ static void wps_display_images(struct gui_wps *gwps)
for (n = 0; n < MAX_IMAGES; n++) for (n = 0; n < MAX_IMAGES; n++)
{ {
if (data->img[n].loaded && 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); 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. The return value indicates whether the line needs to be updated.
*/ */
static bool get_line(struct gui_wps *gwps, static bool get_line(struct gui_wps *gwps,
int line, int subline, int v, int line, int subline,
struct align_pos *align, struct align_pos *align,
char *linebuf, char *linebuf,
int linebuf_size) int linebuf_size)
@ -1477,8 +1494,8 @@ static bool get_line(struct gui_wps *gwps,
#endif #endif
/* Process all tokens of the desired subline */ /* Process all tokens of the desired subline */
last_token_idx = wps_last_token_index(data, line, subline); last_token_idx = wps_last_token_index(data, v, line, subline);
for (i = wps_first_token_index(data, line, subline); for (i = wps_first_token_index(data, v, line, subline);
i <= last_token_idx; i++) i <= last_token_idx; i++)
{ {
switch(data->tokens[i].type) switch(data->tokens[i].type)
@ -1577,16 +1594,16 @@ static bool get_line(struct gui_wps *gwps,
return update; 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; struct wps_data *data = gwps->data;
int i; int i;
int subline_idx = wps_subline_index(data, line, subline); int subline_idx = wps_subline_index(data, v, line, subline);
int last_token_idx = wps_last_token_index(data, line, subline); int last_token_idx = wps_last_token_index(data, v, line, subline);
data->sublines[subline_idx].time_mult = DEFAULT_SUBLINE_TIME_MULTIPLIER; 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++) i <= last_token_idx; i++)
{ {
switch(data->tokens[i].type) 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 /* Calculates which subline should be displayed for the specified line
Returns true iff the subline must be refreshed */ 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; 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 new_subline_refresh;
bool only_one_subline; bool only_one_subline;
num_sublines = data->lines[line].num_sublines; num_sublines = data->viewports[v].lines[line].num_sublines;
reset_subline = (data->lines[line].curr_subline == SUBLINE_RESET); reset_subline = (data->viewports[v].lines[line].curr_subline == SUBLINE_RESET);
new_subline_refresh = false; new_subline_refresh = false;
only_one_subline = false; only_one_subline = false;
/* if time to advance to next sub-line */ /* 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) reset_subline)
{ {
/* search all sublines until the next subline with time > 0 /* 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) if (reset_subline)
search_start = 0; search_start = 0;
else else
search_start = data->lines[line].curr_subline; search_start = data->viewports[v].lines[line].curr_subline;
for (search = 0; search < num_sublines; search++) 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 */ /* 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; 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 /* if back where we started after search or
only one subline is defined on the line */ only one subline is defined on the line */
if (((search > 0) && if (((search > 0) &&
(data->lines[line].curr_subline == search_start)) || (data->viewports[v].lines[line].curr_subline == search_start)) ||
only_one_subline) only_one_subline)
{ {
/* no other subline with a time > 0 exists */ /* 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 : current_tick :
data->lines[line].subline_expire_time) + 100 * HZ; data->viewports[v].lines[line].subline_expire_time) + 100 * HZ;
break; break;
} }
else else
{ {
/* get initial time multiplier for this subline */ /* 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, int subline_idx = wps_subline_index(data, v, line,
data->lines[line].curr_subline); data->viewports[v].lines[line].curr_subline);
/* only use this subline if subline time > 0 */ /* only use this subline if subline time > 0 */
if (data->sublines[subline_idx].time_mult > 0) if (data->sublines[subline_idx].time_mult > 0)
{ {
new_subline_refresh = true; new_subline_refresh = true;
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) + current_tick : data->viewports[v].lines[line].subline_expire_time) +
BASE_SUBLINE_TIME*data->sublines[subline_idx].time_mult; BASE_SUBLINE_TIME*data->sublines[subline_idx].time_mult;
break; break;
} }
@ -1724,10 +1741,10 @@ static void write_line(struct screen *display,
} }
left_xpos = display->getxmargin(); left_xpos = display->getxmargin();
right_xpos = (display->width - right_width); right_xpos = (display->getwidth() - right_width);
center_xpos = (display->width + left_xpos - center_width) / 2; 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. /* Checks for overlapping strings.
If needed the overlapping strings will be merged, separated by a 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; format_align->right = format_align->center;
/* calculate the new width and position of the merged string */ /* calculate the new width and position of the merged string */
right_width = center_width + space_width + right_width; 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 */ /* there is no centered string anymore */
center_width = 0; center_width = 0;
} }
@ -1778,7 +1795,7 @@ static void write_line(struct screen *display,
format_align->right = format_align->center; format_align->right = format_align->center;
/* calculate the new width and position of the string */ /* calculate the new width and position of the string */
right_width = center_width; right_width = center_width;
right_xpos = (display->width - right_width); right_xpos = (display->getwidth() - right_width);
/* there is no centered string anymore */ /* there is no centered string anymore */
center_width = 0; center_width = 0;
} }
@ -1823,7 +1840,7 @@ static void write_line(struct screen *display,
#ifdef HAVE_LCD_BITMAP #ifdef HAVE_LCD_BITMAP
/* clear the line first */ /* clear the line first */
display->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); 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); display->set_drawmode(DRMODE_SOLID);
#endif #endif
@ -1862,7 +1879,7 @@ bool gui_wps_refresh(struct gui_wps *gwps,
if(!gwps || !data || !state || !display) if(!gwps || !data || !state || !display)
return false; return false;
int line, i, subline_idx; int v, line, i, subline_idx;
unsigned char flags; unsigned char flags;
char linebuf[MAX_PATH]; char linebuf[MAX_PATH];
@ -1885,19 +1902,19 @@ bool gui_wps_refresh(struct gui_wps *gwps,
*/ */
bool enable_pm = false; bool enable_pm = false;
/* Set images to not to be displayed */
for (i = 0; i < MAX_IMAGES; i++)
{
data->img[i].display = false;
}
#endif #endif
/* reset to first subline if refresh all flag is set */ /* reset to first subline if refresh all flag is set */
if (refresh_mode == WPS_REFRESH_ALL) 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,23 +1934,40 @@ bool gui_wps_refresh(struct gui_wps *gwps,
state->ff_rewind_count = ffwd_offset; state->ff_rewind_count = ffwd_offset;
for (line = 0; line < data->num_lines; line++) for (v = 0; v < data->num_viewports; v++)
{
display->set_viewport(&data->viewports[v].vp);
if (refresh_mode == WPS_REFRESH_ALL)
{
display->clear_viewport();
}
#ifdef HAVE_LCD_BITMAP
/* Set images to not to be displayed */
for (i = 0; i < MAX_IMAGES; i++)
{
data->img[i].display = false;
}
#endif
for (line = 0; line < data->viewports[v].num_lines; line++)
{ {
memset(linebuf, 0, sizeof(linebuf)); memset(linebuf, 0, sizeof(linebuf));
update_line = false; update_line = false;
/* get current subline for the line */ /* get current subline for the line */
new_subline_refresh = update_curr_subline(gwps, line); new_subline_refresh = update_curr_subline(gwps, v, line);
subline_idx = wps_subline_index(data, line, subline_idx = wps_subline_index(data, v, line,
data->lines[line].curr_subline); data->viewports[v].lines[line].curr_subline);
flags = data->sublines[subline_idx].line_type; flags = data->sublines[subline_idx].line_type;
if (refresh_mode == WPS_REFRESH_ALL || (flags & refresh_mode) if (refresh_mode == WPS_REFRESH_ALL || (flags & refresh_mode)
|| new_subline_refresh) || new_subline_refresh)
{ {
/* get_line tells us if we need to update the line */ /* get_line tells us if we need to update the line */
update_line = get_line(gwps, line, data->lines[line].curr_subline, update_line = get_line(gwps, v, line, data->viewports[v].lines[line].curr_subline,
&align, linebuf, sizeof(linebuf)); &align, linebuf, sizeof(linebuf));
} }
@ -1952,19 +1986,19 @@ bool gui_wps_refresh(struct gui_wps *gwps,
/* the peakmeter should be alone on its line */ /* the peakmeter should be alone on its line */
update_line = false; update_line = false;
int h = font_get(FONT_UI)->height; int h = font_get(display->getfont())->height;
int peak_meter_y = display->getymargin() + line * h; int peak_meter_y = display->getymargin() + line * h;
/* The user might decide to have the peak meter in the last /* The user might decide to have the peak meter in the last
line so that it is only displayed if no status bar is line so that it is only displayed if no status bar is
visible. If so we neither want do draw nor enable the visible. If so we neither want do draw nor enable the
peak meter. */ peak meter. */
if (peak_meter_y + h <= display->height) { if (peak_meter_y + h <= display->getheight()) {
/* found a line with a peak meter -> remember that we must /* found a line with a peak meter -> remember that we must
enable it later */ enable it later */
enable_pm = true; enable_pm = true;
peak_meter_screen(gwps->display, 0, peak_meter_y, peak_meter_screen(gwps->display, 0, peak_meter_y,
MIN(h, display->height - peak_meter_y)); MIN(h, display->getheight() - peak_meter_y));
} }
} }
@ -1992,13 +2026,22 @@ bool gui_wps_refresh(struct gui_wps *gwps,
else else
write_line(display, &align, line, false); 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 #ifdef HAVE_LCD_BITMAP
data->peak_meter_enabled = enable_pm; data->peak_meter_enabled = enable_pm;
wps_display_images(gwps);
#endif #endif
/* Restore the default viewport */
display->set_viewport(NULL);
display->update(); display->update();
#ifdef HAVE_BACKLIGHT #ifdef HAVE_BACKLIGHT

View file

@ -61,6 +61,7 @@
#ifdef HAVE_LCD_BITMAP #ifdef HAVE_LCD_BITMAP
struct gui_img{ struct gui_img{
struct bitmap bm; struct bitmap bm;
struct viewport* vp; /* The viewport to display this image in */
int x; /* x-pos */ int x; /* x-pos */
int y; /* y-pos */ int y; /* y-pos */
bool loaded; /* load state */ bool loaded; /* load state */
@ -86,6 +87,7 @@ struct align_pos {
#define IMG_BUFSIZE ((LCD_HEIGHT*LCD_WIDTH*LCD_DEPTH/8) \ #define IMG_BUFSIZE ((LCD_HEIGHT*LCD_WIDTH*LCD_DEPTH/8) \
+ (2*LCD_HEIGHT*LCD_WIDTH/8)) + (2*LCD_HEIGHT*LCD_WIDTH/8))
#define WPS_MAX_VIEWPORTS 16
#define WPS_MAX_LINES (LCD_HEIGHT/5+1) #define WPS_MAX_LINES (LCD_HEIGHT/5+1)
#define WPS_MAX_SUBLINES (WPS_MAX_LINES*3) #define WPS_MAX_SUBLINES (WPS_MAX_LINES*3)
#define WPS_MAX_TOKENS 1024 #define WPS_MAX_TOKENS 1024
@ -95,6 +97,7 @@ struct align_pos {
#else #else
#define WPS_MAX_VIEWPORTS 2
#define WPS_MAX_LINES 2 #define WPS_MAX_LINES 2
#define WPS_MAX_SUBLINES 12 #define WPS_MAX_SUBLINES 12
#define WPS_MAX_TOKENS 64 #define WPS_MAX_TOKENS 64
@ -315,6 +318,14 @@ struct wps_line {
long subline_expire_time; 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 /* wps_data
this struct holds all necessary data which describes the this struct holds all necessary data which describes the
@ -360,10 +371,9 @@ struct wps_data
bool remote_wps; bool remote_wps;
#endif #endif
/* Number of lines in the WPS. During WPS parsing, this is /* Number of viewports in the WPS */
the index of the line being parsed. */ int num_viewports;
int num_lines; struct wps_viewport viewports[WPS_MAX_VIEWPORTS];
struct wps_line lines[WPS_MAX_LINES];
/* Total number of sublines in the WPS. During WPS parsing, this is /* Total number of sublines in the WPS. During WPS parsing, this is
the index of the subline where the parsed tokens are added to. */ 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) /* to setup up the wps-data from a format-buffer (isfile = false)
from a (wps-)file (isfile = true)*/ from a (wps-)file (isfile = true)*/
bool wps_data_load(struct wps_data *wps_data, bool wps_data_load(struct wps_data *wps_data,
struct screen *display,
const char *buf, const char *buf,
bool isfile); bool isfile);
/* Returns the index of the subline in the subline array /* Returns the index of the subline in the subline array
v - 0-based viewport number
line - 0-based line number line - 0-based line number
subline - 0-based subline number within the line 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 /* Returns the index of the first subline's token in the token array
v - 0-based viewport number
line - 0-based line number line - 0-based line number
subline - 0-based subline number within the line 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. /* Returns the index of the last subline's token in the token array.
v - 0-based viewport number
line - 0-based line number line - 0-based line number
subline - 0-based subline number within the line 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 */ /* wps_data end */

View file

@ -493,21 +493,31 @@ static void dump_wps_tokens(struct wps_data *data)
static void print_line_info(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_line *line;
struct wps_subline *subline; struct wps_subline *subline;
if (wps_verbose_level > 0) if (wps_verbose_level > 0)
{ {
DEBUGF("Number of lines : %d\n", data->num_lines); DEBUGF("Number of viewports : %d\n", data->num_viewports);
DEBUGF("Number of sublines: %d\n", data->num_sublines); 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("Number of tokens : %d\n", data->num_tokens);
DEBUGF("\n"); DEBUGF("\n");
} }
if (wps_verbose_level > 1) 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("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("Line %2d (num_sublines=%d, first_subline=%d)\n", DEBUGF("Line %2d (num_sublines=%d, first_subline=%d)\n",
i, line->num_sublines, line->first_subline_idx); i, line->num_sublines, line->first_subline_idx);
@ -517,7 +527,7 @@ static void print_line_info(struct wps_data *data)
{ {
DEBUGF(" Subline %d: first_token=%3d, last_token=%3d", DEBUGF(" Subline %d: first_token=%3d, last_token=%3d",
j, subline->first_token_idx, j, subline->first_token_idx,
wps_last_token_index(data, i, j)); wps_last_token_index(data, v, i, j));
if (subline->line_type & WPS_REFRESH_SCROLL) if (subline->line_type & WPS_REFRESH_SCROLL)
DEBUGF(", scrolled"); DEBUGF(", scrolled");
@ -529,6 +539,7 @@ static void print_line_info(struct wps_data *data)
DEBUGF("\n"); DEBUGF("\n");
} }
} }
}
DEBUGF("\n"); DEBUGF("\n");
} }

View file

@ -69,13 +69,13 @@ static int line;
#ifdef HAVE_LCD_BITMAP #ifdef HAVE_LCD_BITMAP
#if LCD_DEPTH > 1 #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 #else
#define MAX_BITMAPS MAX_IMAGES+1 /* WPS images + pbar bitmap */ #define MAX_BITMAPS (MAX_IMAGES+1) /* WPS images + pbar bitmap */
#endif #endif
#define PROGRESSBAR_BMP MAX_IMAGES #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 */ /* pointers to the bitmap filenames in the WPS source */
static const char *bmp_names[MAX_BITMAPS]; 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); struct wps_token *token, struct wps_data *wps_data);
#ifdef HAVE_LCD_BITMAP #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, static int parse_leftmargin(const char *wps_bufptr,
struct wps_token *token, struct wps_data *wps_data); struct wps_token *token, struct wps_data *wps_data);
static int parse_image_special(const char *wps_bufptr, 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, static int parse_image_load(const char *wps_bufptr,
struct wps_token *token, struct wps_data *wps_data); struct wps_token *token, struct wps_data *wps_data);
#endif /*HAVE_LCD_BITMAP */ #endif /*HAVE_LCD_BITMAP */
#ifdef HAVE_ALBUMART #ifdef HAVE_ALBUMART
static int parse_albumart_load(const char *wps_bufptr, static int parse_albumart_load(const char *wps_bufptr,
struct wps_token *token, struct wps_data *wps_data); 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, { WPS_TOKEN_ALBUMART_DISPLAY, "C", WPS_REFRESH_STATIC,
parse_albumart_conditional }, parse_albumart_conditional },
#endif #endif
{ WPS_NO_TOKEN, "V", 0, parse_viewport },
#if (LCD_DEPTH > 1) || (defined(HAVE_LCD_REMOTE) && (LCD_REMOTE_DEPTH > 1)) #if (LCD_DEPTH > 1) || (defined(HAVE_LCD_REMOTE) && (LCD_REMOTE_DEPTH > 1))
{ WPS_TOKEN_IMAGE_BACKDROP, "X", 0, parse_image_special }, { WPS_TOKEN_IMAGE_BACKDROP, "X", 0, parse_image_special },
#endif #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 */ /* Starts a new subline in the current line during parsing */
static void wps_start_new_subline(struct wps_data *data) static void wps_start_new_subline(struct wps_data *data)
{ {
struct wps_viewport* vp = &data->viewports[data->num_viewports];
data->num_sublines++; data->num_sublines++;
data->sublines[data->num_sublines].first_token_idx = data->num_tokens; 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 #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].x = x;
wps_data->img[n].y = y; 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) if (token->type == WPS_TOKEN_IMAGE_DISPLAY)
wps_data->img[n].always_display = true; 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); 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, static int parse_image_special(const char *wps_bufptr,
struct wps_token *token, struct wps_token *token,
struct wps_data *wps_data) struct wps_data *wps_data)
@ -958,7 +1071,8 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr)
level = -1; level = -1;
while(*wps_bufptr && !fail && data->num_tokens < WPS_MAX_TOKENS - 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++) switch(*wps_bufptr++)
{ {
@ -1066,12 +1180,12 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr)
line++; line++;
wps_start_new_subline(data); 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->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->num_sublines;
data->sublines[data->num_sublines].first_token_idx = 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 */ if (!fail && level >= 0) /* there are unclosed conditionals */
fail = PARSE_FAIL_UNCLOSED_COND; fail = PARSE_FAIL_UNCLOSED_COND;
/* We have finished with the last viewport, so increment count */
data->num_viewports++;
#ifdef DEBUG #ifdef DEBUG
print_debug_info(data, fail, line); print_debug_info(data, fail, line);
#endif #endif
@ -1212,16 +1329,6 @@ static void wps_reset(struct wps_data *data)
#ifdef HAVE_LCD_BITMAP #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) static void load_wps_bitmaps(struct wps_data *wps_data, char *bmpdir)
{ {
char img_path[MAX_PATH]; 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) /* to setup up the wps-data from a format-buffer (isfile = false)
from a (wps-)file (isfile = true)*/ from a (wps-)file (isfile = true)*/
bool wps_data_load(struct wps_data *wps_data, bool wps_data_load(struct wps_data *wps_data,
struct screen *display,
const char *buf, const char *buf,
bool isfile) bool isfile)
{ {
@ -1299,6 +1407,24 @@ bool wps_data_load(struct wps_data *wps_data,
wps_reset(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) if (!isfile)
{ {
return wps_parse(wps_data, buf); return wps_parse(wps_data, buf);
@ -1357,7 +1483,8 @@ bool wps_data_load(struct wps_data *wps_data,
return false; return false;
#ifdef HAVE_LCD_BITMAP #ifdef HAVE_LCD_BITMAP
clear_bmp_names(); /* Set all filename pointers to NULL */
memset(bmp_names, sizeof(bmp_names), 0);
#endif #endif
/* Skip leading UTF-8 BOM, if present. */ /* 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; 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; int idx = first_subline_idx + subline;
if (idx < data->num_sublines - 1) 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) void peak_meter_screen(struct screen *display, int x, int y, int height)
{ {
peak_meter_draw(display, &scales[display->screen_type], x, y, 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. * Draws a peak meter in the specified size at the specified position.
* @param int x - The x coordinate. * @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. * @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 * @param int width - The width of the peak meter. Note that for display
* of clips a 3 pixel wide area is used -> * of clips a 3 pixel wide area is used ->
* width > 3 * 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); start_trigx = x+peak_meter_scale_value(trig_strt_threshold,meterwidth);
display->vline(start_trigx, ycenter - 2, ycenter); display->vline(start_trigx, ycenter - 2, ycenter);
start_trigx ++; 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); stop_trigx = x + peak_meter_scale_value(trig_stp_threshold,meterwidth);
display->vline(stop_trigx, ycenter - 2, ycenter); 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 ) { global_settings.wps_file[0] != 0xff ) {
snprintf(buf, sizeof buf, WPS_DIR "/%s.wps", snprintf(buf, sizeof buf, WPS_DIR "/%s.wps",
global_settings.wps_file); 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 else
{ {
@ -835,7 +835,7 @@ void settings_apply(bool read_disk)
if ( global_settings.rwps_file[0]) { if ( global_settings.rwps_file[0]) {
snprintf(buf, sizeof buf, WPS_DIR "/%s.rwps", snprintf(buf, sizeof buf, WPS_DIR "/%s.rwps",
global_settings.rwps_file); 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 else
{ {