aboutsummaryrefslogtreecommitdiff
path: root/tty.c
diff options
context:
space:
mode:
authornicm <nicm>2017-05-10 16:47:03 +0000
committernicm <nicm>2017-05-10 16:47:03 +0000
commit9dc6946ebf359ec811cc4bb8b68ea9862b496369 (patch)
treee8a243ca8e99208c8eac038e246652b97966090e /tty.c
parentb519551153f5451615a9d64966350400e141e540 (diff)
downloadrtmux-9dc6946ebf359ec811cc4bb8b68ea9862b496369.tar.gz
rtmux-9dc6946ebf359ec811cc4bb8b68ea9862b496369.tar.bz2
rtmux-9dc6946ebf359ec811cc4bb8b68ea9862b496369.zip
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.
Diffstat (limited to 'tty.c')
-rw-r--r--tty.c238
1 files changed, 116 insertions, 122 deletions
diff --git a/tty.c b/tty.c
index ba7a5158..a1219069 100644
--- a/tty.c
+++ b/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