static bool skin_render_line(struct skin_element* line, struct skin_draw_info *info) { bool needs_update = false; int last_value, value; bool in_changed_alternator = false; struct skin_element *child; struct conditional *conditional; int old_refresh_mode = info->refresh_type; if (line->type == LINE_ALTERNATOR) { line = line->children[alternator_change_line(line, info, &in_changed_alternator)]; if (line->children_count == 0) return in_changed_alternator; if (in_changed_alternator) { info->refresh_type = SKIN_REFRESH_ALL; info->force_redraw = true; } } if (line->children_count == 0) return false; /* empty line, do nothing */ child = line->children[0]; while (child) { switch (child->type) { case CONDITIONAL: conditional = (struct conditional*)child->data; last_value = conditional->last_value; value = evaluate_conditional(info->gwps, info->offset, conditional, child->children_count); conditional->last_value = value; if (child->children_count == 1) { /* special handling so * %?aa and %? need special handlng here */ if (value == -1) /* tag is false */ { /* we are in a false branch of a %?aa conditional */ if (last_value == 0) do_tags_in_hidden_conditional(child->children[0], info); break; } } else { if (last_value >= 0 && value != last_value && last_value < child->children_count) do_tags_in_hidden_conditional(child->children[last_value], info); } if (value != last_value) { info->refresh_type = SKIN_REFRESH_ALL; info->force_redraw = true; } if (skin_render_line(child->children[value], info)) needs_update = true; else needs_update = needs_update || (last_value != value); info->refresh_type = old_refresh_mode; break; case TAG: if (child->tag->flags & NOBREAK) info->no_line_break = true; if (child->tag->type == SKIN_TOKEN_SUBLINE_SCROLL) info->line_scrolls = true; fix_line_alignment(info, child); if (!child->data) { break; } if (!do_non_text_tags(info->gwps, info, child, &info->skin_vp->vp)) { static char tempbuf[128]; const char *value = get_token_value(info->gwps, child->data, info->offset, tempbuf, sizeof(tempbuf), NULL); if (value) { #if CONFIG_RTC if (child->tag->flags&SKIN_RTC_REFRESH) needs_update = needs_update || info->refresh_type&SKIN_REFRESH_DYNAMIC; #endif needs_update = needs_update || ((child->tag->flags&info->refresh_type)!=0); strlcat(info->cur_align_start, value, info->buf_size - (info->cur_align_start-info->buf)); } } break; case TEXT: strlcat(info->cur_align_start, child->data, info->buf_size - (info->cur_align_start-info->buf)); needs_update = needs_update || (info->refresh_type&SKIN_REFRESH_STATIC) != 0; break; case COMMENT: default: break; } child = child->next; } if (in_changed_alternator) { info->refresh_type = old_refresh_mode; info->force_redraw = false; needs_update = true; } return needs_update; }