=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/tmux/tty.c,v retrieving revision 1.372 retrieving revision 1.373 diff -c -r1.372 -r1.373 *** src/usr.bin/tmux/tty.c 2020/05/16 15:27:08 1.372 --- src/usr.bin/tmux/tty.c 2020/05/16 15:34:08 1.373 *************** *** 1,4 **** ! /* $OpenBSD: tty.c,v 1.372 2020/05/16 15:27:08 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott --- 1,4 ---- ! /* $OpenBSD: tty.c,v 1.373 2020/05/16 15:34:08 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott *************** *** 34,40 **** static int tty_log_fd = -1; ! static int tty_client_ready(struct client *, struct window_pane *); static void tty_set_italics(struct tty *); static int tty_try_colour(struct tty *, int, const char *); --- 34,40 ---- static int tty_log_fd = -1; ! static int tty_client_ready(struct client *); static void tty_set_italics(struct tty *); static int tty_try_colour(struct tty *, int, const char *); *************** *** 45,56 **** const struct tty_ctx *, u_int, u_int); static void tty_invalidate(struct tty *); static void tty_colours(struct tty *, const struct grid_cell *); ! static void tty_check_fg(struct tty *, struct window_pane *, ! struct grid_cell *); ! static void tty_check_bg(struct tty *, struct window_pane *, ! struct grid_cell *); ! static void tty_check_us(struct tty *, struct window_pane *, ! struct grid_cell *); static void tty_colours_fg(struct tty *, const struct grid_cell *); static void tty_colours_bg(struct tty *, const struct grid_cell *); static void tty_colours_us(struct tty *, const struct grid_cell *); --- 45,53 ---- const struct tty_ctx *, u_int, u_int); static void tty_invalidate(struct tty *); static void tty_colours(struct tty *, const struct grid_cell *); ! static void tty_check_fg(struct tty *, int *, struct grid_cell *); ! static void tty_check_bg(struct tty *, int *, struct grid_cell *); ! static void tty_check_us(struct tty *, int *, struct grid_cell *); static void tty_colours_fg(struct tty *, const struct grid_cell *); static void tty_colours_bg(struct tty *, const struct grid_cell *); static void tty_colours_us(struct tty *, const struct grid_cell *); *************** *** 61,77 **** static void tty_margin_pane(struct tty *, const struct tty_ctx *); static void tty_margin(struct tty *, u_int, u_int); static int tty_large_region(struct tty *, const struct tty_ctx *); ! static int tty_fake_bce(const struct tty *, struct window_pane *, u_int); static void tty_redraw_region(struct tty *, const struct tty_ctx *); 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); static void tty_draw_pane(struct tty *, const struct tty_ctx *, u_int); static void tty_cell(struct tty *, const struct grid_cell *, ! struct window_pane *); ! static void tty_default_colours(struct grid_cell *, struct window_pane *); ! static void tty_default_attributes(struct tty *, struct window_pane *, ! u_int); #define tty_use_margin(tty) \ (tty->term->flags & TERM_DECSLRM) --- 58,74 ---- static void tty_margin_pane(struct tty *, const struct tty_ctx *); static void tty_margin(struct tty *, u_int, u_int); static int tty_large_region(struct tty *, const struct tty_ctx *); ! static int tty_fake_bce(const struct tty *, const struct grid_cell *, ! u_int); static void tty_redraw_region(struct tty *, const struct tty_ctx *); 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); static void tty_draw_pane(struct tty *, const struct tty_ctx *, u_int); static void tty_cell(struct tty *, const struct grid_cell *, ! const struct grid_cell *, int *); ! static void tty_default_attributes(struct tty *, const struct grid_cell *, ! int *, u_int); #define tty_use_margin(tty) \ (tty->term->flags & TERM_DECSLRM) *************** *** 888,893 **** --- 885,911 ---- c->flags |= (CLIENT_REDRAWWINDOW|CLIENT_REDRAWSTATUS); } + /* Get a palette entry. */ + static int + tty_get_palette(int *palette, int c) + { + int new; + + if (palette == NULL) + return (-1); + + new = -1; + if (c < 8) + new = palette[c]; + else if (c >= 90 && c <= 97) + new = palette[8 + c - 90]; + else if (c & COLOUR_FLAG_256) + new = palette[c & ~COLOUR_FLAG_256]; + if (new == 0) + return (-1); + return (new); + } + /* * Is the region large enough to be worth redrawing once later rather than * probably several times now? Currently yes if it is more than 50% of the *************** *** 904,921 **** * emulated. */ static int ! tty_fake_bce(const struct tty *tty, struct window_pane *wp, u_int bg) { - struct grid_cell gc; - if (tty_term_flag(tty->term, TTYC_BCE)) return (0); ! ! memcpy(&gc, &grid_default_cell, sizeof gc); ! if (wp != NULL) ! tty_default_colours(&gc, wp); ! ! if (!COLOUR_DEFAULT(bg) || !COLOUR_DEFAULT(gc.bg)) return (1); return (0); } --- 922,932 ---- * emulated. */ static int ! tty_fake_bce(const struct tty *tty, const struct grid_cell *gc, u_int bg) { if (tty_term_flag(tty->term, TTYC_BCE)) return (0); ! if (!COLOUR_DEFAULT(bg) || !COLOUR_DEFAULT(gc->bg)) return (1); return (0); } *************** *** 929,944 **** tty_redraw_region(struct tty *tty, const struct tty_ctx *ctx) { struct client *c = tty->client; - struct window_pane *wp = ctx->wp; u_int i; /* ! * If region is large, schedule a window redraw. In most cases this is ! * likely to be followed by some more scrolling. */ if (tty_large_region(tty, ctx)) { ! log_debug("%s: %s, large redraw of %%%u", __func__, c->name, wp->id); ! wp->flags |= PANE_REDRAW; return; } --- 940,954 ---- tty_redraw_region(struct tty *tty, const struct tty_ctx *ctx) { struct client *c = tty->client; u_int i; /* ! * If region is large, schedule a redraw. In most cases this is likely ! * to be followed by some more scrolling. */ if (tty_large_region(tty, ctx)) { ! log_debug("%s: %s large redraw", __func__, c->name); ! ctx->redraw_cb(ctx); return; } *************** *** 977,984 **** tty_clamp_line(struct tty *tty, const struct tty_ctx *ctx, u_int px, u_int py, u_int nx, u_int *i, u_int *x, u_int *rx, u_int *ry) { ! struct window_pane *wp = ctx->wp; ! u_int xoff = wp->xoff + px; if (!tty_is_visible(tty, ctx, px, py, nx, 1)) return (0); --- 987,993 ---- tty_clamp_line(struct tty *tty, const struct tty_ctx *ctx, u_int px, u_int py, u_int nx, u_int *i, u_int *x, u_int *rx, u_int *ry) { ! u_int xoff = ctx->rxoff + px; if (!tty_is_visible(tty, ctx, px, py, nx, 1)) return (0); *************** *** 1013,1020 **** /* Clear a line. */ static void ! tty_clear_line(struct tty *tty, struct window_pane *wp, u_int py, u_int px, ! u_int nx, u_int bg) { struct client *c = tty->client; --- 1022,1029 ---- /* Clear a line. */ static void ! tty_clear_line(struct tty *tty, const struct grid_cell *defaults, u_int py, ! u_int px, u_int nx, u_int bg) { struct client *c = tty->client; *************** *** 1025,1031 **** 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); --- 1034,1040 ---- return; /* If genuine BCE is available, can try escape sequences. */ ! if (!tty_fake_bce(tty, defaults, 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); *************** *** 1064,1070 **** log_debug("%s: %s, %u at %u,%u", __func__, c->name, nx, px, py); if (tty_clamp_line(tty, ctx, px, py, nx, &i, &x, &rx, &ry)) ! tty_clear_line(tty, ctx->wp, ry, x, rx, bg); } /* Clamp area position to visible part of pane. */ --- 1073,1079 ---- log_debug("%s: %s, %u at %u,%u", __func__, c->name, nx, px, py); if (tty_clamp_line(tty, ctx, px, py, nx, &i, &x, &rx, &ry)) ! tty_clear_line(tty, &ctx->defaults, ry, x, rx, bg); } /* Clamp area position to visible part of pane. */ *************** *** 1073,1080 **** u_int nx, u_int ny, u_int *i, u_int *j, u_int *x, u_int *y, u_int *rx, u_int *ry) { ! struct window_pane *wp = ctx->wp; ! u_int xoff = wp->xoff + px, yoff = wp->yoff + py; if (!tty_is_visible(tty, ctx, px, py, nx, ny)) return (0); --- 1082,1088 ---- u_int nx, u_int ny, u_int *i, u_int *j, u_int *x, u_int *y, u_int *rx, u_int *ry) { ! u_int xoff = ctx->rxoff + px, yoff = ctx->ryoff + py; if (!tty_is_visible(tty, ctx, px, py, nx, ny)) return (0); *************** *** 1132,1139 **** /* Clear an area, adjusting to visible part of pane. */ static void ! tty_clear_area(struct tty *tty, struct window_pane *wp, u_int py, u_int ny, ! u_int px, u_int nx, u_int bg) { struct client *c = tty->client; u_int yy; --- 1140,1147 ---- /* Clear an area, adjusting to visible part of pane. */ static void ! tty_clear_area(struct tty *tty, const struct grid_cell *defaults, u_int py, ! u_int ny, u_int px, u_int nx, u_int bg) { struct client *c = tty->client; u_int yy; *************** *** 1146,1152 **** return; /* If genuine BCE is available, can try escape sequences. */ ! if (!tty_fake_bce(tty, wp, bg)) { /* Use ED if clearing off the bottom of the terminal. */ if (px == 0 && px + nx >= tty->sx && --- 1154,1160 ---- return; /* If genuine BCE is available, can try escape sequences. */ ! if (!tty_fake_bce(tty, defaults, bg)) { /* Use ED if clearing off the bottom of the terminal. */ if (px == 0 && px + nx >= tty->sx && *************** *** 1199,1205 **** /* 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); } /* Clear an area in a pane. */ --- 1207,1213 ---- /* Couldn't use an escape sequence, loop over the lines. */ for (yy = py; yy < py + ny; yy++) ! tty_clear_line(tty, defaults, yy, px, nx, bg); } /* Clear an area in a pane. */ *************** *** 1210,1233 **** u_int i, j, x, y, rx, ry; if (tty_clamp_area(tty, ctx, px, py, nx, ny, &i, &j, &x, &y, &rx, &ry)) ! tty_clear_area(tty, ctx->wp, y, ry, x, rx, bg); } static void tty_draw_pane(struct tty *tty, const struct tty_ctx *ctx, u_int py) { ! struct window_pane *wp = ctx->wp; ! struct screen *s = wp->screen; ! u_int nx = ctx->sx, i, x, rx, ry; log_debug("%s: %s %u %d", __func__, tty->client->name, py, ctx->bigger); if (!ctx->bigger) { ! tty_draw_line(tty, wp, s, 0, py, nx, ctx->xoff, ctx->yoff + py); return; } ! if (tty_clamp_line(tty, ctx, 0, py, nx, &i, &x, &rx, &ry)) ! tty_draw_line(tty, wp, s, i, py, rx, x, ry); } static const struct grid_cell * --- 1218,1243 ---- u_int i, j, x, y, rx, ry; if (tty_clamp_area(tty, ctx, px, py, nx, ny, &i, &j, &x, &y, &rx, &ry)) ! tty_clear_area(tty, &ctx->defaults, y, ry, x, rx, bg); } static void tty_draw_pane(struct tty *tty, const struct tty_ctx *ctx, u_int py) { ! struct screen *s = ctx->s; ! u_int nx = ctx->sx, i, x, rx, ry; log_debug("%s: %s %u %d", __func__, tty->client->name, py, ctx->bigger); if (!ctx->bigger) { ! tty_draw_line(tty, s, 0, py, nx, ctx->xoff, ctx->yoff + py, ! &ctx->defaults, ctx->palette); return; } ! if (tty_clamp_line(tty, ctx, 0, py, nx, &i, &x, &rx, &ry)) { ! tty_draw_line(tty, s, i, py, rx, x, ry, &ctx->defaults, ! ctx->palette); ! } } static const struct grid_cell * *************** *** 1265,1272 **** } void ! tty_draw_line(struct tty *tty, struct window_pane *wp, struct screen *s, ! u_int px, u_int py, u_int nx, u_int atx, u_int aty) { struct grid *gd = s->grid; struct grid_cell gc, last; --- 1275,1282 ---- } void ! tty_draw_line(struct tty *tty, struct screen *s, u_int px, u_int py, u_int nx, ! u_int atx, u_int aty, const struct grid_cell *defaults, int *palette) { struct grid *gd = s->grid; struct grid_cell gc, last; *************** *** 1314,1321 **** gl = NULL; else gl = grid_get_line(gd, gd->hsize + py - 1); ! if (wp == NULL || ! gl == NULL || (~gl->flags & GRID_LINE_WRAPPED) || atx != 0 || tty->cx < tty->sx || --- 1324,1330 ---- gl = NULL; else gl = grid_get_line(gd, gd->hsize + py - 1); ! if (gl == NULL || (~gl->flags & GRID_LINE_WRAPPED) || atx != 0 || tty->cx < tty->sx || *************** *** 1324,1331 **** atx == 0 && px + sx != nx && tty_term_has(tty->term, TTYC_EL1) && ! !tty_fake_bce(tty, wp, 8)) { ! tty_default_attributes(tty, wp, 8); tty_cursor(tty, nx - 1, aty); tty_putcode(tty, TTYC_EL1); cleared = 1; --- 1333,1340 ---- atx == 0 && px + sx != nx && tty_term_has(tty->term, TTYC_EL1) && ! !tty_fake_bce(tty, defaults, 8)) { ! tty_default_attributes(tty, defaults, palette, 8); tty_cursor(tty, nx - 1, aty); tty_putcode(tty, TTYC_EL1); cleared = 1; *************** *** 1352,1362 **** gcp->us != last.us || ux + width + gcp->data.width > nx || (sizeof buf) - len < gcp->data.size)) { ! tty_attributes(tty, &last, wp); if (last.flags & GRID_FLAG_CLEARED) { log_debug("%s: %zu cleared", __func__, len); ! tty_clear_line(tty, wp, aty, atx + ux, width, ! last.bg); } else { if (!wrapped || atx != 0 || ux != 0) tty_cursor(tty, atx + ux, aty); --- 1361,1371 ---- gcp->us != last.us || ux + width + gcp->data.width > nx || (sizeof buf) - len < gcp->data.size)) { ! tty_attributes(tty, &last, defaults, palette); if (last.flags & GRID_FLAG_CLEARED) { log_debug("%s: %zu cleared", __func__, len); ! tty_clear_line(tty, defaults, aty, atx + ux, ! width, last.bg); } else { if (!wrapped || atx != 0 || ux != 0) tty_cursor(tty, atx + ux, aty); *************** *** 1376,1382 **** if (!tty_check_overlay(tty, atx + ux, aty)) ux += gcp->data.width; else if (ux + gcp->data.width > nx) { ! tty_attributes(tty, &last, wp); tty_cursor(tty, atx + ux, aty); for (j = 0; j < gcp->data.width; j++) { if (ux + j > nx) --- 1385,1391 ---- if (!tty_check_overlay(tty, atx + ux, aty)) ux += gcp->data.width; else if (ux + gcp->data.width > nx) { ! tty_attributes(tty, &last, defaults, palette); tty_cursor(tty, atx + ux, aty); for (j = 0; j < gcp->data.width; j++) { if (ux + j > nx) *************** *** 1385,1391 **** ux++; } } else if (gcp->attr & GRID_ATTR_CHARSET) { ! tty_attributes(tty, &last, wp); tty_cursor(tty, atx + ux, aty); for (j = 0; j < gcp->data.size; j++) tty_putc(tty, gcp->data.data[j]); --- 1394,1400 ---- ux++; } } else if (gcp->attr & GRID_ATTR_CHARSET) { ! tty_attributes(tty, &last, defaults, palette); tty_cursor(tty, atx + ux, aty); for (j = 0; j < gcp->data.size; j++) tty_putc(tty, gcp->data.data[j]); *************** *** 1397,1406 **** } } if (len != 0 && ((~last.flags & GRID_FLAG_CLEARED) || last.bg != 8)) { ! tty_attributes(tty, &last, wp); if (last.flags & GRID_FLAG_CLEARED) { log_debug("%s: %zu cleared (end)", __func__, len); ! tty_clear_line(tty, wp, aty, atx + ux, width, last.bg); } else { if (!wrapped || atx != 0 || ux != 0) tty_cursor(tty, atx + ux, aty); --- 1406,1416 ---- } } if (len != 0 && ((~last.flags & GRID_FLAG_CLEARED) || last.bg != 8)) { ! tty_attributes(tty, &last, defaults, palette); if (last.flags & GRID_FLAG_CLEARED) { log_debug("%s: %zu cleared (end)", __func__, len); ! tty_clear_line(tty, defaults, aty, atx + ux, width, ! last.bg); } else { if (!wrapped || atx != 0 || ux != 0) tty_cursor(tty, atx + ux, aty); *************** *** 1412,1419 **** if (!cleared && ux < nx) { log_debug("%s: %u to end of line (%zu cleared)", __func__, nx - ux, len); ! tty_default_attributes(tty, wp, 8); ! tty_clear_line(tty, wp, aty, atx + ux, nx - ux, 8); } tty->flags = (tty->flags & ~TTY_NOCURSOR) | flags; --- 1422,1429 ---- if (!cleared && ux < nx) { log_debug("%s: %u to end of line (%zu cleared)", __func__, nx - ux, len); ! tty_default_attributes(tty, defaults, palette, 8); ! tty_clear_line(tty, defaults, aty, atx + ux, nx - ux, 8); } tty->flags = (tty->flags & ~TTY_NOCURSOR) | flags; *************** *** 1451,1457 **** } static int ! tty_client_ready(struct client *c, struct window_pane *wp) { if (c->session == NULL || c->tty.term == NULL) return (0); --- 1461,1467 ---- } static int ! tty_client_ready(struct client *c) { if (c->session == NULL || c->tty.term == NULL) return (0); *************** *** 1459,1468 **** return (0); if (c->tty.flags & TTY_FREEZE) return (0); - if (c->session->curw->window != wp->window) - return (0); - if (wp->layout_cell == NULL) - return (0); return (1); } --- 1469,1474 ---- *************** *** 1470,1505 **** tty_write(void (*cmdfn)(struct tty *, const struct tty_ctx *), struct tty_ctx *ctx) { ! struct window_pane *wp = ctx->wp; ! struct client *c; ! if (wp == NULL) return; - if (wp->flags & (PANE_REDRAW|PANE_DROP)) - return; - TAILQ_FOREACH(c, &clients, entry) { ! if (!tty_client_ready(c, wp)) continue; ! if (c->flags & CLIENT_REDRAWPANES) { ! /* ! * Redraw is already deferred to redraw another pane - ! * redraw this one also when that happens. ! */ ! log_debug("adding %%%u to deferred redraw", wp->id); ! wp->flags |= PANE_REDRAW; break; ! } ! ! ctx->bigger = tty_window_offset(&c->tty, &ctx->wox, &ctx->woy, ! &ctx->wsx, &ctx->wsy); ! ! ctx->xoff = wp->xoff; ! ctx->yoff = wp->yoff; ! ! if (status_at_line(c) == 0) ! ctx->yoff += status_line_size(c); ! cmdfn(&c->tty, ctx); } } --- 1476,1494 ---- tty_write(void (*cmdfn)(struct tty *, const struct tty_ctx *), struct tty_ctx *ctx) { ! struct client *c; ! int state; ! if (ctx->set_client_cb == NULL) return; TAILQ_FOREACH(c, &clients, entry) { ! if (!tty_client_ready(c)) continue; ! state = ctx->set_client_cb(ctx, c); ! if (state == -1) break; ! if (state == 0) ! continue; cmdfn(&c->tty, ctx); } } *************** *** 1507,1524 **** void tty_cmd_insertcharacter(struct tty *tty, const struct tty_ctx *ctx) { - struct window_pane *wp = ctx->wp; - if (ctx->bigger || !tty_full_width(tty, ctx) || ! tty_fake_bce(tty, wp, ctx->bg) || (!tty_term_has(tty->term, TTYC_ICH) && !tty_term_has(tty->term, TTYC_ICH1))) { tty_draw_pane(tty, ctx, ctx->ocy); return; } ! tty_default_attributes(tty, wp, ctx->bg); tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); --- 1496,1511 ---- void tty_cmd_insertcharacter(struct tty *tty, const struct tty_ctx *ctx) { if (ctx->bigger || !tty_full_width(tty, ctx) || ! tty_fake_bce(tty, &ctx->defaults, ctx->bg) || (!tty_term_has(tty->term, TTYC_ICH) && !tty_term_has(tty->term, TTYC_ICH1))) { tty_draw_pane(tty, ctx, ctx->ocy); return; } ! tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg); tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); *************** *** 1528,1545 **** void tty_cmd_deletecharacter(struct tty *tty, const struct tty_ctx *ctx) { - struct window_pane *wp = ctx->wp; - if (ctx->bigger || !tty_full_width(tty, ctx) || ! tty_fake_bce(tty, wp, ctx->bg) || (!tty_term_has(tty->term, TTYC_DCH) && !tty_term_has(tty->term, TTYC_DCH1))) { tty_draw_pane(tty, ctx, ctx->ocy); return; } ! tty_default_attributes(tty, wp, ctx->bg); tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); --- 1515,1530 ---- void tty_cmd_deletecharacter(struct tty *tty, const struct tty_ctx *ctx) { if (ctx->bigger || !tty_full_width(tty, ctx) || ! tty_fake_bce(tty, &ctx->defaults, ctx->bg) || (!tty_term_has(tty->term, TTYC_DCH) && !tty_term_has(tty->term, TTYC_DCH1))) { tty_draw_pane(tty, ctx, ctx->ocy); return; } ! tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg); tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); *************** *** 1554,1565 **** return; } ! tty_default_attributes(tty, ctx->wp, ctx->bg); tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); if (tty_term_has(tty->term, TTYC_ECH) && ! !tty_fake_bce(tty, ctx->wp, 8)) tty_putcode1(tty, TTYC_ECH, ctx->num); else tty_repeat_space(tty, ctx->num); --- 1539,1550 ---- return; } ! tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg); tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); if (tty_term_has(tty->term, TTYC_ECH) && ! !tty_fake_bce(tty, &ctx->defaults, 8)) tty_putcode1(tty, TTYC_ECH, ctx->num); else tty_repeat_space(tty, ctx->num); *************** *** 1570,1585 **** { if (ctx->bigger || !tty_full_width(tty, ctx) || ! tty_fake_bce(tty, ctx->wp, ctx->bg) || !tty_term_has(tty->term, TTYC_CSR) || !tty_term_has(tty->term, TTYC_IL1) || ! ctx->wp->sx == 1 || ! ctx->wp->sy == 1) { tty_redraw_region(tty, ctx); return; } ! tty_default_attributes(tty, ctx->wp, ctx->bg); tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower); tty_margin_off(tty); --- 1555,1570 ---- { if (ctx->bigger || !tty_full_width(tty, ctx) || ! tty_fake_bce(tty, &ctx->defaults, ctx->bg) || !tty_term_has(tty->term, TTYC_CSR) || !tty_term_has(tty->term, TTYC_IL1) || ! ctx->sx == 1 || ! ctx->sy == 1) { tty_redraw_region(tty, ctx); return; } ! tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg); tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower); tty_margin_off(tty); *************** *** 1594,1609 **** { if (ctx->bigger || !tty_full_width(tty, ctx) || ! tty_fake_bce(tty, ctx->wp, ctx->bg) || !tty_term_has(tty->term, TTYC_CSR) || !tty_term_has(tty->term, TTYC_DL1) || ! ctx->wp->sx == 1 || ! ctx->wp->sy == 1) { tty_redraw_region(tty, ctx); return; } ! tty_default_attributes(tty, ctx->wp, ctx->bg); tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower); tty_margin_off(tty); --- 1579,1594 ---- { if (ctx->bigger || !tty_full_width(tty, ctx) || ! tty_fake_bce(tty, &ctx->defaults, ctx->bg) || !tty_term_has(tty->term, TTYC_CSR) || !tty_term_has(tty->term, TTYC_DL1) || ! ctx->sx == 1 || ! ctx->sy == 1) { tty_redraw_region(tty, ctx); return; } ! tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg); tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower); tty_margin_off(tty); *************** *** 1616,1635 **** void tty_cmd_clearline(struct tty *tty, const struct tty_ctx *ctx) { ! struct window_pane *wp = ctx->wp; - tty_default_attributes(tty, wp, ctx->bg); - tty_clear_pane_line(tty, ctx, ctx->ocy, 0, ctx->sx, ctx->bg); } void tty_cmd_clearendofline(struct tty *tty, const struct tty_ctx *ctx) { ! struct window_pane *wp = ctx->wp; ! u_int nx = ctx->sx - ctx->ocx; ! tty_default_attributes(tty, wp, ctx->bg); tty_clear_pane_line(tty, ctx, ctx->ocy, ctx->ocx, nx, ctx->bg); } --- 1601,1617 ---- void tty_cmd_clearline(struct tty *tty, const struct tty_ctx *ctx) { ! tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg); tty_clear_pane_line(tty, ctx, ctx->ocy, 0, ctx->sx, ctx->bg); } void tty_cmd_clearendofline(struct tty *tty, const struct tty_ctx *ctx) { ! u_int nx = ctx->sx - ctx->ocx; ! tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg); tty_clear_pane_line(tty, ctx, ctx->ocy, ctx->ocx, nx, ctx->bg); } *************** *** 1637,1670 **** void tty_cmd_clearstartofline(struct tty *tty, const struct tty_ctx *ctx) { ! struct window_pane *wp = ctx->wp; - tty_default_attributes(tty, wp, ctx->bg); - tty_clear_pane_line(tty, ctx, ctx->ocy, 0, ctx->ocx + 1, ctx->bg); } void tty_cmd_reverseindex(struct tty *tty, const struct tty_ctx *ctx) { - struct window_pane *wp = ctx->wp; - if (ctx->ocy != ctx->orupper) return; if (ctx->bigger || (!tty_full_width(tty, ctx) && !tty_use_margin(tty)) || ! tty_fake_bce(tty, wp, 8) || !tty_term_has(tty->term, TTYC_CSR) || (!tty_term_has(tty->term, TTYC_RI) && !tty_term_has(tty->term, TTYC_RIN)) || ! ctx->wp->sx == 1 || ! ctx->wp->sy == 1) { tty_redraw_region(tty, ctx); return; } ! tty_default_attributes(tty, wp, ctx->bg); tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower); tty_margin_pane(tty, ctx); --- 1619,1648 ---- void tty_cmd_clearstartofline(struct tty *tty, const struct tty_ctx *ctx) { ! tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg); tty_clear_pane_line(tty, ctx, ctx->ocy, 0, ctx->ocx + 1, ctx->bg); } void tty_cmd_reverseindex(struct tty *tty, const struct tty_ctx *ctx) { if (ctx->ocy != ctx->orupper) return; if (ctx->bigger || (!tty_full_width(tty, ctx) && !tty_use_margin(tty)) || ! tty_fake_bce(tty, &ctx->defaults, 8) || !tty_term_has(tty->term, TTYC_CSR) || (!tty_term_has(tty->term, TTYC_RI) && !tty_term_has(tty->term, TTYC_RIN)) || ! ctx->sx == 1 || ! ctx->sy == 1) { tty_redraw_region(tty, ctx); return; } ! tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg); tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower); tty_margin_pane(tty, ctx); *************** *** 1679,1700 **** void tty_cmd_linefeed(struct tty *tty, const struct tty_ctx *ctx) { - struct window_pane *wp = ctx->wp; - if (ctx->ocy != ctx->orlower) return; if (ctx->bigger || (!tty_full_width(tty, ctx) && !tty_use_margin(tty)) || ! tty_fake_bce(tty, wp, 8) || !tty_term_has(tty->term, TTYC_CSR) || ! wp->sx == 1 || ! wp->sy == 1) { tty_redraw_region(tty, ctx); return; } ! tty_default_attributes(tty, wp, ctx->bg); tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower); tty_margin_pane(tty, ctx); --- 1657,1676 ---- void tty_cmd_linefeed(struct tty *tty, const struct tty_ctx *ctx) { if (ctx->ocy != ctx->orlower) return; if (ctx->bigger || (!tty_full_width(tty, ctx) && !tty_use_margin(tty)) || ! tty_fake_bce(tty, &ctx->defaults, 8) || !tty_term_has(tty->term, TTYC_CSR) || ! ctx->sx == 1 || ! ctx->sy == 1) { tty_redraw_region(tty, ctx); return; } ! tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg); tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower); tty_margin_pane(tty, ctx); *************** *** 1720,1739 **** void tty_cmd_scrollup(struct tty *tty, const struct tty_ctx *ctx) { ! struct window_pane *wp = ctx->wp; ! u_int i; if (ctx->bigger || (!tty_full_width(tty, ctx) && !tty_use_margin(tty)) || ! tty_fake_bce(tty, wp, 8) || !tty_term_has(tty->term, TTYC_CSR) || ! wp->sx == 1 || ! wp->sy == 1) { tty_redraw_region(tty, ctx); return; } ! tty_default_attributes(tty, wp, ctx->bg); tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower); tty_margin_pane(tty, ctx); --- 1696,1714 ---- void tty_cmd_scrollup(struct tty *tty, const struct tty_ctx *ctx) { ! u_int i; if (ctx->bigger || (!tty_full_width(tty, ctx) && !tty_use_margin(tty)) || ! tty_fake_bce(tty, &ctx->defaults, 8) || !tty_term_has(tty->term, TTYC_CSR) || ! ctx->sx == 1 || ! ctx->sy == 1) { tty_redraw_region(tty, ctx); return; } ! tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg); tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower); tty_margin_pane(tty, ctx); *************** *** 1757,1778 **** void tty_cmd_scrolldown(struct tty *tty, const struct tty_ctx *ctx) { ! struct window_pane *wp = ctx->wp; ! u_int i; if (ctx->bigger || (!tty_full_width(tty, ctx) && !tty_use_margin(tty)) || ! tty_fake_bce(tty, wp, 8) || !tty_term_has(tty->term, TTYC_CSR) || (!tty_term_has(tty->term, TTYC_RI) && !tty_term_has(tty->term, TTYC_RIN)) || ! wp->sx == 1 || ! wp->sy == 1) { tty_redraw_region(tty, ctx); return; } ! tty_default_attributes(tty, wp, ctx->bg); tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower); tty_margin_pane(tty, ctx); --- 1732,1752 ---- void tty_cmd_scrolldown(struct tty *tty, const struct tty_ctx *ctx) { ! u_int i; if (ctx->bigger || (!tty_full_width(tty, ctx) && !tty_use_margin(tty)) || ! tty_fake_bce(tty, &ctx->defaults, 8) || !tty_term_has(tty->term, TTYC_CSR) || (!tty_term_has(tty->term, TTYC_RI) && !tty_term_has(tty->term, TTYC_RIN)) || ! ctx->sx == 1 || ! ctx->sy == 1) { tty_redraw_region(tty, ctx); return; } ! tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg); tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower); tty_margin_pane(tty, ctx); *************** *** 1789,1798 **** void tty_cmd_clearendofscreen(struct tty *tty, const struct tty_ctx *ctx) { ! struct window_pane *wp = ctx->wp; ! u_int px, py, nx, ny; ! tty_default_attributes(tty, wp, ctx->bg); tty_region_pane(tty, ctx, 0, ctx->sy - 1); tty_margin_off(tty); --- 1763,1771 ---- void tty_cmd_clearendofscreen(struct tty *tty, const struct tty_ctx *ctx) { ! u_int px, py, nx, ny; ! tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg); tty_region_pane(tty, ctx, 0, ctx->sy - 1); tty_margin_off(tty); *************** *** 1814,1823 **** void tty_cmd_clearstartofscreen(struct tty *tty, const struct tty_ctx *ctx) { ! struct window_pane *wp = ctx->wp; ! u_int px, py, nx, ny; ! tty_default_attributes(tty, wp, ctx->bg); tty_region_pane(tty, ctx, 0, ctx->sy - 1); tty_margin_off(tty); --- 1787,1795 ---- void tty_cmd_clearstartofscreen(struct tty *tty, const struct tty_ctx *ctx) { ! u_int px, py, nx, ny; ! tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg); tty_region_pane(tty, ctx, 0, ctx->sy - 1); tty_margin_off(tty); *************** *** 1839,1848 **** void tty_cmd_clearscreen(struct tty *tty, const struct tty_ctx *ctx) { ! struct window_pane *wp = ctx->wp; ! u_int px, py, nx, ny; ! tty_default_attributes(tty, wp, ctx->bg); tty_region_pane(tty, ctx, 0, ctx->sy - 1); tty_margin_off(tty); --- 1811,1819 ---- void tty_cmd_clearscreen(struct tty *tty, const struct tty_ctx *ctx) { ! u_int px, py, nx, ny; ! tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg); tty_region_pane(tty, ctx, 0, ctx->sy - 1); tty_margin_off(tty); *************** *** 1858,1872 **** void tty_cmd_alignmenttest(struct tty *tty, const struct tty_ctx *ctx) { ! struct window_pane *wp = ctx->wp; ! u_int i, j; if (ctx->bigger) { ! wp->flags |= PANE_REDRAW; return; } ! tty_attributes(tty, &grid_default_cell, wp); tty_region_pane(tty, ctx, 0, ctx->sy - 1); tty_margin_off(tty); --- 1829,1842 ---- void tty_cmd_alignmenttest(struct tty *tty, const struct tty_ctx *ctx) { ! u_int i, j; if (ctx->bigger) { ! ctx->redraw_cb(ctx); return; } ! tty_attributes(tty, &grid_default_cell, &ctx->defaults, ctx->palette); tty_region_pane(tty, ctx, 0, ctx->sy - 1); tty_margin_off(tty); *************** *** 1892,1905 **** tty_margin_off(tty); tty_cursor_pane_unless_wrap(tty, ctx, ctx->ocx, ctx->ocy); ! tty_cell(tty, ctx->cell, ctx->wp); } void tty_cmd_cells(struct tty *tty, const struct tty_ctx *ctx) { - struct window_pane *wp = ctx->wp; - if (!tty_is_visible(tty, ctx, ctx->ocx, ctx->ocy, ctx->num, 1)) return; --- 1862,1873 ---- tty_margin_off(tty); tty_cursor_pane_unless_wrap(tty, ctx, ctx->ocx, ctx->ocy); ! tty_cell(tty, ctx->cell, &ctx->defaults, ctx->palette); } void tty_cmd_cells(struct tty *tty, const struct tty_ctx *ctx) { if (!tty_is_visible(tty, ctx, ctx->ocx, ctx->ocy, ctx->num, 1)) return; *************** *** 1915,1928 **** tty->cy == tty->rlower) tty_draw_pane(tty, ctx, ctx->ocy); else ! wp->flags |= PANE_REDRAW; return; } tty_margin_off(tty); tty_cursor_pane_unless_wrap(tty, ctx, ctx->ocx, ctx->ocy); ! tty_attributes(tty, ctx->cell, ctx->wp); tty_putn(tty, ctx->ptr, ctx->num, ctx->num); } --- 1883,1896 ---- tty->cy == tty->rlower) tty_draw_pane(tty, ctx, ctx->ocy); else ! ctx->redraw_cb(ctx); return; } tty_margin_off(tty); tty_cursor_pane_unless_wrap(tty, ctx, ctx->ocx, ctx->ocy); ! tty_attributes(tty, ctx->cell, &ctx->defaults, ctx->palette); tty_putn(tty, ctx->ptr, ctx->num, ctx->num); } *************** *** 1958,1964 **** } static void ! tty_cell(struct tty *tty, const struct grid_cell *gc, struct window_pane *wp) { const struct grid_cell *gcp; --- 1926,1933 ---- } static void ! tty_cell(struct tty *tty, const struct grid_cell *gc, ! const struct grid_cell *defaults, int *palette) { const struct grid_cell *gcp; *************** *** 1973,1979 **** return; /* Set the attributes. */ ! tty_attributes(tty, gc, wp); /* Get the cell and if ASCII write with putc to do ACS translation. */ gcp = tty_check_codeset(tty, gc); --- 1942,1948 ---- return; /* Set the attributes. */ ! tty_attributes(tty, gc, defaults, palette); /* Get the cell and if ASCII write with putc to do ACS translation. */ gcp = tty_check_codeset(tty, gc); *************** *** 1999,2019 **** 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; } static void tty_invalidate(struct tty *tty) { 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->cx = tty->cy = UINT_MAX; - tty->rupper = tty->rleft = UINT_MAX; tty->rlower = tty->rright = UINT_MAX; --- 1968,1983 ---- *************** *** 2089,2095 **** tty_margin_pane(struct tty *tty, const struct tty_ctx *ctx) { tty_margin(tty, ctx->xoff - ctx->wox, ! ctx->xoff + ctx->wp->sx - 1 - ctx->wox); } /* Set margin at absolute position. */ --- 2053,2059 ---- tty_margin_pane(struct tty *tty, const struct tty_ctx *ctx) { tty_margin(tty, ctx->xoff - ctx->wox, ! ctx->xoff + ctx->sx - 1 - ctx->wox); } /* Set margin at absolute position. */ *************** *** 2282,2309 **** void tty_attributes(struct tty *tty, const struct grid_cell *gc, ! struct window_pane *wp) { struct grid_cell *tc = &tty->cell, gc2; int changed; - /* Ignore cell if it is the same as the last one. */ - if (wp != NULL && - (int)wp->id == tty->last_wp && - ~(wp->flags & PANE_STYLECHANGED) && - gc->attr == tty->last_cell.attr && - gc->fg == tty->last_cell.fg && - gc->bg == tty->last_cell.bg && - gc->us == tty->last_cell.us) - 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); /* * If no setab, try to use the reverse attribute as a best-effort for a * non-default background. This is a bit of a hack but it doesn't do --- 2246,2270 ---- void tty_attributes(struct tty *tty, const struct grid_cell *gc, ! const struct grid_cell *defaults, int *palette) { struct grid_cell *tc = &tty->cell, gc2; int changed; /* Copy cell and update default colours. */ memcpy(&gc2, gc, sizeof gc2); ! if (gc2.fg == 8) ! gc2.fg = defaults->fg; ! if (gc2.bg == 8) ! gc2.bg = defaults->bg; + /* Ignore cell if it is the same as the last one. */ + if (gc2.attr == tty->last_cell.attr && + gc2.fg == tty->last_cell.fg && + gc2.bg == tty->last_cell.bg && + gc2.us == tty->last_cell.us) + return; + /* * If no setab, try to use the reverse attribute as a best-effort for a * non-default background. This is a bit of a hack but it doesn't do *************** *** 2320,2328 **** } /* Fix up the colours if necessary. */ ! tty_check_fg(tty, wp, &gc2); ! tty_check_bg(tty, wp, &gc2); ! tty_check_us(tty, wp, &gc2); /* * If any bits are being cleared or the underline colour is now default, --- 2281,2289 ---- } /* Fix up the colours if necessary. */ ! tty_check_fg(tty, palette, &gc2); ! tty_check_bg(tty, palette, &gc2); ! tty_check_us(tty, palette, &gc2); /* * If any bits are being cleared or the underline colour is now default, *************** *** 2377,2382 **** --- 2338,2345 ---- tty_putcode(tty, TTYC_SMOL); if ((changed & GRID_ATTR_CHARSET) && tty_acs_needed(tty)) tty_putcode(tty, TTYC_SMACS); + + memcpy(&tty->last_cell, &gc2, sizeof tty->last_cell); } static void *************** *** 2441,2447 **** } static void ! tty_check_fg(struct tty *tty, struct window_pane *wp, struct grid_cell *gc) { u_char r, g, b; u_int colours; --- 2404,2410 ---- } static void ! tty_check_fg(struct tty *tty, int *palette, struct grid_cell *gc) { u_char r, g, b; u_int colours; *************** *** 2456,2462 **** c = gc->fg; if (c < 8 && gc->attr & GRID_ATTR_BRIGHT) c += 90; ! if ((c = window_pane_get_palette(wp, c)) != -1) gc->fg = c; } --- 2419,2425 ---- c = gc->fg; if (c < 8 && gc->attr & GRID_ATTR_BRIGHT) c += 90; ! if ((c = tty_get_palette(palette, c)) != -1) gc->fg = c; } *************** *** 2497,2503 **** } static void ! tty_check_bg(struct tty *tty, struct window_pane *wp, struct grid_cell *gc) { u_char r, g, b; u_int colours; --- 2460,2466 ---- } static void ! tty_check_bg(struct tty *tty, int *palette, struct grid_cell *gc) { u_char r, g, b; u_int colours; *************** *** 2505,2511 **** /* Perform substitution if this pane has a palette. */ if (~gc->flags & GRID_FLAG_NOPALETTE) { ! if ((c = window_pane_get_palette(wp, gc->bg)) != -1) gc->bg = c; } --- 2468,2474 ---- /* Perform substitution if this pane has a palette. */ if (~gc->flags & GRID_FLAG_NOPALETTE) { ! if ((c = tty_get_palette(palette, gc->bg)) != -1) gc->bg = c; } *************** *** 2548,2561 **** } static void ! tty_check_us(__unused struct tty *tty, struct window_pane *wp, ! struct grid_cell *gc) { int c; /* Perform substitution if this pane has a palette. */ if (~gc->flags & GRID_FLAG_NOPALETTE) { ! if ((c = window_pane_get_palette(wp, gc->us)) != -1) gc->us = c; } --- 2511,2523 ---- } static void ! tty_check_us(__unused struct tty *tty, int *palette, struct grid_cell *gc) { int c; /* Perform substitution if this pane has a palette. */ if (~gc->flags & GRID_FLAG_NOPALETTE) { ! if ((c = tty_get_palette(palette, gc->us)) != -1) gc->us = c; } *************** *** 2686,2697 **** gc->bg = wp->bg; } ! static void tty_default_colours(struct grid_cell *gc, struct window_pane *wp) { struct options *oo = wp->options; - int c; if (wp->flags & PANE_STYLECHANGED) { wp->flags &= ~PANE_STYLECHANGED; --- 2648,2660 ---- gc->bg = wp->bg; } ! void tty_default_colours(struct grid_cell *gc, struct window_pane *wp) { struct options *oo = wp->options; + memcpy(gc, &grid_default_cell, sizeof *gc); + if (wp->flags & PANE_STYLECHANGED) { wp->flags &= ~PANE_STYLECHANGED; *************** *** 2707,2718 **** gc->fg = wp->cached_active_gc.fg; else gc->fg = wp->cached_gc.fg; - - if (gc->fg != 8) { - c = window_pane_get_palette(wp, gc->fg); - if (c != -1) - gc->fg = c; - } } if (gc->bg == 8) { --- 2670,2675 ---- *************** *** 2720,2740 **** gc->bg = wp->cached_active_gc.bg; else gc->bg = wp->cached_gc.bg; - - if (gc->bg != 8) { - c = window_pane_get_palette(wp, gc->bg); - if (c != -1) - gc->bg = c; - } } } static void ! tty_default_attributes(struct tty *tty, struct window_pane *wp, u_int bg) { ! static struct grid_cell gc; memcpy(&gc, &grid_default_cell, sizeof gc); gc.bg = bg; ! tty_attributes(tty, &gc, wp); } --- 2677,2692 ---- gc->bg = wp->cached_active_gc.bg; else gc->bg = wp->cached_gc.bg; } } static void ! tty_default_attributes(struct tty *tty, const struct grid_cell *defaults, ! int *palette, u_int bg) { ! struct grid_cell gc; memcpy(&gc, &grid_default_cell, sizeof gc); gc.bg = bg; ! tty_attributes(tty, &gc, defaults, palette); }