This week only. Pastebin PRO Accounts Christmas Special! Don't miss out!Want more features on Pastebin? Sign Up, it's FREE!
Guest

Untitled

By: a guest on Oct 10th, 2010  |  syntax: None  |  size: 7.79 KB  |  views: 83  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. diff --git a/apps/gui/skin_engine/skin_render.c b/apps/gui/skin_engine/skin_render.c
  2. index 304ebf1..0b843a5 100644
  3. --- a/apps/gui/skin_engine/skin_render.c
  4. +++ b/apps/gui/skin_engine/skin_render.c
  5. @@ -27,6 +27,10 @@
  6.  #include "strlcat.h"
  7.  
  8.  #include "config.h"
  9. +
  10. +#include "thread.h"
  11. +extern struct thread_entry threads[MAXTHREADS];
  12. +
  13.  #include "kernel.h"
  14.  #ifdef HAVE_ALBUMART
  15.  #include "albumart.h"
  16. @@ -68,8 +72,8 @@ struct skin_draw_info {
  17.      int offset; /* used by the playlist viewer */
  18.  };
  19.  
  20. -typedef bool (*skin_render_func)(struct skin_element* alternator, struct skin_draw_info *info);
  21. -bool skin_render_alternator(struct skin_element* alternator, struct skin_draw_info *info);
  22. +static int alternator_change_line(struct skin_element* alternator,
  23. +                                  struct skin_draw_info *info, bool* line_changed);
  24.  
  25.  #ifdef HAVE_LCD_BITMAP
  26.  static void skin_render_playlistviewer(struct playlistviewer* viewer,
  27. @@ -375,14 +379,29 @@ static bool skin_render_line(struct skin_element* line, struct skin_draw_info *i
  28.  {
  29.      bool needs_update = false;
  30.      int last_value, value;
  31. +    bool in_changed_alternator = false;
  32. +    struct skin_element *child;
  33. +    struct conditional *conditional;
  34. +    int old_refresh_mode = info->refresh_type;
  35. +    
  36. +    if (line->type == LINE_ALTERNATOR)
  37. +    {
  38. +        line = line->children[alternator_change_line(line, info,
  39. +                                                     &in_changed_alternator)];
  40. +        if (line->children_count == 0)
  41. +            return in_changed_alternator;
  42. +        if (in_changed_alternator)
  43. +        {
  44. +            info->refresh_type = SKIN_REFRESH_ALL;
  45. +            info->force_redraw = true;
  46. +        }
  47. +        
  48. +    }
  49.      
  50.      if (line->children_count == 0)
  51.          return false; /* empty line, do nothing */
  52. +    child = line->children[0];
  53.          
  54. -    struct skin_element *child = line->children[0];
  55. -    struct conditional *conditional;
  56. -    skin_render_func func = skin_render_line;
  57. -    int old_refresh_mode = info->refresh_type;
  58.      while (child)
  59.      {
  60.          switch (child->type)
  61. @@ -411,20 +430,15 @@ static bool skin_render_line(struct skin_element* line, struct skin_draw_info *i
  62.                      if (last_value >= 0 && value != last_value && last_value < child->children_count)
  63.                          do_tags_in_hidden_conditional(child->children[last_value], info);
  64.                  }
  65. -                if (child->children[value]->type == LINE_ALTERNATOR)
  66. -                {
  67. -                    func = skin_render_alternator;
  68. -                }
  69. -                else if (child->children[value]->type == LINE)
  70. -                    func = skin_render_line;
  71. -                
  72.                  if (value != last_value)
  73.                  {
  74.                      info->refresh_type = SKIN_REFRESH_ALL;
  75.                      info->force_redraw = true;
  76.                  }
  77. -                    
  78. -                if (func(child->children[value], info))
  79. +                struct thread_entry *t = &threads[thread_get_current()];
  80. +                if (thread_stack_usage(t) > 90)
  81. +                    panicf("skin engine: rendering stack overflow");
  82. +                if (skin_render_line(child->children[value], info))
  83.                      needs_update = true;
  84.                  else
  85.                      needs_update = needs_update || (last_value != value);
  86. @@ -475,6 +489,12 @@ static bool skin_render_line(struct skin_element* line, struct skin_draw_info *i
  87.  
  88.          child = child->next;
  89.      }
  90. +    if (in_changed_alternator)
  91. +    {
  92. +        info->refresh_type = old_refresh_mode;
  93. +        info->force_redraw = false;
  94. +        needs_update = true;
  95. +    }
  96.      return needs_update;
  97.  }
  98.  
  99. @@ -483,6 +503,8 @@ static int get_subline_timeout(struct gui_wps *gwps, struct skin_element* line)
  100.      struct skin_element *element=line;
  101.      struct wps_token *token;
  102.      int retval = DEFAULT_SUBLINE_TIME_MULTIPLIER*TIMEOUT_UNIT;
  103. +restart: /* we are really using tail recursion so do it with a messy goto
  104. +            to prevent stack overusage */
  105.      if (element->type == LINE)
  106.      {
  107.          if (element->children_count == 0)
  108. @@ -504,9 +526,8 @@ static int get_subline_timeout(struct gui_wps *gwps, struct skin_element* line)
  109.                                             element->children_count);
  110.              if (val >= 0)
  111.              {
  112. -                retval = get_subline_timeout(gwps, element->children[val]);
  113. -                if (retval >= 0)
  114. -                    return retval;
  115. +                element = element->children[val];
  116. +                goto restart;
  117.              }
  118.          }
  119.          element = element->next;
  120. @@ -514,11 +535,11 @@ static int get_subline_timeout(struct gui_wps *gwps, struct skin_element* line)
  121.      return retval;
  122.  }
  123.  
  124. -bool skin_render_alternator(struct skin_element* element, struct skin_draw_info *info)
  125. +static int alternator_change_line(struct skin_element* element,
  126. +                           struct skin_draw_info *info, bool* line_changed)
  127.  {
  128.      bool changed_lines = false;
  129.      struct line_alternator *alternator = (struct line_alternator*)element->data;
  130. -    unsigned old_refresh = info->refresh_type;
  131.      if (info->refresh_type == SKIN_REFRESH_ALL)
  132.      {
  133.          alternator->current_line = element->children_count-1;
  134. @@ -561,13 +582,9 @@ bool skin_render_alternator(struct skin_element* element, struct skin_draw_info
  135.              alternator->current_line = try_line;
  136.              alternator->next_change_tick = current_tick + rettimeout;
  137.          }
  138. -
  139. -        info->refresh_type = SKIN_REFRESH_ALL;
  140. -        info->force_redraw = true;
  141.      }
  142. -    bool ret = skin_render_line(element->children[alternator->current_line], info);
  143. -    info->refresh_type = old_refresh;
  144. -    return changed_lines || ret;
  145. +    *line_changed = changed_lines;
  146. +    return alternator->current_line;
  147.  }
  148.  
  149.  static void skin_render_viewport(struct skin_element* viewport, struct gui_wps *gwps,
  150. @@ -575,7 +592,6 @@ static void skin_render_viewport(struct skin_element* viewport, struct gui_wps *
  151.  {
  152.      struct screen *display = gwps->display;
  153.      char linebuf[MAX_LINE];
  154. -    skin_render_func func = skin_render_line;
  155.      struct skin_element* line = viewport;
  156.      struct skin_draw_info info = {
  157.          .gwps = gwps,
  158. @@ -613,14 +629,8 @@ static void skin_render_viewport(struct skin_element* viewport, struct gui_wps *
  159.          align->left = info.buf;
  160.          align->center = NULL;
  161.          align->right = NULL;
  162. -        
  163. -        
  164. -        if (line->type == LINE_ALTERNATOR)
  165. -            func = skin_render_alternator;
  166. -        else if (line->type == LINE)
  167. -            func = skin_render_line;
  168. -        
  169. -        needs_update = func(line, &info);
  170. +                
  171. +        needs_update = skin_render_line(line, &info);
  172.          
  173.          /* only update if the line needs to be, and there is something to write */
  174.          if (refresh_type && needs_update)
  175. @@ -722,7 +732,6 @@ static void skin_render_playlistviewer(struct playlistviewer* viewer,
  176.  {
  177.      struct screen *display = gwps->display;
  178.      char linebuf[MAX_LINE];
  179. -    skin_render_func func = skin_render_line;
  180.      struct skin_element* line;
  181.      struct skin_draw_info info = {
  182.          .gwps = gwps,
  183. @@ -774,13 +783,7 @@ static void skin_render_playlistviewer(struct playlistviewer* viewer,
  184.          align->center = NULL;
  185.          align->right = NULL;
  186.          
  187. -        
  188. -        if (line->type == LINE_ALTERNATOR)
  189. -            func = skin_render_alternator;
  190. -        else if (line->type == LINE)
  191. -            func = skin_render_line;
  192. -        
  193. -        needs_update = func(line, &info);
  194. +        needs_update = skin_render_line(line, &info);
  195.          
  196.          /* only update if the line needs to be, and there is something to write */
  197.          if (refresh_type && needs_update)
clone this paste RAW Paste Data