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