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:
parent
1544b36966
commit
d02c79c03f
7 changed files with 360 additions and 165 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue