diff options
Diffstat (limited to 'apps/gui/skin_engine/skin_parser.c')
-rw-r--r-- | apps/gui/skin_engine/skin_parser.c | 137 |
1 files changed, 94 insertions, 43 deletions
diff --git a/apps/gui/skin_engine/skin_parser.c b/apps/gui/skin_engine/skin_parser.c index 68bddf6205..f8c9b75a87 100644 --- a/apps/gui/skin_engine/skin_parser.c +++ b/apps/gui/skin_engine/skin_parser.c | |||
@@ -72,11 +72,13 @@ static int condindex[WPS_MAX_COND_LEVEL]; | |||
72 | /* number of condtional options in current level */ | 72 | /* number of condtional options in current level */ |
73 | static int numoptions[WPS_MAX_COND_LEVEL]; | 73 | static int numoptions[WPS_MAX_COND_LEVEL]; |
74 | 74 | ||
75 | /* the current line in the file */ | 75 | /* line number, debug only */ |
76 | static int line; | 76 | static int line_number; |
77 | 77 | ||
78 | /* the current viewport */ | 78 | /* the current viewport */ |
79 | static struct skin_viewport *curr_vp; | 79 | static struct skin_viewport *curr_vp; |
80 | /* the current line, linked to the above viewport */ | ||
81 | static struct wps_line *curr_line; | ||
80 | 82 | ||
81 | #ifdef HAVE_LCD_BITMAP | 83 | #ifdef HAVE_LCD_BITMAP |
82 | 84 | ||
@@ -397,7 +399,7 @@ static struct skin_token_list *new_skin_token_list_item(struct wps_token *token, | |||
397 | immediately after the first eol, i.e. to the start of the next line */ | 399 | immediately after the first eol, i.e. to the start of the next line */ |
398 | static int skip_end_of_line(const char *wps_bufptr) | 400 | static int skip_end_of_line(const char *wps_bufptr) |
399 | { | 401 | { |
400 | line++; | 402 | line_number++; |
401 | int skip = 0; | 403 | int skip = 0; |
402 | while(*(wps_bufptr + skip) != '\n') | 404 | while(*(wps_bufptr + skip) != '\n') |
403 | skip++; | 405 | skip++; |
@@ -405,11 +407,59 @@ static int skip_end_of_line(const char *wps_bufptr) | |||
405 | } | 407 | } |
406 | 408 | ||
407 | /* Starts a new subline in the current line during parsing */ | 409 | /* Starts a new subline in the current line during parsing */ |
408 | static void wps_start_new_subline(struct wps_data *data) | 410 | static bool wps_start_new_subline(struct wps_line *line, int curr_token) |
409 | { | 411 | { |
410 | data->num_sublines++; | 412 | struct wps_subline *subline = skin_buffer_alloc(sizeof(struct wps_subline)); |
411 | data->sublines[data->num_sublines].first_token_idx = data->num_tokens; | 413 | if (!subline) |
412 | data->lines[data->num_lines].num_sublines++; | 414 | return false; |
415 | |||
416 | subline->first_token_idx = curr_token; | ||
417 | subline->next = NULL; | ||
418 | |||
419 | subline->line_type = 0; | ||
420 | subline->time_mult = 0; | ||
421 | |||
422 | line->curr_subline->last_token_idx = curr_token-1; | ||
423 | line->curr_subline->next = subline; | ||
424 | line->curr_subline = subline; | ||
425 | return true; | ||
426 | } | ||
427 | |||
428 | static bool wps_start_new_line(struct skin_viewport *vp, int curr_token) | ||
429 | { | ||
430 | struct wps_line *line = skin_buffer_alloc(sizeof(struct wps_line)); | ||
431 | struct wps_subline *subline = NULL; | ||
432 | if (!line) | ||
433 | return false; | ||
434 | |||
435 | /* init the subline */ | ||
436 | subline = &line->sublines; | ||
437 | subline->first_token_idx = curr_token; | ||
438 | subline->next = NULL; | ||
439 | subline->line_type = 0; | ||
440 | subline->time_mult = 0; | ||
441 | |||
442 | /* init the new line */ | ||
443 | line->curr_subline = &line->sublines; | ||
444 | line->next = NULL; | ||
445 | line->subline_expire_time = 0; | ||
446 | |||
447 | /* connect to curr_line and vp pointers. | ||
448 | * 1) close the previous lines subline | ||
449 | * 2) connect to vp pointer | ||
450 | * 3) connect to curr_line global pointer | ||
451 | */ | ||
452 | if (curr_line) | ||
453 | { | ||
454 | curr_line->curr_subline->last_token_idx = curr_token - 1; | ||
455 | curr_line->next = line; | ||
456 | curr_line->curr_subline = NULL; | ||
457 | } | ||
458 | curr_line = line; | ||
459 | if (!vp->lines) | ||
460 | vp->lines = line; | ||
461 | line_number++; | ||
462 | return true; | ||
413 | } | 463 | } |
414 | 464 | ||
415 | #ifdef HAVE_LCD_BITMAP | 465 | #ifdef HAVE_LCD_BITMAP |
@@ -617,6 +667,12 @@ static int parse_viewport(const char *wps_bufptr, | |||
617 | skin_vp->hidden_flags = 0; | 667 | skin_vp->hidden_flags = 0; |
618 | skin_vp->label = VP_NO_LABEL; | 668 | skin_vp->label = VP_NO_LABEL; |
619 | skin_vp->pb = NULL; | 669 | skin_vp->pb = NULL; |
670 | skin_vp->lines = NULL; | ||
671 | |||
672 | curr_line = NULL; | ||
673 | if (!wps_start_new_line(skin_vp, wps_data->num_tokens)) | ||
674 | return WPS_ERROR_INVALID_PARAM; | ||
675 | |||
620 | 676 | ||
621 | if (*ptr == 'l') | 677 | if (*ptr == 'l') |
622 | { | 678 | { |
@@ -647,18 +703,6 @@ static int parse_viewport(const char *wps_bufptr, | |||
647 | if (*ptr != '|') | 703 | if (*ptr != '|') |
648 | return WPS_ERROR_INVALID_PARAM; | 704 | return WPS_ERROR_INVALID_PARAM; |
649 | 705 | ||
650 | curr_vp->last_line = wps_data->num_lines - 1; | ||
651 | |||
652 | skin_vp->first_line = wps_data->num_lines; | ||
653 | |||
654 | if (wps_data->num_sublines < WPS_MAX_SUBLINES) | ||
655 | { | ||
656 | wps_data->lines[wps_data->num_lines].first_subline_idx = | ||
657 | wps_data->num_sublines; | ||
658 | |||
659 | wps_data->sublines[wps_data->num_sublines].first_token_idx = | ||
660 | wps_data->num_tokens; | ||
661 | } | ||
662 | 706 | ||
663 | struct skin_token_list *list = new_skin_token_list_item(NULL, skin_vp); | 707 | struct skin_token_list *list = new_skin_token_list_item(NULL, skin_vp); |
664 | if (!list) | 708 | if (!list) |
@@ -826,8 +870,15 @@ static int parse_progressbar(const char *wps_bufptr, | |||
826 | #else | 870 | #else |
827 | int font_height = 8; | 871 | int font_height = 8; |
828 | #endif | 872 | #endif |
829 | int line_num = wps_data->num_lines - curr_vp->first_line; | 873 | /* we need to know what line number (viewport relative) this pb is, |
830 | 874 | * so count them... */ | |
875 | int line_num = -1; | ||
876 | struct wps_line *line = curr_vp->lines; | ||
877 | while (line) | ||
878 | { | ||
879 | line_num++; | ||
880 | line = line->next; | ||
881 | } | ||
831 | pb->have_bitmap_pb = false; | 882 | pb->have_bitmap_pb = false; |
832 | pb->bm.data = NULL; /* no bitmap specified */ | 883 | pb->bm.data = NULL; /* no bitmap specified */ |
833 | 884 | ||
@@ -1241,8 +1292,7 @@ static int parse_token(const char *wps_bufptr, struct wps_data *wps_data) | |||
1241 | 1292 | ||
1242 | taglen = (tag->type != WPS_TOKEN_UNKNOWN) ? strlen(tag->name) : 2; | 1293 | taglen = (tag->type != WPS_TOKEN_UNKNOWN) ? strlen(tag->name) : 2; |
1243 | token->type = tag->type; | 1294 | token->type = tag->type; |
1244 | wps_data->sublines[wps_data->num_sublines].line_type |= | 1295 | curr_line->curr_subline->line_type |= tag->refresh_type; |
1245 | tag->refresh_type; | ||
1246 | 1296 | ||
1247 | /* if the tag has a special parsing function, we call it */ | 1297 | /* if the tag has a special parsing function, we call it */ |
1248 | if (tag->parse_func) | 1298 | if (tag->parse_func) |
@@ -1282,7 +1332,7 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr, bool debug) | |||
1282 | int ret; | 1332 | int ret; |
1283 | int max_tokens = TOKEN_BLOCK_SIZE; | 1333 | int max_tokens = TOKEN_BLOCK_SIZE; |
1284 | size_t buf_free = 0; | 1334 | size_t buf_free = 0; |
1285 | line = 1; | 1335 | line_number = 1; |
1286 | level = -1; | 1336 | level = -1; |
1287 | 1337 | ||
1288 | /* allocate enough RAM for a reasonable skin, grow as needed. | 1338 | /* allocate enough RAM for a reasonable skin, grow as needed. |
@@ -1293,8 +1343,7 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr, bool debug) | |||
1293 | skin_buffer_increment(max_tokens * sizeof(struct wps_token), false); | 1343 | skin_buffer_increment(max_tokens * sizeof(struct wps_token), false); |
1294 | data->num_tokens = 0; | 1344 | data->num_tokens = 0; |
1295 | 1345 | ||
1296 | while(*wps_bufptr && !fail | 1346 | while (*wps_bufptr && !fail) |
1297 | && data->num_lines < WPS_MAX_LINES) | ||
1298 | { | 1347 | { |
1299 | /* first make sure there is enough room for tokens */ | 1348 | /* first make sure there is enough room for tokens */ |
1300 | if (max_tokens -1 == data->num_tokens) | 1349 | if (max_tokens -1 == data->num_tokens) |
@@ -1337,9 +1386,7 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr, bool debug) | |||
1337 | break; | 1386 | break; |
1338 | } | 1387 | } |
1339 | 1388 | ||
1340 | if (data->num_sublines+1 < WPS_MAX_SUBLINES) | 1389 | if (!wps_start_new_subline(curr_line, data->num_tokens)) |
1341 | wps_start_new_subline(data); | ||
1342 | else | ||
1343 | fail = PARSE_FAIL_LIMITS_EXCEEDED; | 1390 | fail = PARSE_FAIL_LIMITS_EXCEEDED; |
1344 | 1391 | ||
1345 | break; | 1392 | break; |
@@ -1419,19 +1466,16 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr, bool debug) | |||
1419 | fail = PARSE_FAIL_UNCLOSED_COND; | 1466 | fail = PARSE_FAIL_UNCLOSED_COND; |
1420 | break; | 1467 | break; |
1421 | } | 1468 | } |
1469 | /* add a new token for the \n so empty lines are correct */ | ||
1470 | data->tokens[data->num_tokens].type = WPS_TOKEN_CHARACTER; | ||
1471 | data->tokens[data->num_tokens].value.c = '\n'; | ||
1472 | data->tokens[data->num_tokens].next = false; | ||
1473 | data->num_tokens++; | ||
1422 | 1474 | ||
1423 | line++; | 1475 | if (!wps_start_new_line(curr_vp, data->num_tokens)) |
1424 | wps_start_new_subline(data); | 1476 | { |
1425 | data->num_lines++; /* Start a new line */ | 1477 | fail = PARSE_FAIL_LIMITS_EXCEEDED; |
1426 | 1478 | break; | |
1427 | if ((data->num_lines < WPS_MAX_LINES) && | ||
1428 | (data->num_sublines < WPS_MAX_SUBLINES)) | ||
1429 | { | ||
1430 | data->lines[data->num_lines].first_subline_idx = | ||
1431 | data->num_sublines; | ||
1432 | |||
1433 | data->sublines[data->num_sublines].first_token_idx = | ||
1434 | data->num_tokens; | ||
1435 | } | 1479 | } |
1436 | 1480 | ||
1437 | break; | 1481 | break; |
@@ -1511,11 +1555,12 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr, bool debug) | |||
1511 | /* freeup unused tokens */ | 1555 | /* freeup unused tokens */ |
1512 | skin_buffer_free_from_front(sizeof(struct wps_token) | 1556 | skin_buffer_free_from_front(sizeof(struct wps_token) |
1513 | * (max_tokens - data->num_tokens)); | 1557 | * (max_tokens - data->num_tokens)); |
1514 | curr_vp->last_line = data->num_lines - 1; | 1558 | /* close the last subline */ |
1559 | curr_line->curr_subline->last_token_idx = data->num_tokens; | ||
1515 | 1560 | ||
1516 | #if defined(DEBUG) || defined(SIMULATOR) | 1561 | #if defined(DEBUG) || defined(SIMULATOR) |
1517 | if (debug) | 1562 | if (debug) |
1518 | print_debug_info(data, fail, line); | 1563 | print_debug_info(data, fail, line_number); |
1519 | #else | 1564 | #else |
1520 | (void)debug; | 1565 | (void)debug; |
1521 | #endif | 1566 | #endif |
@@ -1658,6 +1703,12 @@ bool skin_data_load(struct wps_data *wps_data, | |||
1658 | curr_vp->vp.height = display->getheight(); | 1703 | curr_vp->vp.height = display->getheight(); |
1659 | curr_vp->pb = NULL; | 1704 | curr_vp->pb = NULL; |
1660 | curr_vp->hidden_flags = 0; | 1705 | curr_vp->hidden_flags = 0; |
1706 | curr_vp->lines = NULL; | ||
1707 | |||
1708 | curr_line = NULL; | ||
1709 | if (!wps_start_new_line(curr_vp, 0)) | ||
1710 | return false; | ||
1711 | |||
1661 | switch (statusbar_position(display->screen_type)) | 1712 | switch (statusbar_position(display->screen_type)) |
1662 | { | 1713 | { |
1663 | case STATUSBAR_OFF: | 1714 | case STATUSBAR_OFF: |