Pastebin launched a little side project called VERYVIRAL.com, check it out ;-) Want more features on Pastebin? Sign Up, it's FREE!
Guest

Untitled

By: a guest on Oct 10th, 2010  |  syntax: None  |  size: 7.78 KB  |  views: 78  |  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..d0221a8 100644
  3. --- a/apps/gui/skin_engine/skin_render.c
  4. +++ b/apps/gui/skin_engine/skin_render.c
  5. @@ -68,8 +68,8 @@ struct skin_draw_info {
  6.      int offset; /* used by the playlist viewer */
  7.  };
  8.  
  9. -typedef bool (*skin_render_func)(struct skin_element* alternator, struct skin_draw_info *info);
  10. -bool skin_render_alternator(struct skin_element* alternator, struct skin_draw_info *info);
  11. +static int alternator_change_line(struct skin_element* alternator,
  12. +                                  struct skin_draw_info *info, bool* line_changed);
  13.  
  14.  #ifdef HAVE_LCD_BITMAP
  15.  static void skin_render_playlistviewer(struct playlistviewer* viewer,
  16. @@ -375,14 +375,29 @@ static bool skin_render_line(struct skin_element* line, struct skin_draw_info *i
  17.  {
  18.      bool needs_update = false;
  19.      int last_value, value;
  20. +    bool in_changed_alternator = false;
  21. +    struct skin_element *child;
  22. +    struct conditional *conditional;
  23. +    int old_refresh_mode = info->refresh_type;
  24. +    
  25. +    if (line->type == LINE_ALTERNATOR)
  26. +    {
  27. +        line = line->children[alternator_change_line(line, info,
  28. +                                                     &in_changed_alternator)];
  29. +        if (line->children_count == 0)
  30. +            return in_changed_alternator;
  31. +        if (in_changed_alternator)
  32. +        {
  33. +            info->refresh_type = SKIN_REFRESH_ALL;
  34. +            info->force_redraw = true;
  35. +        }
  36. +        
  37. +    }
  38.      
  39.      if (line->children_count == 0)
  40.          return false; /* empty line, do nothing */
  41. +    child = line->children[0];
  42.          
  43. -    struct skin_element *child = line->children[0];
  44. -    struct conditional *conditional;
  45. -    skin_render_func func = skin_render_line;
  46. -    int old_refresh_mode = info->refresh_type;
  47.      while (child)
  48.      {
  49.          switch (child->type)
  50. @@ -411,20 +426,13 @@ static bool skin_render_line(struct skin_element* line, struct skin_draw_info *i
  51.                      if (last_value >= 0 && value != last_value && last_value < child->children_count)
  52.                          do_tags_in_hidden_conditional(child->children[last_value], info);
  53.                  }
  54. -                if (child->children[value]->type == LINE_ALTERNATOR)
  55. -                {
  56. -                    func = skin_render_alternator;
  57. -                }
  58. -                else if (child->children[value]->type == LINE)
  59. -                    func = skin_render_line;
  60. -                
  61.                  if (value != last_value)
  62.                  {
  63.                      info->refresh_type = SKIN_REFRESH_ALL;
  64.                      info->force_redraw = true;
  65.                  }
  66.                      
  67. -                if (func(child->children[value], info))
  68. +                if (skin_render_line(child->children[value], info))
  69.                      needs_update = true;
  70.                  else
  71.                      needs_update = needs_update || (last_value != value);
  72. @@ -475,6 +483,12 @@ static bool skin_render_line(struct skin_element* line, struct skin_draw_info *i
  73.  
  74.          child = child->next;
  75.      }
  76. +    if (in_changed_alternator)
  77. +    {
  78. +        info->refresh_type = old_refresh_mode;
  79. +        info->force_redraw = false;
  80. +        needs_update = true;
  81. +    }
  82.      return needs_update;
  83.  }
  84.  
  85. @@ -483,6 +497,8 @@ static int get_subline_timeout(struct gui_wps *gwps, struct skin_element* line)
  86.      struct skin_element *element=line;
  87.      struct wps_token *token;
  88.      int retval = DEFAULT_SUBLINE_TIME_MULTIPLIER*TIMEOUT_UNIT;
  89. +restart: /* we are really using tail recursion so do it with a messy goto
  90. +            to prevent stack overusage */
  91.      if (element->type == LINE)
  92.      {
  93.          if (element->children_count == 0)
  94. @@ -504,9 +520,8 @@ static int get_subline_timeout(struct gui_wps *gwps, struct skin_element* line)
  95.                                             element->children_count);
  96.              if (val >= 0)
  97.              {
  98. -                retval = get_subline_timeout(gwps, element->children[val]);
  99. -                if (retval >= 0)
  100. -                    return retval;
  101. +                element = element->children[val];
  102. +                goto restart;
  103.              }
  104.          }
  105.          element = element->next;
  106. @@ -514,11 +529,11 @@ static int get_subline_timeout(struct gui_wps *gwps, struct skin_element* line)
  107.      return retval;
  108.  }
  109.  
  110. -bool skin_render_alternator(struct skin_element* element, struct skin_draw_info *info)
  111. +static int alternator_change_line(struct skin_element* element,
  112. +                           struct skin_draw_info *info, bool* line_changed)
  113.  {
  114.      bool changed_lines = false;
  115.      struct line_alternator *alternator = (struct line_alternator*)element->data;
  116. -    unsigned old_refresh = info->refresh_type;
  117.      if (info->refresh_type == SKIN_REFRESH_ALL)
  118.      {
  119.          alternator->current_line = element->children_count-1;
  120. @@ -561,13 +576,9 @@ bool skin_render_alternator(struct skin_element* element, struct skin_draw_info
  121.              alternator->current_line = try_line;
  122.              alternator->next_change_tick = current_tick + rettimeout;
  123.          }
  124. -
  125. -        info->refresh_type = SKIN_REFRESH_ALL;
  126. -        info->force_redraw = true;
  127.      }
  128. -    bool ret = skin_render_line(element->children[alternator->current_line], info);
  129. -    info->refresh_type = old_refresh;
  130. -    return changed_lines || ret;
  131. +    *line_changed = changed_lines;
  132. +    return alternator->current_line;
  133.  }
  134.  
  135.  static void skin_render_viewport(struct skin_element* viewport, struct gui_wps *gwps,
  136. @@ -575,7 +586,6 @@ static void skin_render_viewport(struct skin_element* viewport, struct gui_wps *
  137.  {
  138.      struct screen *display = gwps->display;
  139.      char linebuf[MAX_LINE];
  140. -    skin_render_func func = skin_render_line;
  141.      struct skin_element* line = viewport;
  142.      struct skin_draw_info info = {
  143.          .gwps = gwps,
  144. @@ -613,14 +623,8 @@ static void skin_render_viewport(struct skin_element* viewport, struct gui_wps *
  145.          align->left = info.buf;
  146.          align->center = NULL;
  147.          align->right = NULL;
  148. -        
  149. -        
  150. -        if (line->type == LINE_ALTERNATOR)
  151. -            func = skin_render_alternator;
  152. -        else if (line->type == LINE)
  153. -            func = skin_render_line;
  154. -        
  155. -        needs_update = func(line, &info);
  156. +                
  157. +        needs_update = skin_render_line(line, &info);
  158.          
  159.          /* only update if the line needs to be, and there is something to write */
  160.          if (refresh_type && needs_update)
  161. @@ -715,14 +719,13 @@ void skin_render(struct gui_wps *gwps, unsigned refresh_mode)
  162.  }
  163.  
  164.  #ifdef HAVE_LCD_BITMAP
  165. -static void skin_render_playlistviewer(struct playlistviewer* viewer,
  166. +static __attribute__((noinline)) void skin_render_playlistviewer(struct playlistviewer* viewer,
  167.                                         struct gui_wps *gwps,
  168.                                         struct skin_viewport* skin_viewport,
  169.                                         unsigned long refresh_type)
  170.  {
  171.      struct screen *display = gwps->display;
  172.      char linebuf[MAX_LINE];
  173. -    skin_render_func func = skin_render_line;
  174.      struct skin_element* line;
  175.      struct skin_draw_info info = {
  176.          .gwps = gwps,
  177. @@ -774,13 +777,7 @@ static void skin_render_playlistviewer(struct playlistviewer* viewer,
  178.          align->center = NULL;
  179.          align->right = NULL;
  180.          
  181. -        
  182. -        if (line->type == LINE_ALTERNATOR)
  183. -            func = skin_render_alternator;
  184. -        else if (line->type == LINE)
  185. -            func = skin_render_line;
  186. -        
  187. -        needs_update = func(line, &info);
  188. +        needs_update = skin_render_line(line, &info);
  189.          
  190.          /* only update if the line needs to be, and there is something to write */
  191.          if (refresh_type && needs_update)