aboutsummaryrefslogtreecommitdiff
path: root/tty.c
diff options
context:
space:
mode:
authorNicholas Marriott <nicholas.marriott@gmail.com>2017-02-07 13:41:17 +0000
committerNicholas Marriott <nicholas.marriott@gmail.com>2017-02-07 13:41:17 +0000
commit8872a0da8e9588b0ec5eac1a1cc3753037ed68e1 (patch)
tree5c21a56f80ffeed5c2c1edadb7b1b73873026a3a /tty.c
parent0f5a2c86da5cf2cf024b0653fb84f2dc69c246a2 (diff)
parent9f66fb4fd779640c214df812afcdc0840d851c53 (diff)
downloadrtmux-8872a0da8e9588b0ec5eac1a1cc3753037ed68e1.tar.gz
rtmux-8872a0da8e9588b0ec5eac1a1cc3753037ed68e1.tar.bz2
rtmux-8872a0da8e9588b0ec5eac1a1cc3753037ed68e1.zip
Merge branch 'master' of github.com:tmux/tmux
Diffstat (limited to 'tty.c')
-rw-r--r--tty.c146
1 files changed, 105 insertions, 41 deletions
diff --git a/tty.c b/tty.c
index f50fbdb2..b99305ce 100644
--- a/tty.c
+++ b/tty.c
@@ -64,6 +64,8 @@ static int tty_large_region(struct tty *, const struct tty_ctx *);
static int tty_fake_bce(const struct tty *, const struct window_pane *,
u_int);
static void tty_redraw_region(struct tty *, const struct tty_ctx *);
+static void tty_clear_area(struct tty *, const struct tty_ctx *ctx, u_int,
+ u_int, u_int, u_int);
static void tty_emulate_repeat(struct tty *, enum tty_code_code,
enum tty_code_code, u_int);
static void tty_repeat_space(struct tty *, u_int);
@@ -79,7 +81,7 @@ static void tty_default_attributes(struct tty *, const struct window_pane *,
#define tty_use_margin(tty) \
((tty)->term_type == TTY_VT420)
-#define tty_pane_full_width(tty, ctx) \
+#define tty_pane_full_width(tty, ctx) \
((ctx)->xoff == 0 && screen_size_x((ctx)->wp->screen) >= (tty)->sx)
void
@@ -246,6 +248,9 @@ tty_start_tty(struct tty *tty)
tty_putcode(tty, TTYC_SGR0);
memcpy(&tty->cell, &grid_default_cell, sizeof tty->cell);
+ memcpy(&tty->last_cell, &grid_default_cell, sizeof tty->last_cell);
+ tty->last_wp = -1;
+
tty_putcode(tty, TTYC_RMKX);
if (tty_use_acs(tty))
tty_putcode(tty, TTYC_ENACS);
@@ -682,6 +687,17 @@ tty_redraw_region(struct tty *tty, const struct tty_ctx *ctx)
}
}
+static void
+tty_clear_area(struct tty *tty, const struct tty_ctx *ctx, u_int sx, u_int sy,
+ u_int ex, u_int ey)
+{
+ char s[64];
+
+ snprintf (s, sizeof s, "\033[32;%u;%u;%u;%u$x", ctx->yoff + sy + 1,
+ ctx->xoff + sx + 1, ctx->yoff + ey + 1, ctx->xoff + ex + 1);
+ tty_puts(tty, s);
+}
+
void
tty_draw_pane(struct tty *tty, const struct window_pane *wp, u_int py, u_int ox,
u_int oy)
@@ -895,6 +911,7 @@ 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);
tty_default_attributes(tty, wp, ctx->bg);
@@ -904,8 +921,11 @@ tty_cmd_clearline(struct tty *tty, const struct tty_ctx *ctx)
!tty_fake_bce(tty, wp, ctx->bg) &&
tty_term_has(tty->term, TTYC_EL))
tty_putcode(tty, TTYC_EL);
+ else if (tty->term_type == TTY_VT420 &&
+ !tty_fake_bce(tty, wp, ctx->bg))
+ tty_clear_area(tty, ctx, 0, ctx->ocy, sx - 1, ctx->ocy);
else
- tty_repeat_space(tty, screen_size_x(s));
+ tty_repeat_space(tty, sx);
}
void
@@ -913,6 +933,7 @@ 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);
tty_default_attributes(tty, wp, ctx->bg);
@@ -922,8 +943,11 @@ tty_cmd_clearendofline(struct tty *tty, const struct tty_ctx *ctx)
tty_term_has(tty->term, TTYC_EL) &&
!tty_fake_bce(tty, wp, ctx->bg))
tty_putcode(tty, TTYC_EL);
+ else if (tty->term_type == TTY_VT420 &&
+ !tty_fake_bce(tty, wp, ctx->bg))
+ tty_clear_area(tty, ctx, ctx->ocx, ctx->ocy, sx - 1, ctx->ocy);
else
- tty_repeat_space(tty, screen_size_x(s) - ctx->ocx);
+ tty_repeat_space(tty, sx - ctx->ocx);
}
void
@@ -938,7 +962,10 @@ tty_cmd_clearstartofline(struct tty *tty, const struct tty_ctx *ctx)
!tty_fake_bce(tty, ctx->wp, ctx->bg)) {
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
tty_putcode(tty, TTYC_EL1);
- } else {
+ } else if (tty->term_type == TTY_VT420 &&
+ !tty_fake_bce(tty, wp, ctx->bg))
+ tty_clear_area(tty, ctx, 0, ctx->ocy, ctx->ocx, ctx->ocy);
+ else {
tty_cursor_pane(tty, ctx, 0, ctx->ocy);
tty_repeat_space(tty, ctx->ocx + 1);
}
@@ -1020,32 +1047,51 @@ 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);
tty_default_attributes(tty, wp, ctx->bg);
- tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1);
+ tty_region_pane(tty, ctx, 0, sy - 1);
tty_margin_off(tty);
- tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
if (tty_pane_full_width(tty, ctx) &&
+ 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->term_type == TTY_VT420 &&
+ !tty_fake_bce(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_putcode(tty, TTYC_EL);
+ else
+ tty_repeat_space(tty, sx - ctx->ocx);
+ if (ctx->ocy != sy - 1) {
+ tty_clear_area(tty, ctx, 0, ctx->ocy + 1, sx - 1,
+ sy - 1);
+ }
+ } 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 != screen_size_y(s) - 1) {
+ if (ctx->ocy != sy - 1) {
tty_cursor_pane(tty, ctx, 0, ctx->ocy + 1);
- for (i = ctx->ocy + 1; i < screen_size_y(s); i++) {
+ for (i = ctx->ocy + 1; i < sy; i++) {
tty_putcode(tty, TTYC_EL);
- if (i == screen_size_y(s) - 1)
+ if (i == sy - 1)
continue;
tty_emulate_repeat(tty, TTYC_CUD, TTYC_CUD1, 1);
tty->cy++;
}
}
} else {
- tty_repeat_space(tty, screen_size_x(s) - ctx->ocx);
- for (j = ctx->ocy + 1; j < screen_size_y(s); j++) {
+ 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, screen_size_x(s));
+ tty_repeat_space(tty, sx);
}
}
}
@@ -1056,27 +1102,33 @@ 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);
- tty_attributes(tty, &grid_default_cell, wp);
+ tty_default_attributes(tty, wp, ctx->bg);
- tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1);
+ tty_region_pane(tty, ctx, 0, sy - 1);
tty_margin_off(tty);
- tty_cursor_pane(tty, ctx, 0, 0);
- if (tty_pane_full_width(tty, ctx) &&
+ if (tty->term_type == TTY_VT420 &&
+ !tty_fake_bce(tty, wp, ctx->bg))
+ tty_clear_area(tty, ctx, 0, 0, sx - 1, ctx->ocy - 1);
+ 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 < 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, screen_size_x(s));
+ tty_repeat_space(tty, sx);
}
}
+ tty_cursor_pane(tty, ctx, 0, ctx->ocy);
tty_repeat_space(tty, ctx->ocx + 1);
}
@@ -1086,27 +1138,37 @@ 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);
tty_default_attributes(tty, wp, ctx->bg);
- tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1);
+ tty_region_pane(tty, ctx, 0, sy - 1);
tty_margin_off(tty);
- tty_cursor_pane(tty, ctx, 0, 0);
if (tty_pane_full_width(tty, ctx) &&
+ 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->term_type == TTY_VT420 &&
+ !tty_fake_bce(tty, wp, ctx->bg))
+ tty_clear_area(tty, ctx, 0, 0, sx - 1, sy - 1);
+ else if (tty_pane_full_width(tty, ctx) &&
tty_term_has(tty->term, TTYC_EL) &&
!tty_fake_bce(tty, wp, ctx->bg)) {
- for (i = 0; i < screen_size_y(s); i++) {
+ tty_cursor_pane(tty, ctx, 0, 0);
+ for (i = 0; i < sy; i++) {
tty_putcode(tty, TTYC_EL);
- if (i != screen_size_y(s) - 1) {
+ if (i != sy - 1) {
tty_emulate_repeat(tty, TTYC_CUD, TTYC_CUD1, 1);
tty->cy++;
}
}
} else {
- for (j = 0; j < screen_size_y(s); j++) {
+ tty_cursor_pane(tty, ctx, 0, 0);
+ for (j = 0; j < sy; j++) {
tty_cursor_pane(tty, ctx, 0, j);
- tty_repeat_space(tty, screen_size_x(s));
+ tty_repeat_space(tty, sx);
}
}
}
@@ -1174,18 +1236,6 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx)
}
void
-tty_cmd_utf8character(struct tty *tty, const struct tty_ctx *ctx)
-{
- struct window_pane *wp = ctx->wp;
-
- /*
- * Cannot rely on not being a partial character, so just redraw the
- * whole line.
- */
- tty_draw_pane(tty, wp, ctx->ocy, ctx->xoff, ctx->yoff);
-}
-
-void
tty_cmd_setselection(struct tty *tty, const struct tty_ctx *ctx)
{
char *buf;
@@ -1262,13 +1312,15 @@ tty_reset(struct tty *tty)
{
struct grid_cell *gc = &tty->cell;
- if (grid_cells_equal(gc, &grid_default_cell))
- return;
+ if (!grid_cells_equal(gc, &grid_default_cell)) {
+ if ((gc->attr & GRID_ATTR_CHARSET) && tty_use_acs(tty))
+ tty_putcode(tty, TTYC_RMACS);
+ tty_putcode(tty, TTYC_SGR0);
+ memcpy(gc, &grid_default_cell, sizeof *gc);
+ }
- if ((gc->attr & GRID_ATTR_CHARSET) && tty_use_acs(tty))
- tty_putcode(tty, TTYC_RMACS);
- tty_putcode(tty, TTYC_SGR0);
- memcpy(gc, &grid_default_cell, sizeof *gc);
+ memcpy(&tty->last_cell, &grid_default_cell, sizeof tty->last_cell);
+ tty->last_wp = -1;
}
/* Turn off margin. */
@@ -1490,6 +1542,18 @@ tty_attributes(struct tty *tty, const struct grid_cell *gc,
struct grid_cell *tc = &tty->cell, gc2;
u_char changed;
+ /* Ignore cell if it is the same as the last one. */
+ if (wp != NULL &&
+ (int)wp->id == tty->last_wp &&
+ ~(wp->window->flags & WINDOW_STYLECHANGED) &&
+ gc->attr == tty->last_cell.attr &&
+ gc->fg == tty->last_cell.fg &&
+ gc->bg == tty->last_cell.bg)
+ return;
+ tty->last_wp = (wp != NULL ? (int)wp->id : -1);
+ memcpy(&tty->last_cell, gc, sizeof tty->last_cell);
+
+ /* Copy cell and update default colours. */
memcpy(&gc2, gc, sizeof gc2);
if (wp != NULL)
tty_default_colours(&gc2, wp);