From 97ee6e258728174ffffee11359db5b0ac637f137 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Thu, 28 May 2026 08:24:54 +0100 Subject: [PATCH] Break screen_write_collect_flush into some helper functions. --- screen-write.c | 232 ++++++++++++++++++++++++++----------------------- 1 file changed, 121 insertions(+), 111 deletions(-) diff --git a/screen-write.c b/screen-write.c index 31ef6e74..d9a5fafb 100644 --- a/screen-write.c +++ b/screen-write.c @@ -2100,58 +2100,52 @@ screen_write_collect_scroll(struct screen_write_ctx *ctx, u_int bg) TAILQ_INSERT_TAIL(&ctx->s->write_list[s->rlower].items, ci, entry); } -/* Flush collected lines. */ -static void -screen_write_collect_flush(struct screen_write_ctx *ctx, int scroll_only, - const char *from) +/* Flush collected scrolling. */ +static int +screen_write_collect_flush_scrolled(struct screen_write_ctx *ctx) +{ + struct window_pane *wp = ctx->wp; + struct screen *s = ctx->s; + struct tty_ctx ttyctx; + + screen_write_initctx(ctx, &ttyctx, 1, 1); + if (ttyctx.flags & TTY_CTX_PANE_OBSCURED && wp != NULL) { + screen_write_redraw_pane(ctx, &ttyctx); + return 0; + } + + log_debug("%s: scrolled %u (region %u-%u)", __func__, ctx->scrolled, + s->rupper, s->rlower); + if (ctx->scrolled > s->rlower - s->rupper + 1) + ctx->scrolled = s->rlower - s->rupper + 1; + + if (wp != NULL && wp->yoff + wp->sy > wp->window->sy) + ttyctx.orlower -= (wp->yoff + wp->sy - wp->window->sy); + ttyctx.n = ctx->scrolled; + ttyctx.bg = ctx->bg; + tty_write(tty_cmd_scrollup, &ttyctx); + + if (wp != NULL) + wp->flags |= PANE_REDRAWSCROLLBAR; + return 1; +} + +/* Flush a collected line. */ +static u_int +screen_write_collect_flush_line(struct screen_write_ctx *ctx, u_int y) { struct window_pane *wp = ctx->wp; struct screen *s = ctx->s; struct screen_write_citem *ci, *tmp; - struct screen_write_cline *cl; - u_int y, cx, cy, last, items = 0, i; - u_int wr_start, wr_end, wr_length, wsx, wsy; - int written; - int r_start, r_end, ci_start, ci_end; - int xoff, yoff; + struct screen_write_cline *cl = &s->write_list[y]; + u_int last = UINT_MAX, items = 0, wsx, wsy; + u_int w_start, w_end, w_length, i; + int xoff, yoff, written; + int r_start, r_end, c_start, c_end; struct tty_ctx ttyctx; struct visible_ranges *r; struct visible_range *ri; - if (s->mode & MODE_SYNC) - goto discard; - - if (ctx->scrolled != 0) { - screen_write_initctx(ctx, &ttyctx, 1, 1); - if (ttyctx.flags & TTY_CTX_PANE_OBSCURED && wp != NULL) { - screen_write_redraw_pane(ctx, &ttyctx); - goto discard; - } - - log_debug("%s: scrolled %u (region %u-%u)", __func__, - ctx->scrolled, s->rupper, s->rlower); - if (ctx->scrolled > s->rlower - s->rupper + 1) - ctx->scrolled = s->rlower - s->rupper + 1; - - if (wp != NULL && wp->yoff + wp->sy > wp->window->sy) - ttyctx.orlower -= (wp->yoff + wp->sy - wp->window->sy); - ttyctx.n = ctx->scrolled; - ttyctx.bg = ctx->bg; - tty_write(tty_cmd_scrollup, &ttyctx); - - if (wp != NULL) - wp->flags |= PANE_REDRAWSCROLLBAR; - } - ctx->scrolled = 0; - ctx->bg = 8; - - if (scroll_only) - return; - - cx = s->cx; cy = s->cy; - - /* The xoff and width of window pane relative to the window we - * are writing to relative to the visible_ranges array. */ if (wp != NULL) { wsx = wp->window->sx; wsy = wp->window->sy; @@ -2163,79 +2157,95 @@ screen_write_collect_flush(struct screen_write_ctx *ctx, int scroll_only, xoff = 0; yoff = 0; } + if (y + yoff >= wsy) + return (0); - for (y = 0; y < screen_size_y(s); y++) { - if (y + yoff >= wsy) - continue; - cl = &ctx->s->write_list[y]; + r = screen_redraw_get_visible_ranges(wp, 0, y + yoff, wsx, NULL); + TAILQ_FOREACH_SAFE(ci, &cl->items, entry, tmp) { + log_debug("collect list: x=%u (last %u), y=%u, used=%u", ci->x, + last, y, ci->used); + if (last != UINT_MAX && ci->x <= last) + fatalx("collect list bad order: %u <= %u", ci->x, last); - r = screen_redraw_get_visible_ranges(wp, 0, y + yoff, wsx, - NULL); + w_length = 0; + written = 0; + for (i = 0; i < r->used; i++) { + ri = &r->ranges[i]; + if (ri->nx == 0) + continue; - last = UINT_MAX; - TAILQ_FOREACH_SAFE(ci, &cl->items, entry, tmp) { - log_debug("collect list: x=%u (last %u), y=%u, used=%u", - ci->x, last, y, ci->used); - if (last != UINT_MAX && ci->x <= last) { - fatalx("collect list not in order: %u <= %u", - ci->x, last); - } - wr_length = 0; - written = 0; - for (i = 0; i < r->used; i++) { - ri = &r->ranges[i]; - if (ri->nx == 0) - continue; - r_start = ri->px; - r_end = ri->px + ri->nx; - ci_start = ci->x; - ci_end = ci->x + ci->used; - - if (ci_start + xoff > r_end || - ci_end + xoff < r_start) - continue; - - if (r_start > ci_start + xoff) - wr_start = ci_start + - (r_start - (ci_start + xoff)); - else - wr_start = ci_start; - if (ci_end + xoff > r_end) - wr_end = ci_end - - ((ci_end + xoff) - r_end); - else - wr_end = ci_end; - wr_length = wr_end - wr_start; - - if (wr_length <= 0) - continue; - screen_write_set_cursor(ctx, wr_start, y); - if (ci->type == CLEAR) { - screen_write_initctx(ctx, &ttyctx, 1, 0); - ttyctx.bg = ci->bg; - ttyctx.n = wr_length; - tty_write(tty_cmd_clearcharacter, - &ttyctx); - } else { - screen_write_initctx(ctx, &ttyctx, 0, 0); - ttyctx.cell = &ci->gc; - if (ci->wrapped) - ttyctx.flags |= TTY_CTX_WRAPPED; - ttyctx.data.data = cl->data + wr_start; - ttyctx.data.size = wr_length; - tty_write(tty_cmd_cells, &ttyctx); - } - items++; - written = 1; - } - if (written) { - last = ci->x; - TAILQ_REMOVE(&cl->items, ci, entry); - screen_write_free_citem(ci); + r_start = ri->px; + r_end = ri->px + ri->nx; + c_start = ci->x; + c_end = ci->x + ci->used; + + if (c_start + xoff > r_end || c_end + xoff < r_start) + continue; + if (r_start > c_start + xoff) + w_start = c_start + (r_start - c_start + xoff); + else + w_start = c_start; + if (c_end + xoff > r_end) + w_end = c_end - (c_end + xoff - r_end); + else + w_end = c_end; + w_length = w_end - w_start; + if (w_length <= 0) + continue; + + screen_write_set_cursor(ctx, w_start, y); + if (ci->type == CLEAR) { + screen_write_initctx(ctx, &ttyctx, 1, 0); + ttyctx.bg = ci->bg; + ttyctx.n = w_length; + tty_write(tty_cmd_clearcharacter, &ttyctx); + } else { + screen_write_initctx(ctx, &ttyctx, 0, 0); + ttyctx.cell = &ci->gc; + if (ci->wrapped) + ttyctx.flags |= TTY_CTX_WRAPPED; + ttyctx.data.data = cl->data + w_start; + ttyctx.data.size = w_length; + tty_write(tty_cmd_cells, &ttyctx); } + items++; + written = 1; + } + if (written) { + last = ci->x; + TAILQ_REMOVE(&cl->items, ci, entry); + screen_write_free_citem(ci); } } + return (items); +} +/* Flush collected lines. */ +static void +screen_write_collect_flush(struct screen_write_ctx *ctx, int scroll_only, + const char *from) +{ + struct screen *s = ctx->s; + u_int y, cx, cy, items = 0; + struct screen_write_citem *ci, *tmp; + struct screen_write_cline *cl; + + if (s->mode & MODE_SYNC) + goto discard; + + if (ctx->scrolled != 0) { + if (!screen_write_collect_flush_scrolled(ctx)) + goto discard; + ctx->scrolled = 0; + } + ctx->bg = 8; + + if (scroll_only) + return; + + cx = s->cx; cy = s->cy; + for (y = 0; y < screen_size_y(s); y++) + items += screen_write_collect_flush_line(ctx, y); s->cx = cx; s->cy = cy; log_debug("%s: flushed %u items (%s)", __func__, items, from); @@ -2243,7 +2253,7 @@ screen_write_collect_flush(struct screen_write_ctx *ctx, int scroll_only, discard: for (y = 0; y < screen_size_y(s); y++) { - cl = &ctx->s->write_list[y]; + cl = &s->write_list[y]; TAILQ_FOREACH_SAFE(ci, &cl->items, entry, tmp) { TAILQ_REMOVE(&cl->items, ci, entry); screen_write_free_citem(ci);