diff options
Diffstat (limited to 'apps/gui/wps_parser.c')
-rw-r--r-- | apps/gui/wps_parser.c | 179 |
1 files changed, 153 insertions, 26 deletions
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; | |||
69 | #ifdef HAVE_LCD_BITMAP | 69 | #ifdef HAVE_LCD_BITMAP |
70 | 70 | ||
71 | #if LCD_DEPTH > 1 | 71 | #if LCD_DEPTH > 1 |
72 | #define MAX_BITMAPS MAX_IMAGES+2 /* WPS images + pbar bitmap + backdrop */ | 72 | #define MAX_BITMAPS (MAX_IMAGES+2) /* WPS images + pbar bitmap + backdrop */ |
73 | #else | 73 | #else |
74 | #define MAX_BITMAPS MAX_IMAGES+1 /* WPS images + pbar bitmap */ | 74 | #define MAX_BITMAPS (MAX_IMAGES+1) /* WPS images + pbar bitmap */ |
75 | #endif | 75 | #endif |
76 | 76 | ||
77 | #define PROGRESSBAR_BMP MAX_IMAGES | 77 | #define PROGRESSBAR_BMP MAX_IMAGES |
78 | #define BACKDROP_BMP MAX_IMAGES+1 | 78 | #define BACKDROP_BMP (MAX_IMAGES+1) |
79 | 79 | ||
80 | /* pointers to the bitmap filenames in the WPS source */ | 80 | /* pointers to the bitmap filenames in the WPS source */ |
81 | static const char *bmp_names[MAX_BITMAPS]; | 81 | static const char *bmp_names[MAX_BITMAPS]; |
@@ -118,6 +118,8 @@ static int parse_dir_level(const char *wps_bufptr, | |||
118 | struct wps_token *token, struct wps_data *wps_data); | 118 | struct wps_token *token, struct wps_data *wps_data); |
119 | 119 | ||
120 | #ifdef HAVE_LCD_BITMAP | 120 | #ifdef HAVE_LCD_BITMAP |
121 | static int parse_viewport(const char *wps_bufptr, | ||
122 | struct wps_token *token, struct wps_data *wps_data); | ||
121 | static int parse_leftmargin(const char *wps_bufptr, | 123 | static int parse_leftmargin(const char *wps_bufptr, |
122 | struct wps_token *token, struct wps_data *wps_data); | 124 | struct wps_token *token, struct wps_data *wps_data); |
123 | static int parse_image_special(const char *wps_bufptr, | 125 | static int parse_image_special(const char *wps_bufptr, |
@@ -131,7 +133,6 @@ static int parse_image_display(const char *wps_bufptr, | |||
131 | static int parse_image_load(const char *wps_bufptr, | 133 | static int parse_image_load(const char *wps_bufptr, |
132 | struct wps_token *token, struct wps_data *wps_data); | 134 | struct wps_token *token, struct wps_data *wps_data); |
133 | #endif /*HAVE_LCD_BITMAP */ | 135 | #endif /*HAVE_LCD_BITMAP */ |
134 | |||
135 | #ifdef HAVE_ALBUMART | 136 | #ifdef HAVE_ALBUMART |
136 | static int parse_albumart_load(const char *wps_bufptr, | 137 | static int parse_albumart_load(const char *wps_bufptr, |
137 | struct wps_token *token, struct wps_data *wps_data); | 138 | struct wps_token *token, struct wps_data *wps_data); |
@@ -311,6 +312,9 @@ static const struct wps_tag all_tags[] = { | |||
311 | { WPS_TOKEN_ALBUMART_DISPLAY, "C", WPS_REFRESH_STATIC, | 312 | { WPS_TOKEN_ALBUMART_DISPLAY, "C", WPS_REFRESH_STATIC, |
312 | parse_albumart_conditional }, | 313 | parse_albumart_conditional }, |
313 | #endif | 314 | #endif |
315 | |||
316 | { WPS_NO_TOKEN, "V", 0, parse_viewport }, | ||
317 | |||
314 | #if (LCD_DEPTH > 1) || (defined(HAVE_LCD_REMOTE) && (LCD_REMOTE_DEPTH > 1)) | 318 | #if (LCD_DEPTH > 1) || (defined(HAVE_LCD_REMOTE) && (LCD_REMOTE_DEPTH > 1)) |
315 | { WPS_TOKEN_IMAGE_BACKDROP, "X", 0, parse_image_special }, | 319 | { WPS_TOKEN_IMAGE_BACKDROP, "X", 0, parse_image_special }, |
316 | #endif | 320 | #endif |
@@ -334,9 +338,11 @@ static int skip_end_of_line(const char *wps_bufptr) | |||
334 | /* Starts a new subline in the current line during parsing */ | 338 | /* Starts a new subline in the current line during parsing */ |
335 | static void wps_start_new_subline(struct wps_data *data) | 339 | static void wps_start_new_subline(struct wps_data *data) |
336 | { | 340 | { |
341 | struct wps_viewport* vp = &data->viewports[data->num_viewports]; | ||
342 | |||
337 | data->num_sublines++; | 343 | data->num_sublines++; |
338 | data->sublines[data->num_sublines].first_token_idx = data->num_tokens; | 344 | data->sublines[data->num_sublines].first_token_idx = data->num_tokens; |
339 | data->lines[data->num_lines].num_sublines++; | 345 | vp->lines[vp->num_lines].num_sublines++; |
340 | } | 346 | } |
341 | 347 | ||
342 | #ifdef HAVE_LCD_BITMAP | 348 | #ifdef HAVE_LCD_BITMAP |
@@ -482,6 +488,9 @@ static int parse_image_load(const char *wps_bufptr, | |||
482 | wps_data->img[n].x = x; | 488 | wps_data->img[n].x = x; |
483 | wps_data->img[n].y = y; | 489 | wps_data->img[n].y = y; |
484 | 490 | ||
491 | /* save current viewport */ | ||
492 | wps_data->img[n].vp = &wps_data->viewports[wps_data->num_viewports].vp; | ||
493 | |||
485 | if (token->type == WPS_TOKEN_IMAGE_DISPLAY) | 494 | if (token->type == WPS_TOKEN_IMAGE_DISPLAY) |
486 | wps_data->img[n].always_display = true; | 495 | wps_data->img[n].always_display = true; |
487 | 496 | ||
@@ -489,6 +498,110 @@ static int parse_image_load(const char *wps_bufptr, | |||
489 | return skip_end_of_line(wps_bufptr); | 498 | return skip_end_of_line(wps_bufptr); |
490 | } | 499 | } |
491 | 500 | ||
501 | static int parse_viewport(const char *wps_bufptr, | ||
502 | struct wps_token *token, | ||
503 | struct wps_data *wps_data) | ||
504 | { | ||
505 | const char *ptr = wps_bufptr; | ||
506 | struct viewport* vp; | ||
507 | int depth; | ||
508 | |||
509 | (void)token; /* Kill warnings */ | ||
510 | |||
511 | if (*wps_bufptr != '|') | ||
512 | return WPS_ERROR_INVALID_PARAM; /* malformed token: e.g. %Cl7 */ | ||
513 | |||
514 | ptr = wps_bufptr + 1; | ||
515 | /* format: %V|x|y|width|height|fg_pattern|bg_pattern| */ | ||
516 | |||
517 | if (wps_data->num_viewports >= WPS_MAX_VIEWPORTS) | ||
518 | return WPS_ERROR_INVALID_PARAM; | ||
519 | |||
520 | wps_data->num_viewports++; | ||
521 | vp = &wps_data->viewports[wps_data->num_viewports].vp; | ||
522 | |||
523 | /* Set the defaults for fields not user-specified */ | ||
524 | vp->drawmode = DRMODE_SOLID; | ||
525 | vp->xmargin = 0; | ||
526 | vp->ymargin = 0; | ||
527 | |||
528 | /* Work out the depth of this display */ | ||
529 | #ifdef HAVE_REMOTE_LCD | ||
530 | depth = (wps_data->remote_wps ? LCD_REMOTE_DEPTH : LCD_DEPTH); | ||
531 | #else | ||
532 | depth = LCD_DEPTH; | ||
533 | #endif | ||
534 | |||
535 | #ifdef HAVE_LCD_COLOR | ||
536 | if (depth == 16) | ||
537 | { | ||
538 | parse_list("dddddcc", '|', ptr, &vp->x, &vp->y, &vp->width, | ||
539 | &vp->height, &vp->font, &vp->fg_pattern,&vp->bg_pattern); | ||
540 | } | ||
541 | else | ||
542 | #endif | ||
543 | #if (LCD_DEPTH == 2) || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH == 2) | ||
544 | if (depth == 2) { | ||
545 | parse_list("dddddgg", '|', ptr, &vp->x, &vp->y, &vp->width, | ||
546 | &vp->height, &vp->font, &vp->fg_pattern, &vp->bg_pattern); | ||
547 | } | ||
548 | else | ||
549 | #endif | ||
550 | #if (LCD_DEPTH == 1) || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH == 1) | ||
551 | if (depth == 1) | ||
552 | { | ||
553 | parse_list("ddddd", '|', ptr, &vp->x, &vp->y, &vp->width, &vp->height, | ||
554 | &vp->font); | ||
555 | } | ||
556 | else | ||
557 | #endif | ||
558 | {} | ||
559 | |||
560 | /* Default to using the user font if the font was an invalid number */ | ||
561 | if ((vp->font != FONT_SYSFIXED) && (vp->font != FONT_UI)) | ||
562 | vp->font = FONT_UI; | ||
563 | |||
564 | /* Validate the viewport dimensions - we know that the numbers are | ||
565 | non-negative integers */ | ||
566 | #ifdef HAVE_REMOTE_LCD | ||
567 | if (wps_data->remote_wps) | ||
568 | { | ||
569 | if ((vp->x >= LCD_REMOTE_WIDTH) || | ||
570 | ((vp->x + vp->width) >= LCD_REMOTE_WIDTH) || | ||
571 | (vp->y >= LCD_REMOTE_HEIGHT) || | ||
572 | ((vp->y + vp->height) >= LCD_REMOTE_HEIGHT)) | ||
573 | { | ||
574 | return WPS_ERROR_INVALID_PARAM; | ||
575 | } | ||
576 | } | ||
577 | else | ||
578 | #else | ||
579 | { | ||
580 | if ((vp->x >= LCD_WIDTH) || | ||
581 | (vp->y >= LCD_HEIGHT) || | ||
582 | ((vp->y + vp->height) >= LCD_HEIGHT)) | ||
583 | { | ||
584 | return WPS_ERROR_INVALID_PARAM; | ||
585 | } | ||
586 | } | ||
587 | #endif | ||
588 | |||
589 | wps_data->viewports[wps_data->num_viewports].num_lines = 0; | ||
590 | |||
591 | if (wps_data->num_sublines < WPS_MAX_SUBLINES) | ||
592 | { | ||
593 | wps_data->viewports[wps_data->num_viewports].lines[0].first_subline_idx = | ||
594 | wps_data->num_sublines; | ||
595 | |||
596 | wps_data->sublines[wps_data->num_sublines].first_token_idx = | ||
597 | wps_data->num_tokens; | ||
598 | } | ||
599 | |||
600 | /* Skip the rest of the line */ | ||
601 | return skip_end_of_line(wps_bufptr); | ||
602 | } | ||
603 | |||
604 | |||
492 | static int parse_image_special(const char *wps_bufptr, | 605 | static int parse_image_special(const char *wps_bufptr, |
493 | struct wps_token *token, | 606 | struct wps_token *token, |
494 | struct wps_data *wps_data) | 607 | struct wps_data *wps_data) |
@@ -958,7 +1071,8 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr) | |||
958 | level = -1; | 1071 | level = -1; |
959 | 1072 | ||
960 | while(*wps_bufptr && !fail && data->num_tokens < WPS_MAX_TOKENS - 1 | 1073 | while(*wps_bufptr && !fail && data->num_tokens < WPS_MAX_TOKENS - 1 |
961 | && data->num_lines < WPS_MAX_LINES) | 1074 | && data->num_viewports < WPS_MAX_VIEWPORTS |
1075 | && data->viewports[data->num_viewports].num_lines < WPS_MAX_LINES) | ||
962 | { | 1076 | { |
963 | switch(*wps_bufptr++) | 1077 | switch(*wps_bufptr++) |
964 | { | 1078 | { |
@@ -1066,12 +1180,12 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr) | |||
1066 | 1180 | ||
1067 | line++; | 1181 | line++; |
1068 | wps_start_new_subline(data); | 1182 | wps_start_new_subline(data); |
1069 | data->num_lines++; /* Start a new line */ | 1183 | data->viewports[data->num_viewports].num_lines++; /* Start a new line */ |
1070 | 1184 | ||
1071 | if ((data->num_lines < WPS_MAX_LINES) && | 1185 | if ((data->viewports[data->num_viewports].num_lines < WPS_MAX_LINES) && |
1072 | (data->num_sublines < WPS_MAX_SUBLINES)) | 1186 | (data->num_sublines < WPS_MAX_SUBLINES)) |
1073 | { | 1187 | { |
1074 | data->lines[data->num_lines].first_subline_idx = | 1188 | data->viewports[data->num_viewports].lines[data->viewports[data->num_viewports].num_lines].first_subline_idx = |
1075 | data->num_sublines; | 1189 | data->num_sublines; |
1076 | 1190 | ||
1077 | data->sublines[data->num_sublines].first_token_idx = | 1191 | data->sublines[data->num_sublines].first_token_idx = |
@@ -1148,6 +1262,9 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr) | |||
1148 | if (!fail && level >= 0) /* there are unclosed conditionals */ | 1262 | if (!fail && level >= 0) /* there are unclosed conditionals */ |
1149 | fail = PARSE_FAIL_UNCLOSED_COND; | 1263 | fail = PARSE_FAIL_UNCLOSED_COND; |
1150 | 1264 | ||
1265 | /* We have finished with the last viewport, so increment count */ | ||
1266 | data->num_viewports++; | ||
1267 | |||
1151 | #ifdef DEBUG | 1268 | #ifdef DEBUG |
1152 | print_debug_info(data, fail, line); | 1269 | print_debug_info(data, fail, line); |
1153 | #endif | 1270 | #endif |
@@ -1212,16 +1329,6 @@ static void wps_reset(struct wps_data *data) | |||
1212 | 1329 | ||
1213 | #ifdef HAVE_LCD_BITMAP | 1330 | #ifdef HAVE_LCD_BITMAP |
1214 | 1331 | ||
1215 | |||
1216 | static void clear_bmp_names(void) | ||
1217 | { | ||
1218 | int n; | ||
1219 | for (n = 0; n < MAX_BITMAPS; n++) | ||
1220 | { | ||
1221 | bmp_names[n] = NULL; | ||
1222 | } | ||
1223 | } | ||
1224 | |||
1225 | static void load_wps_bitmaps(struct wps_data *wps_data, char *bmpdir) | 1332 | static void load_wps_bitmaps(struct wps_data *wps_data, char *bmpdir) |
1226 | { | 1333 | { |
1227 | char img_path[MAX_PATH]; | 1334 | char img_path[MAX_PATH]; |
@@ -1291,6 +1398,7 @@ static char *skip_utf8_bom(char *buf) | |||
1291 | /* to setup up the wps-data from a format-buffer (isfile = false) | 1398 | /* to setup up the wps-data from a format-buffer (isfile = false) |
1292 | from a (wps-)file (isfile = true)*/ | 1399 | from a (wps-)file (isfile = true)*/ |
1293 | bool wps_data_load(struct wps_data *wps_data, | 1400 | bool wps_data_load(struct wps_data *wps_data, |
1401 | struct screen *display, | ||
1294 | const char *buf, | 1402 | const char *buf, |
1295 | bool isfile) | 1403 | bool isfile) |
1296 | { | 1404 | { |
@@ -1299,6 +1407,24 @@ bool wps_data_load(struct wps_data *wps_data, | |||
1299 | 1407 | ||
1300 | wps_reset(wps_data); | 1408 | wps_reset(wps_data); |
1301 | 1409 | ||
1410 | /* Initialise the first (default) viewport */ | ||
1411 | wps_data->viewports[0].vp.x = 0; | ||
1412 | wps_data->viewports[0].vp.y = 0; | ||
1413 | wps_data->viewports[0].vp.width = display->width; | ||
1414 | wps_data->viewports[0].vp.height = display->height; | ||
1415 | #ifdef HAVE_LCD_BITMAP | ||
1416 | wps_data->viewports[0].vp.font = FONT_UI; | ||
1417 | wps_data->viewports[0].vp.drawmode = DRMODE_SOLID; | ||
1418 | #endif | ||
1419 | wps_data->viewports[0].vp.xmargin = display->getxmargin(); | ||
1420 | wps_data->viewports[0].vp.ymargin = display->getymargin(); | ||
1421 | #if LCD_DEPTH > 1 | ||
1422 | if (display->depth > 1) | ||
1423 | { | ||
1424 | wps_data->viewports[0].vp.fg_pattern = display->get_foreground(); | ||
1425 | wps_data->viewports[0].vp.bg_pattern = display->get_background(); | ||
1426 | } | ||
1427 | #endif | ||
1302 | if (!isfile) | 1428 | if (!isfile) |
1303 | { | 1429 | { |
1304 | return wps_parse(wps_data, buf); | 1430 | return wps_parse(wps_data, buf); |
@@ -1357,7 +1483,8 @@ bool wps_data_load(struct wps_data *wps_data, | |||
1357 | return false; | 1483 | return false; |
1358 | 1484 | ||
1359 | #ifdef HAVE_LCD_BITMAP | 1485 | #ifdef HAVE_LCD_BITMAP |
1360 | clear_bmp_names(); | 1486 | /* Set all filename pointers to NULL */ |
1487 | memset(bmp_names, sizeof(bmp_names), 0); | ||
1361 | #endif | 1488 | #endif |
1362 | 1489 | ||
1363 | /* Skip leading UTF-8 BOM, if present. */ | 1490 | /* Skip leading UTF-8 BOM, if present. */ |
@@ -1385,20 +1512,20 @@ bool wps_data_load(struct wps_data *wps_data, | |||
1385 | } | 1512 | } |
1386 | } | 1513 | } |
1387 | 1514 | ||
1388 | int wps_subline_index(struct wps_data *data, int line, int subline) | 1515 | int wps_subline_index(struct wps_data *data, int v, int line, int subline) |
1389 | { | 1516 | { |
1390 | return data->lines[line].first_subline_idx + subline; | 1517 | return data->viewports[v].lines[line].first_subline_idx + subline; |
1391 | } | 1518 | } |
1392 | 1519 | ||
1393 | int wps_first_token_index(struct wps_data *data, int line, int subline) | 1520 | int wps_first_token_index(struct wps_data *data, int v, int line, int subline) |
1394 | { | 1521 | { |
1395 | int first_subline_idx = data->lines[line].first_subline_idx; | 1522 | int first_subline_idx = data->viewports[v].lines[line].first_subline_idx; |
1396 | return data->sublines[first_subline_idx + subline].first_token_idx; | 1523 | return data->sublines[first_subline_idx + subline].first_token_idx; |
1397 | } | 1524 | } |
1398 | 1525 | ||
1399 | int wps_last_token_index(struct wps_data *data, int line, int subline) | 1526 | int wps_last_token_index(struct wps_data *data, int v, int line, int subline) |
1400 | { | 1527 | { |
1401 | int first_subline_idx = data->lines[line].first_subline_idx; | 1528 | int first_subline_idx = data->viewports[v].lines[line].first_subline_idx; |
1402 | int idx = first_subline_idx + subline; | 1529 | int idx = first_subline_idx + subline; |
1403 | if (idx < data->num_sublines - 1) | 1530 | if (idx < data->num_sublines - 1) |
1404 | { | 1531 | { |