1. diff --git a/apps/gui/skin_engine/skin_parser.c b/apps/gui/skin_engine/skin_parser.c
  2. index a866101..b65d409 100644
  3. --- a/apps/gui/skin_engine/skin_parser.c
  4. +++ b/apps/gui/skin_engine/skin_parser.c
  5. @@ -720,6 +720,24 @@ static int parse_timeout_tag(struct skin_element *element,
  6. return 0;
  7. }
  8.  
  9. +static int parse_substring_tag(struct skin_element* element,
  10. + struct wps_token *token,
  11. + struct wps_data *wps_data)
  12. +{
  13. + (void)wps_data;
  14. + struct substring *ss = (struct substring*)skin_buffer_alloc(sizeof(struct substring));
  15. + if (!ss)
  16. + return 1;
  17. + ss->start = element->params[0].data.number;
  18. + if (element->params[1].type == DEFAULT)
  19. + ss->length = -1;
  20. + else
  21. + ss->length = element->params[1].data.number;
  22. + memcpy(&ss->tag, &element->params[2], sizeof(ss->tag));
  23. + token->value.data = ss;
  24. + return 0;
  25. +}
  26. +
  27. static int parse_progressbar_tag(struct skin_element* element,
  28. struct wps_token *token,
  29. struct wps_data *wps_data)
  30. @@ -1788,6 +1806,9 @@ static int skin_element_callback(struct skin_element* element, void* data)
  31. case SKIN_TOKEN_LOGICAL_IF:
  32. function = parse_logical_if;
  33. break;
  34. + case SKIN_TOKEN_SUBSTRING:
  35. + function = parse_substring_tag;
  36. + break;
  37. case SKIN_TOKEN_PROGRESSBAR:
  38. case SKIN_TOKEN_VOLUME:
  39. case SKIN_TOKEN_BATTERY_PERCENT:
  40. diff --git a/apps/gui/skin_engine/skin_tokens.c b/apps/gui/skin_engine/skin_tokens.c
  41. index ed72241..30721bb 100644
  42. --- a/apps/gui/skin_engine/skin_tokens.c
  43. +++ b/apps/gui/skin_engine/skin_tokens.c
  44. @@ -868,7 +868,35 @@ const char *get_token_value(struct gui_wps *gwps,
  45. struct logical_if *lif = token->value.data;
  46. return get_lif_token_value(gwps, lif, offset, buf, buf_size);
  47. }
  48. - break;
  49. + break;
  50. + case SKIN_TOKEN_SUBSTRING:
  51. + {
  52. + struct substring *ss = token->value.data;
  53. + struct wps_token *source = ss->tag.data.code->children[0]->data;
  54. + const char *token_val = get_token_value(gwps, source, offset,
  55. + buf, buf_size, intval);
  56. + int ret_len = ss->length;
  57. + if (token_val)
  58. + {
  59. + int len = strlen(token_val);
  60. + if (len < ss->start)
  61. + return NULL;
  62. + if (ret_len < 0)
  63. + ret_len = strlen(token_val) - ss->start;
  64. + if (token_val != buf)
  65. + {
  66. + memcpy(buf, &token_val[ss->start], ret_len);
  67. + }
  68. + else
  69. + {
  70. + buf = &buf[ss->start];
  71. + }
  72. + buf[ret_len] = '\0';
  73. + return buf;
  74. + }
  75. + return NULL;
  76. + }
  77. + break;
  78.  
  79. case SKIN_TOKEN_CHARACTER:
  80. if (token->value.c == '\n')
  81. diff --git a/apps/gui/skin_engine/wps_internals.h b/apps/gui/skin_engine/wps_internals.h
  82. index e996c96..c2d2c1d 100644
  83. --- a/apps/gui/skin_engine/wps_internals.h
  84. +++ b/apps/gui/skin_engine/wps_internals.h
  85. @@ -288,6 +288,12 @@ struct logical_if {
  86. int num_options;
  87. };
  88.  
  89. +struct substring {
  90. + int start;
  91. + int length;
  92. + struct skin_tag_parameter tag;
  93. +};
  94. +
  95. #ifdef HAVE_SKIN_VARIABLES
  96. struct skin_var {
  97. const char *label;
  98. diff --git a/lib/skin_parser/tag_table.c b/lib/skin_parser/tag_table.c
  99. index 849e1d9..f60b031 100644
  100. --- a/lib/skin_parser/tag_table.c
  101. +++ b/lib/skin_parser/tag_table.c
  102. @@ -236,7 +236,8 @@ static const struct tag_info legal_tags[] =
  103. { SKIN_TOKEN_VAR_SET, "vs", "SSI|I", SKIN_REFRESH_STATIC },
  104. { SKIN_TOKEN_VAR_GETVAL, "vg", "S", SKIN_REFRESH_DYNAMIC },
  105. { SKIN_TOKEN_VAR_TIMEOUT, "vl", "S|D", SKIN_REFRESH_DYNAMIC },
  106. -
  107. +
  108. + { SKIN_TOKEN_SUBSTRING, "ss", "IiC", SKIN_REFRESH_DYNAMIC },
  109. { SKIN_TOKEN_UNKNOWN, "" , "", 0 }
  110. /* Keep this here to mark the end of the table */
  111. };
  112. diff --git a/lib/skin_parser/tag_table.h b/lib/skin_parser/tag_table.h
  113. index 5a93e36..82ee475 100644
  114. --- a/lib/skin_parser/tag_table.h
  115. +++ b/lib/skin_parser/tag_table.h
  116. @@ -279,6 +279,8 @@ enum skin_token_type {
  117. SKIN_TOKEN_VAR_SET,
  118. SKIN_TOKEN_VAR_GETVAL,
  119. SKIN_TOKEN_VAR_TIMEOUT,
  120. +
  121. + SKIN_TOKEN_SUBSTRING,
  122. };
  123.  
  124. /*