mirror of
https://github.com/tmux/tmux.git
synced 2025-09-02 05:21:10 +00:00
Support setting the default window and pane background colours (window
and active pane via window-style and window-active-style options, an individual pane by a new select-pane -P flag). From J Raynor.
This commit is contained in:
170
tty.c
170
tty.c
@ -43,11 +43,14 @@ void tty_colours_fg(struct tty *, const struct grid_cell *);
|
||||
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 *);
|
||||
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))
|
||||
@ -581,6 +584,23 @@ tty_large_region(unused struct tty *tty, const struct tty_ctx *ctx)
|
||||
return (ctx->orlower - ctx->orupper >= screen_size_y(wp->screen) / 2);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
@ -604,15 +624,23 @@ tty_redraw_region(struct tty *tty, const struct tty_ctx *ctx)
|
||||
|
||||
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);
|
||||
tty_draw_pane(tty, wp, i, ctx->xoff, ctx->yoff);
|
||||
} else {
|
||||
for (i = ctx->orupper; i <= ctx->orlower; i++)
|
||||
tty_draw_line(tty, s, i, ctx->xoff, ctx->yoff);
|
||||
tty_draw_pane(tty, wp, i, ctx->xoff, ctx->yoff);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy)
|
||||
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;
|
||||
@ -650,20 +678,20 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy)
|
||||
~(GRID_FLAG_FG256|GRID_FLAG_BG256);
|
||||
tmpgc.flags |= s->sel.cell.flags &
|
||||
(GRID_FLAG_FG256|GRID_FLAG_BG256);
|
||||
tty_cell(tty, &tmpgc);
|
||||
tty_cell(tty, &tmpgc, wp);
|
||||
} else
|
||||
tty_cell(tty, gc);
|
||||
tty_cell(tty, gc, wp);
|
||||
}
|
||||
|
||||
if (sx >= tty->sx) {
|
||||
tty_update_mode(tty, tty->mode, s);
|
||||
return;
|
||||
}
|
||||
tty_reset(tty);
|
||||
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_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,19 +741,19 @@ tty_cmd_insertcharacter(struct tty *tty, const struct tty_ctx *ctx)
|
||||
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);
|
||||
tty_draw_pane(tty, wp, ctx->ocy, ctx->xoff, ctx->yoff);
|
||||
return;
|
||||
}
|
||||
|
||||
tty_reset(tty);
|
||||
tty_attributes(tty, &grid_default_cell, wp);
|
||||
|
||||
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
|
||||
|
||||
if (tty_term_has(tty->term, TTYC_ICH) ||
|
||||
tty_term_has(tty->term, TTYC_ICH1))
|
||||
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_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff);
|
||||
tty_draw_pane(tty, wp, ctx->ocy, ctx->xoff, ctx->yoff);
|
||||
}
|
||||
|
||||
void
|
||||
@ -733,14 +761,14 @@ tty_cmd_deletecharacter(struct tty *tty, const struct tty_ctx *ctx)
|
||||
{
|
||||
struct window_pane *wp = ctx->wp;
|
||||
|
||||
if (!tty_pane_full_width(tty, ctx) ||
|
||||
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_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff);
|
||||
tty_draw_pane(tty, wp, ctx->ocy, ctx->xoff, ctx->yoff);
|
||||
return;
|
||||
}
|
||||
|
||||
tty_reset(tty);
|
||||
tty_attributes(tty, &grid_default_cell, wp);
|
||||
|
||||
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
|
||||
|
||||
@ -754,11 +782,11 @@ tty_cmd_clearcharacter(struct tty *tty, const struct tty_ctx *ctx)
|
||||
{
|
||||
u_int i;
|
||||
|
||||
tty_reset(tty);
|
||||
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))
|
||||
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,14 +797,14 @@ tty_cmd_clearcharacter(struct tty *tty, const struct tty_ctx *ctx)
|
||||
void
|
||||
tty_cmd_insertline(struct tty *tty, const struct tty_ctx *ctx)
|
||||
{
|
||||
if (!tty_pane_full_width(tty, 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_reset(tty);
|
||||
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,14 +815,14 @@ tty_cmd_insertline(struct tty *tty, const struct tty_ctx *ctx)
|
||||
void
|
||||
tty_cmd_deleteline(struct tty *tty, const struct tty_ctx *ctx)
|
||||
{
|
||||
if (!tty_pane_full_width(tty, 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_reset(tty);
|
||||
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,11 +836,12 @@ tty_cmd_clearline(struct tty *tty, const struct tty_ctx *ctx)
|
||||
struct window_pane *wp = ctx->wp;
|
||||
struct screen *s = wp->screen;
|
||||
|
||||
tty_reset(tty);
|
||||
tty_attributes(tty, &grid_default_cell, wp);
|
||||
|
||||
tty_cursor_pane(tty, ctx, 0, ctx->ocy);
|
||||
|
||||
if (tty_pane_full_width(tty, ctx) && tty_term_has(tty->term, TTYC_EL))
|
||||
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,11 +853,12 @@ tty_cmd_clearendofline(struct tty *tty, const struct tty_ctx *ctx)
|
||||
struct window_pane *wp = ctx->wp;
|
||||
struct screen *s = wp->screen;
|
||||
|
||||
tty_reset(tty);
|
||||
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))
|
||||
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,9 +867,10 @@ tty_cmd_clearendofline(struct tty *tty, const struct tty_ctx *ctx)
|
||||
void
|
||||
tty_cmd_clearstartofline(struct tty *tty, const struct tty_ctx *ctx)
|
||||
{
|
||||
tty_reset(tty);
|
||||
tty_attributes(tty, &grid_default_cell, ctx->wp);
|
||||
|
||||
if (ctx->xoff == 0 && tty_term_has(tty->term, TTYC_EL1)) {
|
||||
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,14 +885,14 @@ tty_cmd_reverseindex(struct tty *tty, const struct tty_ctx *ctx)
|
||||
if (ctx->ocy != ctx->orupper)
|
||||
return;
|
||||
|
||||
if (!tty_pane_full_width(tty, 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_RI)) {
|
||||
tty_redraw_region(tty, ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
tty_reset(tty);
|
||||
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,7 +908,7 @@ tty_cmd_linefeed(struct tty *tty, const struct tty_ctx *ctx)
|
||||
if (ctx->ocy != ctx->orlower)
|
||||
return;
|
||||
|
||||
if (!tty_pane_full_width(tty, ctx) ||
|
||||
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,7 +925,7 @@ tty_cmd_linefeed(struct tty *tty, const struct tty_ctx *ctx)
|
||||
if (ctx->num && !(tty->term->flags & TERM_EARLYWRAP))
|
||||
return;
|
||||
|
||||
tty_reset(tty);
|
||||
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,12 +940,13 @@ tty_cmd_clearendofscreen(struct tty *tty, const struct tty_ctx *ctx)
|
||||
struct screen *s = wp->screen;
|
||||
u_int i, j;
|
||||
|
||||
tty_reset(tty);
|
||||
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)) {
|
||||
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,12 +974,13 @@ tty_cmd_clearstartofscreen(struct tty *tty, const struct tty_ctx *ctx)
|
||||
struct screen *s = wp->screen;
|
||||
u_int i, j;
|
||||
|
||||
tty_reset(tty);
|
||||
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)) {
|
||||
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,12 +1002,13 @@ tty_cmd_clearscreen(struct tty *tty, const struct tty_ctx *ctx)
|
||||
struct screen *s = wp->screen;
|
||||
u_int i, j;
|
||||
|
||||
tty_reset(tty);
|
||||
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)) {
|
||||
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,7 +1031,7 @@ tty_cmd_alignmenttest(struct tty *tty, const struct tty_ctx *ctx)
|
||||
struct screen *s = wp->screen;
|
||||
u_int i, j;
|
||||
|
||||
tty_reset(tty);
|
||||
tty_attributes(tty, &grid_default_cell, wp);
|
||||
|
||||
tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1);
|
||||
|
||||
@ -1038,12 +1072,12 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx)
|
||||
*/
|
||||
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);
|
||||
tty_cell(tty, &ctx->last_cell, wp);
|
||||
}
|
||||
} else
|
||||
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
|
||||
|
||||
tty_cell(tty, ctx->cell);
|
||||
tty_cell(tty, ctx->cell, wp);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1055,7 +1089,7 @@ tty_cmd_utf8character(struct tty *tty, const struct tty_ctx *ctx)
|
||||
* 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);
|
||||
tty_draw_pane(tty, wp, ctx->ocy, ctx->xoff, ctx->yoff);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1088,12 +1122,13 @@ tty_cmd_rawstring(struct tty *tty, const struct tty_ctx *ctx)
|
||||
tty->cx = tty->cy = UINT_MAX;
|
||||
tty->rupper = tty->rlower = UINT_MAX;
|
||||
|
||||
tty_reset(tty);
|
||||
tty_attributes(tty, &grid_default_cell, ctx->wp);
|
||||
tty_cursor(tty, 0, 0);
|
||||
}
|
||||
|
||||
void
|
||||
tty_cell(struct tty *tty, const struct grid_cell *gc)
|
||||
tty_cell(struct tty *tty, const struct grid_cell *gc,
|
||||
const struct window_pane *wp)
|
||||
{
|
||||
struct utf8_data ud;
|
||||
u_int i;
|
||||
@ -1108,7 +1143,7 @@ tty_cell(struct tty *tty, const struct grid_cell *gc)
|
||||
return;
|
||||
|
||||
/* Set the attributes. */
|
||||
tty_attributes(tty, gc);
|
||||
tty_attributes(tty, gc, wp);
|
||||
|
||||
/* Get the cell and if ASCII write with putc to do ACS translation. */
|
||||
grid_cell_get(gc, &ud);
|
||||
@ -1312,12 +1347,14 @@ out:
|
||||
}
|
||||
|
||||
void
|
||||
tty_attributes(struct tty *tty, const struct grid_cell *gc)
|
||||
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
|
||||
@ -1609,6 +1646,47 @@ tty_try_256(struct tty *tty, u_char colour, const char *type)
|
||||
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
|
||||
tty_bell(struct tty *tty)
|
||||
{
|
||||
|
Reference in New Issue
Block a user