mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-03 16:46:18 +00:00 
			
		
		
		
	We can use ECH to clear sections of lines, so use it for internal panes
(that don't touch an edge). Move all the tty clear code into two common functions rather than having the same bunch of checks everywhere.
This commit is contained in:
		
							
								
								
									
										238
									
								
								tty.c
									
									
									
									
									
								
							
							
						
						
									
										238
									
								
								tty.c
									
									
									
									
									
								
							@@ -754,6 +754,73 @@ tty_redraw_region(struct tty *tty, const struct tty_ctx *ctx)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
tty_clear_line(struct tty *tty, const struct window_pane *wp, u_int py,
 | 
			
		||||
    u_int px, u_int nx, u_int bg)
 | 
			
		||||
{
 | 
			
		||||
	log_debug("%s: %u at %u,%u", __func__, nx, px, py);
 | 
			
		||||
 | 
			
		||||
	/* Nothing to clear. */
 | 
			
		||||
	if (nx == 0)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	/* If genuine BCE is available, can try escape sequences. */
 | 
			
		||||
	if (!tty_fake_bce(tty, wp, bg)) {
 | 
			
		||||
		/* Off the end of the line, use EL if available. */
 | 
			
		||||
		if (px + nx >= tty->sx && tty_term_has(tty->term, TTYC_EL)) {
 | 
			
		||||
			tty_cursor(tty, px, py);
 | 
			
		||||
			tty_putcode(tty, TTYC_EL);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* At the start of the line. Use EL1. */
 | 
			
		||||
		if (px == 0 && tty_term_has(tty->term, TTYC_EL1)) {
 | 
			
		||||
			tty_cursor(tty, px + nx - 1, py);
 | 
			
		||||
			tty_putcode(tty, TTYC_EL1);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Section of line. Use ECH if possible. */
 | 
			
		||||
		if (tty_term_has(tty->term, TTYC_ECH)) {
 | 
			
		||||
			tty_cursor(tty, px, py);
 | 
			
		||||
			tty_putcode1(tty, TTYC_ECH, nx);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Couldn't use an escape sequence, use spaces. */
 | 
			
		||||
	tty_repeat_space(tty, nx);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
tty_clear_area(struct tty *tty, const struct window_pane *wp, u_int py,
 | 
			
		||||
    u_int ny, u_int px, u_int nx, u_int bg)
 | 
			
		||||
{
 | 
			
		||||
	u_int	yy;
 | 
			
		||||
 | 
			
		||||
	log_debug("%s: %u,%u at %u,%u", __func__, nx, ny, px, py);
 | 
			
		||||
 | 
			
		||||
	/* Nothing to clear. */
 | 
			
		||||
	if (nx == 0 || ny == 0)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	/* If genuine BCE is available, can try escape sequences. */
 | 
			
		||||
	if (!tty_fake_bce(tty, wp, bg)) {
 | 
			
		||||
		if (px == 0 &&
 | 
			
		||||
		    px + nx >= tty->sx &&
 | 
			
		||||
		    py + ny >= tty->sy &&
 | 
			
		||||
		    tty_term_has(tty->term, TTYC_ED)) {
 | 
			
		||||
			tty_cursor(tty, 0, py);
 | 
			
		||||
			tty_putcode(tty, TTYC_ED);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Couldn't use an escape sequence, loop over the lines. */
 | 
			
		||||
	for (yy = py; yy < py + ny; yy++)
 | 
			
		||||
		tty_clear_line(tty, wp, yy, px, nx, bg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
tty_draw_pane(struct tty *tty, const struct window_pane *wp, u_int py, u_int ox,
 | 
			
		||||
    u_int oy)
 | 
			
		||||
@@ -766,7 +833,7 @@ tty_draw_line(struct tty *tty, const struct window_pane *wp,
 | 
			
		||||
    struct screen *s, u_int py, u_int ox, u_int oy)
 | 
			
		||||
{
 | 
			
		||||
	struct grid_cell	 gc, last;
 | 
			
		||||
	u_int			 i, j, sx, width;
 | 
			
		||||
	u_int			 i, j, sx, nx, width;
 | 
			
		||||
	int			 flags, cleared = 0;
 | 
			
		||||
	char			 buf[512];
 | 
			
		||||
	size_t			 len;
 | 
			
		||||
@@ -857,16 +924,10 @@ tty_draw_line(struct tty *tty, const struct window_pane *wp,
 | 
			
		||||
		tty_putn(tty, buf, len, width);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!cleared && sx < tty->sx) {
 | 
			
		||||
	nx = screen_size_x(s) - sx;
 | 
			
		||||
	if (!cleared && sx < tty->sx && nx != 0) {
 | 
			
		||||
		tty_default_attributes(tty, wp, 8);
 | 
			
		||||
		tty_cursor(tty, ox + sx, oy + py);
 | 
			
		||||
		if (sx != screen_size_x(s) &&
 | 
			
		||||
		    ox + screen_size_x(s) >= tty->sx &&
 | 
			
		||||
		    tty_term_has(tty->term, TTYC_EL) &&
 | 
			
		||||
		    !tty_fake_bce(tty, wp, 8))
 | 
			
		||||
			tty_putcode(tty, TTYC_EL);
 | 
			
		||||
		else
 | 
			
		||||
			tty_repeat_space(tty, screen_size_x(s) - sx);
 | 
			
		||||
		tty_clear_line(tty, wp, oy + py, ox + sx, nx, 8);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	tty->flags = (tty->flags & ~TTY_NOCURSOR) | flags;
 | 
			
		||||
@@ -1012,56 +1073,36 @@ void
 | 
			
		||||
tty_cmd_clearline(struct tty *tty, const struct tty_ctx *ctx)
 | 
			
		||||
{
 | 
			
		||||
	struct window_pane	*wp = ctx->wp;
 | 
			
		||||
	struct screen		*s = wp->screen;
 | 
			
		||||
	u_int			 sx = screen_size_x(s);
 | 
			
		||||
	u_int			 nx, py = ctx->yoff + ctx->ocy;
 | 
			
		||||
 | 
			
		||||
	tty_default_attributes(tty, wp, ctx->bg);
 | 
			
		||||
 | 
			
		||||
	tty_cursor_pane(tty, ctx, 0, ctx->ocy);
 | 
			
		||||
 | 
			
		||||
	if (tty_pane_full_width(tty, ctx) &&
 | 
			
		||||
	    !tty_fake_bce(tty, wp, ctx->bg) &&
 | 
			
		||||
	    tty_term_has(tty->term, TTYC_EL))
 | 
			
		||||
		tty_putcode(tty, TTYC_EL);
 | 
			
		||||
	else
 | 
			
		||||
		tty_repeat_space(tty, sx);
 | 
			
		||||
	nx = screen_size_x(wp->screen);
 | 
			
		||||
	tty_clear_line(tty, wp, py, ctx->xoff, nx, ctx->bg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
tty_cmd_clearendofline(struct tty *tty, const struct tty_ctx *ctx)
 | 
			
		||||
{
 | 
			
		||||
	struct window_pane	*wp = ctx->wp;
 | 
			
		||||
	struct screen		*s = wp->screen;
 | 
			
		||||
	u_int			 sx = screen_size_x(s);
 | 
			
		||||
	u_int			 nx, py = ctx->yoff + ctx->ocy;
 | 
			
		||||
 | 
			
		||||
	tty_default_attributes(tty, wp, ctx->bg);
 | 
			
		||||
 | 
			
		||||
	tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
 | 
			
		||||
 | 
			
		||||
	if (tty_pane_full_width(tty, ctx) &&
 | 
			
		||||
	    tty_term_has(tty->term, TTYC_EL) &&
 | 
			
		||||
	    !tty_fake_bce(tty, wp, ctx->bg))
 | 
			
		||||
		tty_putcode(tty, TTYC_EL);
 | 
			
		||||
	else
 | 
			
		||||
		tty_repeat_space(tty, sx - ctx->ocx);
 | 
			
		||||
	nx = screen_size_x(wp->screen) - ctx->ocx;
 | 
			
		||||
	tty_clear_line(tty, wp, py, ctx->xoff + ctx->ocx, nx, ctx->bg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
tty_cmd_clearstartofline(struct tty *tty, const struct tty_ctx *ctx)
 | 
			
		||||
{
 | 
			
		||||
	struct window_pane	*wp = ctx->wp;
 | 
			
		||||
	u_int			 nx, py = ctx->yoff + ctx->ocy;
 | 
			
		||||
 | 
			
		||||
	tty_default_attributes(tty, wp, ctx->bg);
 | 
			
		||||
 | 
			
		||||
	if (ctx->xoff == 0 &&
 | 
			
		||||
	    tty_term_has(tty->term, TTYC_EL1) &&
 | 
			
		||||
	    !tty_fake_bce(tty, ctx->wp, ctx->bg)) {
 | 
			
		||||
		tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
 | 
			
		||||
		tty_putcode(tty, TTYC_EL1);
 | 
			
		||||
	} else {
 | 
			
		||||
		tty_cursor_pane(tty, ctx, 0, ctx->ocy);
 | 
			
		||||
		tty_repeat_space(tty, ctx->ocx + 1);
 | 
			
		||||
	}
 | 
			
		||||
	nx = screen_size_x(wp->screen) - ctx->ocx;
 | 
			
		||||
	tty_clear_line(tty, wp, py, ctx->xoff, ctx->ocx + 1, ctx->bg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -1159,116 +1200,69 @@ void
 | 
			
		||||
tty_cmd_clearendofscreen(struct tty *tty, const struct tty_ctx *ctx)
 | 
			
		||||
{
 | 
			
		||||
	struct window_pane	*wp = ctx->wp;
 | 
			
		||||
	struct screen		*s = wp->screen;
 | 
			
		||||
	u_int			 i, j;
 | 
			
		||||
	u_int			 sx = screen_size_x(s), sy = screen_size_y(s);
 | 
			
		||||
	u_int			 px, py, nx, ny;
 | 
			
		||||
 | 
			
		||||
	tty_default_attributes(tty, wp, ctx->bg);
 | 
			
		||||
 | 
			
		||||
	tty_region_pane(tty, ctx, 0, sy - 1);
 | 
			
		||||
	tty_region_pane(tty, ctx, 0, screen_size_y(wp->screen) - 1);
 | 
			
		||||
	tty_margin_off(tty);
 | 
			
		||||
 | 
			
		||||
	if (tty_pane_full_width(tty, ctx) &&
 | 
			
		||||
	    ctx->yoff + wp->sy >= tty->sy - 1 &&
 | 
			
		||||
	    status_at_line(tty->client) <= 0 &&
 | 
			
		||||
	    tty_term_has(tty->term, TTYC_ED)) {
 | 
			
		||||
		tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
 | 
			
		||||
		tty_putcode(tty, TTYC_ED);
 | 
			
		||||
	} else if (tty_pane_full_width(tty, ctx) &&
 | 
			
		||||
	    tty_term_has(tty->term, TTYC_EL) &&
 | 
			
		||||
	    !tty_fake_bce(tty, wp, ctx->bg)) {
 | 
			
		||||
		tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
 | 
			
		||||
		tty_putcode(tty, TTYC_EL);
 | 
			
		||||
		if (ctx->ocy != sy - 1) {
 | 
			
		||||
			tty_cursor_pane(tty, ctx, 0, ctx->ocy + 1);
 | 
			
		||||
			for (i = ctx->ocy + 1; i < sy; i++) {
 | 
			
		||||
				tty_putcode(tty, TTYC_EL);
 | 
			
		||||
				if (i == sy - 1)
 | 
			
		||||
					continue;
 | 
			
		||||
				tty_emulate_repeat(tty, TTYC_CUD, TTYC_CUD1, 1);
 | 
			
		||||
				tty->cy++;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
 | 
			
		||||
		tty_repeat_space(tty, sx - ctx->ocx);
 | 
			
		||||
		for (j = ctx->ocy + 1; j < sy; j++) {
 | 
			
		||||
			tty_cursor_pane(tty, ctx, 0, j);
 | 
			
		||||
			tty_repeat_space(tty, sx);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	px = ctx->xoff;
 | 
			
		||||
	nx = screen_size_x(wp->screen);
 | 
			
		||||
	py = ctx->yoff + ctx->ocy + 1;
 | 
			
		||||
	ny = screen_size_y(wp->screen) - ctx->ocy - 1;
 | 
			
		||||
 | 
			
		||||
	tty_clear_area(tty, wp, py, ny, px, nx, ctx->bg);
 | 
			
		||||
 | 
			
		||||
	px = ctx->xoff + ctx->ocx;
 | 
			
		||||
	nx = screen_size_x(wp->screen) - ctx->ocx;
 | 
			
		||||
	py = ctx->yoff + ctx->ocy;
 | 
			
		||||
 | 
			
		||||
	tty_clear_line(tty, wp, py, px, nx, ctx->bg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
tty_cmd_clearstartofscreen(struct tty *tty, const struct tty_ctx *ctx)
 | 
			
		||||
{
 | 
			
		||||
	struct window_pane	*wp = ctx->wp;
 | 
			
		||||
	struct screen		*s = wp->screen;
 | 
			
		||||
	u_int			 i, j;
 | 
			
		||||
	u_int			 sx = screen_size_x(s), sy = screen_size_y(s);
 | 
			
		||||
	u_int			 px, py, nx, ny;
 | 
			
		||||
 | 
			
		||||
	tty_default_attributes(tty, wp, ctx->bg);
 | 
			
		||||
 | 
			
		||||
	tty_region_pane(tty, ctx, 0, sy - 1);
 | 
			
		||||
	tty_region_pane(tty, ctx, 0, screen_size_y(wp->screen) - 1);
 | 
			
		||||
	tty_margin_off(tty);
 | 
			
		||||
 | 
			
		||||
	if (tty_pane_full_width(tty, ctx) &&
 | 
			
		||||
	    tty_term_has(tty->term, TTYC_EL) &&
 | 
			
		||||
	    !tty_fake_bce(tty, wp, ctx->bg)) {
 | 
			
		||||
		tty_cursor_pane(tty, ctx, 0, 0);
 | 
			
		||||
		for (i = 0; i < ctx->ocy; i++) {
 | 
			
		||||
			tty_putcode(tty, TTYC_EL);
 | 
			
		||||
			tty_emulate_repeat(tty, TTYC_CUD, TTYC_CUD1, 1);
 | 
			
		||||
			tty->cy++;
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		tty_cursor_pane(tty, ctx, 0, 0);
 | 
			
		||||
		for (j = 0; j < ctx->ocy; j++) {
 | 
			
		||||
			tty_cursor_pane(tty, ctx, 0, j);
 | 
			
		||||
			tty_repeat_space(tty, sx);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	tty_cursor_pane(tty, ctx, 0, ctx->ocy);
 | 
			
		||||
	tty_repeat_space(tty, ctx->ocx + 1);
 | 
			
		||||
	px = ctx->xoff;
 | 
			
		||||
	nx = screen_size_x(wp->screen);
 | 
			
		||||
	py = ctx->yoff;
 | 
			
		||||
	ny = ctx->ocy - 1;
 | 
			
		||||
 | 
			
		||||
	tty_clear_area(tty, wp, py, ny, px, nx, ctx->bg);
 | 
			
		||||
 | 
			
		||||
	px = ctx->xoff;
 | 
			
		||||
	nx = ctx->ocx + 1;
 | 
			
		||||
	py = ctx->yoff + ctx->ocy;
 | 
			
		||||
 | 
			
		||||
	tty_clear_line(tty, wp, py, px, nx, ctx->bg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
tty_cmd_clearscreen(struct tty *tty, const struct tty_ctx *ctx)
 | 
			
		||||
{
 | 
			
		||||
	struct window_pane	*wp = ctx->wp;
 | 
			
		||||
	struct screen		*s = wp->screen;
 | 
			
		||||
	u_int			 i, j;
 | 
			
		||||
	u_int			 sx = screen_size_x(s), sy = screen_size_y(s);
 | 
			
		||||
	u_int			 px, py, nx, ny;
 | 
			
		||||
 | 
			
		||||
	tty_default_attributes(tty, wp, ctx->bg);
 | 
			
		||||
 | 
			
		||||
	tty_region_pane(tty, ctx, 0, sy - 1);
 | 
			
		||||
	tty_region_pane(tty, ctx, 0, screen_size_y(wp->screen) - 1);
 | 
			
		||||
	tty_margin_off(tty);
 | 
			
		||||
 | 
			
		||||
	if (tty_pane_full_width(tty, ctx) &&
 | 
			
		||||
	    ctx->yoff + wp->sy >= tty->sy - 1 &&
 | 
			
		||||
	    status_at_line(tty->client) <= 0 &&
 | 
			
		||||
	    tty_term_has(tty->term, TTYC_ED)) {
 | 
			
		||||
		tty_cursor_pane(tty, ctx, 0, 0);
 | 
			
		||||
		tty_putcode(tty, TTYC_ED);
 | 
			
		||||
	} else if (tty_pane_full_width(tty, ctx) &&
 | 
			
		||||
	    tty_term_has(tty->term, TTYC_EL) &&
 | 
			
		||||
	    !tty_fake_bce(tty, wp, ctx->bg)) {
 | 
			
		||||
		tty_cursor_pane(tty, ctx, 0, 0);
 | 
			
		||||
		for (i = 0; i < sy; i++) {
 | 
			
		||||
			tty_putcode(tty, TTYC_EL);
 | 
			
		||||
			if (i != sy - 1) {
 | 
			
		||||
				tty_emulate_repeat(tty, TTYC_CUD, TTYC_CUD1, 1);
 | 
			
		||||
				tty->cy++;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		tty_cursor_pane(tty, ctx, 0, 0);
 | 
			
		||||
		for (j = 0; j < sy; j++) {
 | 
			
		||||
			tty_cursor_pane(tty, ctx, 0, j);
 | 
			
		||||
			tty_repeat_space(tty, sx);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	px = ctx->xoff;
 | 
			
		||||
	nx = screen_size_x(wp->screen);
 | 
			
		||||
	py = ctx->yoff;
 | 
			
		||||
	ny = screen_size_y(wp->screen);
 | 
			
		||||
 | 
			
		||||
	tty_clear_area(tty, wp, py, ny, px, nx, ctx->bg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user