summaryrefslogtreecommitdiff
path: root/apps/gui/skin_engine/skin_parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/gui/skin_engine/skin_parser.c')
-rw-r--r--apps/gui/skin_engine/skin_parser.c137
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 */
73static int numoptions[WPS_MAX_COND_LEVEL]; 73static int numoptions[WPS_MAX_COND_LEVEL];
74 74
75/* the current line in the file */ 75/* line number, debug only */
76static int line; 76static int line_number;
77 77
78/* the current viewport */ 78/* the current viewport */
79static struct skin_viewport *curr_vp; 79static struct skin_viewport *curr_vp;
80/* the current line, linked to the above viewport */
81static 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 */
398static int skip_end_of_line(const char *wps_bufptr) 400static 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 */
408static void wps_start_new_subline(struct wps_data *data) 410static 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
428static 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: