=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/tmux/tty.c,v retrieving revision 1.175 retrieving revision 1.176 diff -c -r1.175 -r1.176 *** src/usr.bin/tmux/tty.c 2015/04/15 22:34:46 1.175 --- src/usr.bin/tmux/tty.c 2015/04/19 21:05:27 1.176 *************** *** 1,4 **** ! /* $OpenBSD: tty.c,v 1.175 2015/04/15 22:34:46 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott --- 1,4 ---- ! /* $OpenBSD: tty.c,v 1.176 2015/04/19 21:05:27 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott *************** *** 43,53 **** void tty_colours_bg(struct tty *, const struct grid_cell *); int tty_large_region(struct tty *, const struct tty_ctx *); void tty_redraw_region(struct tty *, const struct tty_ctx *); void tty_emulate_repeat( struct tty *, enum tty_code_code, enum tty_code_code, u_int); void tty_repeat_space(struct tty *, u_int); ! void tty_cell(struct tty *, const struct grid_cell *); #define tty_use_acs(tty) \ (tty_term_has((tty)->term, TTYC_ACSC) && !((tty)->flags & TTY_UTF8)) --- 43,56 ---- void tty_colours_bg(struct tty *, const struct grid_cell *); int tty_large_region(struct tty *, const struct tty_ctx *); + int tty_fake_bce(const struct tty *, const struct window_pane *); void tty_redraw_region(struct tty *, const struct tty_ctx *); void tty_emulate_repeat( struct tty *, enum tty_code_code, enum tty_code_code, u_int); void tty_repeat_space(struct tty *, u_int); ! void tty_cell(struct tty *, const struct grid_cell *, ! const struct window_pane *); ! void tty_default_colours(struct grid_cell *, const struct window_pane *); #define tty_use_acs(tty) \ (tty_term_has((tty)->term, TTYC_ACSC) && !((tty)->flags & TTY_UTF8)) *************** *** 582,587 **** --- 585,607 ---- } /* + * Return if BCE is needed but the terminal doesn't have it - it'll need to be + * emulated. + */ + int + tty_fake_bce(const struct tty *tty, const struct window_pane *wp) + { + struct grid_cell gc; + + memcpy(&gc, &grid_default_cell, sizeof gc); + tty_default_colours(&gc, wp); + + if (gc.bg == 8 && !(gc.flags & GRID_FLAG_BG256)) + return (0); + return (!tty_term_flag(tty->term, TTYC_BCE)); + } + + /* * Redraw scroll region using data from screen (already updated). Used when * CSR not supported, or window is a pane that doesn't take up the full * width of the terminal. *************** *** 604,619 **** if (ctx->ocy < ctx->orupper || ctx->ocy > ctx->orlower) { for (i = ctx->ocy; i < screen_size_y(s); i++) ! tty_draw_line(tty, s, i, ctx->xoff, ctx->yoff); } else { for (i = ctx->orupper; i <= ctx->orlower; i++) ! tty_draw_line(tty, s, i, ctx->xoff, ctx->yoff); } } void ! tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy) { const struct grid_cell *gc; struct grid_line *gl; struct grid_cell tmpgc; --- 624,647 ---- if (ctx->ocy < ctx->orupper || ctx->ocy > ctx->orlower) { for (i = ctx->ocy; i < screen_size_y(s); i++) ! tty_draw_pane(tty, wp, i, ctx->xoff, ctx->yoff); } else { for (i = ctx->orupper; i <= ctx->orlower; i++) ! tty_draw_pane(tty, wp, i, ctx->xoff, ctx->yoff); } } void ! tty_draw_pane(struct tty *tty, const struct window_pane *wp, u_int py, u_int ox, ! u_int oy) { + tty_draw_line(tty, wp, wp->screen, py, ox, oy); + } + + void + tty_draw_line(struct tty *tty, const struct window_pane *wp, + struct screen *s, u_int py, u_int ox, u_int oy) + { const struct grid_cell *gc; struct grid_line *gl; struct grid_cell tmpgc; *************** *** 650,669 **** ~(GRID_FLAG_FG256|GRID_FLAG_BG256); tmpgc.flags |= s->sel.cell.flags & (GRID_FLAG_FG256|GRID_FLAG_BG256); ! tty_cell(tty, &tmpgc); } else ! tty_cell(tty, gc); } if (sx >= tty->sx) { tty_update_mode(tty, tty->mode, s); return; } ! tty_reset(tty); 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_putcode(tty, TTYC_EL); else tty_repeat_space(tty, screen_size_x(s) - sx); --- 678,697 ---- ~(GRID_FLAG_FG256|GRID_FLAG_BG256); tmpgc.flags |= s->sel.cell.flags & (GRID_FLAG_FG256|GRID_FLAG_BG256); ! tty_cell(tty, &tmpgc, wp); } else ! tty_cell(tty, gc, wp); } if (sx >= tty->sx) { tty_update_mode(tty, tty->mode, s); return; } ! tty_attributes(tty, &grid_default_cell, wp); 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)) tty_putcode(tty, TTYC_EL); else tty_repeat_space(tty, screen_size_x(s) - sx); *************** *** 713,731 **** struct window_pane *wp = ctx->wp; if (!tty_pane_full_width(tty, ctx)) { ! tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff); return; } ! tty_reset(tty); tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); ! if (tty_term_has(tty->term, TTYC_ICH) || ! tty_term_has(tty->term, TTYC_ICH1)) tty_emulate_repeat(tty, TTYC_ICH, TTYC_ICH1, ctx->num); else ! tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff); } void --- 741,759 ---- struct window_pane *wp = ctx->wp; if (!tty_pane_full_width(tty, ctx)) { ! tty_draw_pane(tty, wp, ctx->ocy, ctx->xoff, ctx->yoff); return; } ! tty_attributes(tty, &grid_default_cell, wp); tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); ! if (!tty_fake_bce(tty, wp) && (tty_term_has(tty->term, TTYC_ICH) || ! tty_term_has(tty->term, TTYC_ICH1))) tty_emulate_repeat(tty, TTYC_ICH, TTYC_ICH1, ctx->num); else ! tty_draw_pane(tty, wp, ctx->ocy, ctx->xoff, ctx->yoff); } void *************** *** 733,746 **** { struct window_pane *wp = ctx->wp; ! if (!tty_pane_full_width(tty, ctx) || (!tty_term_has(tty->term, TTYC_DCH) && !tty_term_has(tty->term, TTYC_DCH1))) { ! tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff); return; } ! tty_reset(tty); tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); --- 761,774 ---- { struct window_pane *wp = ctx->wp; ! if (!tty_pane_full_width(tty, ctx) || tty_fake_bce(tty, wp) || (!tty_term_has(tty->term, TTYC_DCH) && !tty_term_has(tty->term, TTYC_DCH1))) { ! tty_draw_pane(tty, wp, ctx->ocy, ctx->xoff, ctx->yoff); return; } ! tty_attributes(tty, &grid_default_cell, wp); tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); *************** *** 754,764 **** { u_int i; ! tty_reset(tty); tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); ! if (tty_term_has(tty->term, TTYC_ECH)) tty_putcode1(tty, TTYC_ECH, ctx->num); else { for (i = 0; i < ctx->num; i++) --- 782,792 ---- { u_int i; ! tty_attributes(tty, &grid_default_cell, ctx->wp); tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); ! if (tty_term_has(tty->term, TTYC_ECH) && !tty_fake_bce(tty, ctx->wp)) tty_putcode1(tty, TTYC_ECH, ctx->num); else { for (i = 0; i < ctx->num; i++) *************** *** 769,782 **** void tty_cmd_insertline(struct tty *tty, const struct tty_ctx *ctx) { ! if (!tty_pane_full_width(tty, ctx) || !tty_term_has(tty->term, TTYC_CSR) || !tty_term_has(tty->term, TTYC_IL1)) { tty_redraw_region(tty, ctx); return; } ! tty_reset(tty); tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower); tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); --- 797,810 ---- void tty_cmd_insertline(struct tty *tty, const struct tty_ctx *ctx) { ! if (!tty_pane_full_width(tty, ctx) || tty_fake_bce(tty, ctx->wp) || !tty_term_has(tty->term, TTYC_CSR) || !tty_term_has(tty->term, TTYC_IL1)) { tty_redraw_region(tty, ctx); return; } ! tty_attributes(tty, &grid_default_cell, ctx->wp); tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower); tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); *************** *** 787,800 **** void tty_cmd_deleteline(struct tty *tty, const struct tty_ctx *ctx) { ! if (!tty_pane_full_width(tty, ctx) || !tty_term_has(tty->term, TTYC_CSR) || !tty_term_has(tty->term, TTYC_DL1)) { tty_redraw_region(tty, ctx); return; } ! tty_reset(tty); tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower); tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); --- 815,828 ---- void tty_cmd_deleteline(struct tty *tty, const struct tty_ctx *ctx) { ! if (!tty_pane_full_width(tty, ctx) || tty_fake_bce(tty, ctx->wp) || !tty_term_has(tty->term, TTYC_CSR) || !tty_term_has(tty->term, TTYC_DL1)) { tty_redraw_region(tty, ctx); return; } ! tty_attributes(tty, &grid_default_cell, ctx->wp); tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower); tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); *************** *** 808,818 **** struct window_pane *wp = ctx->wp; struct screen *s = wp->screen; ! tty_reset(tty); tty_cursor_pane(tty, ctx, 0, 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, screen_size_x(s)); --- 836,847 ---- struct window_pane *wp = ctx->wp; struct screen *s = wp->screen; ! tty_attributes(tty, &grid_default_cell, wp); tty_cursor_pane(tty, ctx, 0, ctx->ocy); ! if (tty_pane_full_width(tty, ctx) && !tty_fake_bce(tty, wp) && ! tty_term_has(tty->term, TTYC_EL)) tty_putcode(tty, TTYC_EL); else tty_repeat_space(tty, screen_size_x(s)); *************** *** 824,834 **** struct window_pane *wp = ctx->wp; struct screen *s = wp->screen; ! tty_reset(tty); 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, screen_size_x(s) - ctx->ocx); --- 853,864 ---- struct window_pane *wp = ctx->wp; struct screen *s = wp->screen; ! tty_attributes(tty, &grid_default_cell, wp); 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)) tty_putcode(tty, TTYC_EL); else tty_repeat_space(tty, screen_size_x(s) - ctx->ocx); *************** *** 837,845 **** void tty_cmd_clearstartofline(struct tty *tty, const struct tty_ctx *ctx) { ! tty_reset(tty); ! if (ctx->xoff == 0 && tty_term_has(tty->term, TTYC_EL1)) { tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); tty_putcode(tty, TTYC_EL1); } else { --- 867,876 ---- void tty_cmd_clearstartofline(struct tty *tty, const struct tty_ctx *ctx) { ! tty_attributes(tty, &grid_default_cell, ctx->wp); ! if (ctx->xoff == 0 && tty_term_has(tty->term, TTYC_EL1) && ! !tty_fake_bce(tty, ctx->wp)) { tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); tty_putcode(tty, TTYC_EL1); } else { *************** *** 854,867 **** if (ctx->ocy != ctx->orupper) return; ! if (!tty_pane_full_width(tty, ctx) || !tty_term_has(tty->term, TTYC_CSR) || !tty_term_has(tty->term, TTYC_RI)) { tty_redraw_region(tty, ctx); return; } ! tty_reset(tty); tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower); tty_cursor_pane(tty, ctx, ctx->ocx, ctx->orupper); --- 885,898 ---- if (ctx->ocy != ctx->orupper) return; ! if (!tty_pane_full_width(tty, ctx) || tty_fake_bce(tty, ctx->wp) || !tty_term_has(tty->term, TTYC_CSR) || !tty_term_has(tty->term, TTYC_RI)) { tty_redraw_region(tty, ctx); return; } ! tty_attributes(tty, &grid_default_cell, ctx->wp); tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower); tty_cursor_pane(tty, ctx, ctx->ocx, ctx->orupper); *************** *** 877,883 **** if (ctx->ocy != ctx->orlower) return; ! if (!tty_pane_full_width(tty, ctx) || !tty_term_has(tty->term, TTYC_CSR)) { if (tty_large_region(tty, ctx)) wp->flags |= PANE_REDRAW; --- 908,914 ---- if (ctx->ocy != ctx->orlower) return; ! if (!tty_pane_full_width(tty, ctx) || tty_fake_bce(tty, wp) || !tty_term_has(tty->term, TTYC_CSR)) { if (tty_large_region(tty, ctx)) wp->flags |= PANE_REDRAW; *************** *** 894,900 **** if (ctx->num && !(tty->term->flags & TERM_EARLYWRAP)) return; ! tty_reset(tty); tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower); tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); --- 925,931 ---- if (ctx->num && !(tty->term->flags & TERM_EARLYWRAP)) return; ! tty_attributes(tty, &grid_default_cell, wp); tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower); tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); *************** *** 909,920 **** struct screen *s = wp->screen; u_int i, j; ! tty_reset(tty); tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1); 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); if (ctx->ocy != screen_size_y(s) - 1) { tty_cursor_pane(tty, ctx, 0, ctx->ocy + 1); --- 940,952 ---- struct screen *s = wp->screen; u_int i, j; ! tty_attributes(tty, &grid_default_cell, wp); tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1); 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)) { tty_putcode(tty, TTYC_EL); if (ctx->ocy != screen_size_y(s) - 1) { tty_cursor_pane(tty, ctx, 0, ctx->ocy + 1); *************** *** 942,953 **** struct screen *s = wp->screen; u_int i, j; ! tty_reset(tty); tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1); tty_cursor_pane(tty, ctx, 0, 0); ! if (tty_pane_full_width(tty, ctx) && tty_term_has(tty->term, TTYC_EL)) { for (i = 0; i < ctx->ocy; i++) { tty_putcode(tty, TTYC_EL); tty_emulate_repeat(tty, TTYC_CUD, TTYC_CUD1, 1); --- 974,986 ---- struct screen *s = wp->screen; u_int i, j; ! tty_attributes(tty, &grid_default_cell, wp); tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1); tty_cursor_pane(tty, ctx, 0, 0); ! if (tty_pane_full_width(tty, ctx) && ! tty_term_has(tty->term, TTYC_EL) && !tty_fake_bce(tty, wp)) { for (i = 0; i < ctx->ocy; i++) { tty_putcode(tty, TTYC_EL); tty_emulate_repeat(tty, TTYC_CUD, TTYC_CUD1, 1); *************** *** 969,980 **** struct screen *s = wp->screen; u_int i, j; ! tty_reset(tty); tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1); tty_cursor_pane(tty, ctx, 0, 0); ! if (tty_pane_full_width(tty, ctx) && tty_term_has(tty->term, TTYC_EL)) { for (i = 0; i < screen_size_y(s); i++) { tty_putcode(tty, TTYC_EL); if (i != screen_size_y(s) - 1) { --- 1002,1014 ---- struct screen *s = wp->screen; u_int i, j; ! tty_attributes(tty, &grid_default_cell, wp); tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1); tty_cursor_pane(tty, ctx, 0, 0); ! if (tty_pane_full_width(tty, ctx) && ! tty_term_has(tty->term, TTYC_EL) && !tty_fake_bce(tty, wp)) { for (i = 0; i < screen_size_y(s); i++) { tty_putcode(tty, TTYC_EL); if (i != screen_size_y(s) - 1) { *************** *** 997,1003 **** struct screen *s = wp->screen; u_int i, j; ! tty_reset(tty); tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1); --- 1031,1037 ---- struct screen *s = wp->screen; u_int i, j; ! tty_attributes(tty, &grid_default_cell, wp); tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1); *************** *** 1038,1049 **** */ cx = screen_size_x(s) - grid_cell_width(&ctx->last_cell); tty_cursor_pane(tty, ctx, cx, ctx->ocy); ! tty_cell(tty, &ctx->last_cell); } } else tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); ! tty_cell(tty, ctx->cell); } void --- 1072,1083 ---- */ cx = screen_size_x(s) - grid_cell_width(&ctx->last_cell); tty_cursor_pane(tty, ctx, cx, ctx->ocy); ! tty_cell(tty, &ctx->last_cell, wp); } } else tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); ! tty_cell(tty, ctx->cell, wp); } void *************** *** 1055,1061 **** * Cannot rely on not being a partial character, so just redraw the * whole line. */ ! tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff); } void --- 1089,1095 ---- * 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 *************** *** 1088,1099 **** tty->cx = tty->cy = UINT_MAX; tty->rupper = tty->rlower = UINT_MAX; ! tty_reset(tty); tty_cursor(tty, 0, 0); } void ! tty_cell(struct tty *tty, const struct grid_cell *gc) { struct utf8_data ud; u_int i; --- 1122,1134 ---- tty->cx = tty->cy = UINT_MAX; tty->rupper = tty->rlower = UINT_MAX; ! tty_attributes(tty, &grid_default_cell, ctx->wp); tty_cursor(tty, 0, 0); } void ! tty_cell(struct tty *tty, const struct grid_cell *gc, ! const struct window_pane *wp) { struct utf8_data ud; u_int i; *************** *** 1108,1114 **** return; /* Set the attributes. */ ! tty_attributes(tty, gc); /* Get the cell and if ASCII write with putc to do ACS translation. */ grid_cell_get(gc, &ud); --- 1143,1149 ---- return; /* Set the attributes. */ ! tty_attributes(tty, gc, wp); /* Get the cell and if ASCII write with putc to do ACS translation. */ grid_cell_get(gc, &ud); *************** *** 1312,1323 **** } void ! tty_attributes(struct tty *tty, const struct grid_cell *gc) { struct grid_cell *tc = &tty->cell, gc2; u_char changed; memcpy(&gc2, gc, sizeof gc2); /* * If no setab, try to use the reverse attribute as a best-effort for a --- 1347,1360 ---- } void ! tty_attributes(struct tty *tty, const struct grid_cell *gc, ! const struct window_pane *wp) { struct grid_cell *tc = &tty->cell, gc2; u_char changed; memcpy(&gc2, gc, sizeof gc2); + tty_default_colours(&gc2, wp); /* * If no setab, try to use the reverse attribute as a best-effort for a *************** *** 1607,1612 **** --- 1644,1690 ---- } return (-1); + } + + void + tty_default_colours(struct grid_cell *gc, const struct window_pane *wp) + { + const struct grid_cell *agc, *pgc, *wgc; + + if (wp == NULL) + return; + + pgc = &wp->colgc; + agc = options_get_style(&wp->window->options, "window-active-style"); + wgc = options_get_style(&wp->window->options, "window-style"); + + if (gc->fg == 8 && !(gc->flags & GRID_FLAG_FG256)) { + if (pgc->fg != 8 || (pgc->flags & GRID_FLAG_FG256)) { + gc->fg = pgc->fg; + gc->flags |= (pgc->flags & GRID_FLAG_FG256); + } else if (wp == wp->window->active && + (agc->fg != 8 || (agc->flags & GRID_FLAG_FG256))) { + gc->fg = agc->fg; + gc->flags |= (agc->flags & GRID_FLAG_FG256); + } else { + gc->fg = wgc->fg; + gc->flags |= (wgc->flags & GRID_FLAG_FG256); + } + } + + if (gc->bg == 8 && !(gc->flags & GRID_FLAG_BG256)) { + if (pgc->bg != 8 || (pgc->flags & GRID_FLAG_BG256)) { + gc->bg = pgc->bg; + gc->flags |= (pgc->flags & GRID_FLAG_BG256); + } else if (wp == wp->window->active && + (agc->bg != 8 || (agc->flags & GRID_FLAG_BG256))) { + gc->bg = agc->bg; + gc->flags |= (agc->flags & GRID_FLAG_BG256); + } else { + gc->bg = wgc->bg; + gc->flags |= (wgc->flags & GRID_FLAG_BG256); + } + } } void