mirror of
https://github.com/tmux/tmux.git
synced 2025-09-02 21:56:57 +00:00
Add support for BCE (background colour erase). This makes various escape
sequences (notable EL and ED but also IL, DL, ICH, DCH) create blank cells using the current background colour rather than the default colour. On modern systems BCE doesn't really have many benefits, but most other terminals now support it, some (lazy) applications rely on it, and it is not hard to include now that we have pane background colours anyway. Mostly written by Sean Haugh.
This commit is contained in:
95
tty.c
95
tty.c
@ -55,7 +55,8 @@ static void tty_colours_bg(struct tty *, const struct grid_cell *);
|
||||
static void tty_region_pane(struct tty *, const struct tty_ctx *, 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 window_pane *);
|
||||
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_emulate_repeat(struct tty *, enum tty_code_code,
|
||||
enum tty_code_code, u_int);
|
||||
@ -64,6 +65,8 @@ static void tty_cell(struct tty *, const struct grid_cell *,
|
||||
const struct window_pane *);
|
||||
static void tty_default_colours(struct grid_cell *,
|
||||
const struct window_pane *);
|
||||
static void tty_default_attributes(struct tty *, const struct window_pane *,
|
||||
u_int);
|
||||
|
||||
#define tty_use_acs(tty) \
|
||||
(tty_term_has((tty)->term, TTYC_ACSC) && !((tty)->flags & TTY_UTF8))
|
||||
@ -604,17 +607,20 @@ tty_large_region(__unused struct tty *tty, const struct tty_ctx *ctx)
|
||||
* emulated.
|
||||
*/
|
||||
static int
|
||||
tty_fake_bce(const struct tty *tty, const struct window_pane *wp)
|
||||
tty_fake_bce(const struct tty *tty, const 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 (gc.bg == 8)
|
||||
return (0);
|
||||
return (!tty_term_flag(tty->term, TTYC_BCE));
|
||||
if (bg != 8 || gc.bg != 8)
|
||||
return (1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -695,13 +701,13 @@ tty_draw_line(struct tty *tty, const struct window_pane *wp,
|
||||
}
|
||||
|
||||
if (sx < tty->sx) {
|
||||
tty_attributes(tty, &grid_default_cell, wp);
|
||||
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))
|
||||
!tty_fake_bce(tty, wp, 8))
|
||||
tty_putcode(tty, TTYC_EL);
|
||||
else
|
||||
tty_repeat_space(tty, screen_size_x(s) - sx);
|
||||
@ -759,14 +765,15 @@ 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_fake_bce(tty, wp) ||
|
||||
(!tty_term_has(tty->term, TTYC_DCH) &&
|
||||
!tty_term_has(tty->term, TTYC_DCH1))) {
|
||||
if (!tty_pane_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, wp, ctx->ocy, ctx->xoff, ctx->yoff);
|
||||
return;
|
||||
}
|
||||
|
||||
tty_attributes(tty, &grid_default_cell, wp);
|
||||
tty_default_attributes(tty, wp, ctx->bg);
|
||||
|
||||
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
|
||||
|
||||
@ -778,14 +785,15 @@ tty_cmd_deletecharacter(struct tty *tty, const struct tty_ctx *ctx)
|
||||
{
|
||||
struct window_pane *wp = ctx->wp;
|
||||
|
||||
if (!tty_pane_full_width(tty, ctx) || tty_fake_bce(tty, wp) ||
|
||||
if (!tty_pane_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, wp, ctx->ocy, ctx->xoff, ctx->yoff);
|
||||
return;
|
||||
}
|
||||
|
||||
tty_attributes(tty, &grid_default_cell, wp);
|
||||
tty_default_attributes(tty, wp, ctx->bg);
|
||||
|
||||
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
|
||||
|
||||
@ -801,7 +809,8 @@ tty_cmd_clearcharacter(struct tty *tty, const struct tty_ctx *ctx)
|
||||
|
||||
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
|
||||
|
||||
if (tty_term_has(tty->term, TTYC_ECH) && !tty_fake_bce(tty, ctx->wp))
|
||||
if (tty_term_has(tty->term, TTYC_ECH) &&
|
||||
!tty_fake_bce(tty, ctx->wp, ctx->bg))
|
||||
tty_putcode1(tty, TTYC_ECH, ctx->num);
|
||||
else {
|
||||
for (i = 0; i < ctx->num; i++)
|
||||
@ -812,14 +821,15 @@ 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) || tty_fake_bce(tty, ctx->wp) ||
|
||||
if (!tty_pane_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)) {
|
||||
tty_redraw_region(tty, ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
tty_attributes(tty, &grid_default_cell, ctx->wp);
|
||||
tty_default_attributes(tty, ctx->wp, ctx->bg);
|
||||
|
||||
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
|
||||
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
|
||||
@ -830,14 +840,15 @@ 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) || tty_fake_bce(tty, ctx->wp) ||
|
||||
if (!tty_pane_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)) {
|
||||
tty_redraw_region(tty, ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
tty_attributes(tty, &grid_default_cell, ctx->wp);
|
||||
tty_default_attributes(tty, ctx->wp, ctx->bg);
|
||||
|
||||
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
|
||||
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
|
||||
@ -851,11 +862,12 @@ tty_cmd_clearline(struct tty *tty, const struct tty_ctx *ctx)
|
||||
struct window_pane *wp = ctx->wp;
|
||||
struct screen *s = wp->screen;
|
||||
|
||||
tty_attributes(tty, &grid_default_cell, wp);
|
||||
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) &&
|
||||
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
|
||||
@ -868,12 +880,13 @@ tty_cmd_clearendofline(struct tty *tty, const struct tty_ctx *ctx)
|
||||
struct window_pane *wp = ctx->wp;
|
||||
struct screen *s = wp->screen;
|
||||
|
||||
tty_attributes(tty, &grid_default_cell, wp);
|
||||
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))
|
||||
tty_term_has(tty->term, TTYC_EL) &&
|
||||
!tty_fake_bce(tty, wp, ctx->bg))
|
||||
tty_putcode(tty, TTYC_EL);
|
||||
else
|
||||
tty_repeat_space(tty, screen_size_x(s) - ctx->ocx);
|
||||
@ -882,10 +895,13 @@ tty_cmd_clearendofline(struct tty *tty, const struct tty_ctx *ctx)
|
||||
void
|
||||
tty_cmd_clearstartofline(struct tty *tty, const struct tty_ctx *ctx)
|
||||
{
|
||||
tty_attributes(tty, &grid_default_cell, ctx->wp);
|
||||
struct window_pane *wp = ctx->wp;
|
||||
|
||||
if (ctx->xoff == 0 && tty_term_has(tty->term, TTYC_EL1) &&
|
||||
!tty_fake_bce(tty, ctx->wp)) {
|
||||
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 {
|
||||
@ -900,7 +916,8 @@ tty_cmd_reverseindex(struct tty *tty, const struct tty_ctx *ctx)
|
||||
if (ctx->ocy != ctx->orupper)
|
||||
return;
|
||||
|
||||
if (!tty_pane_full_width(tty, ctx) || tty_fake_bce(tty, ctx->wp) ||
|
||||
if (!tty_pane_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_RI)) {
|
||||
tty_redraw_region(tty, ctx);
|
||||
@ -923,7 +940,8 @@ tty_cmd_linefeed(struct tty *tty, const struct tty_ctx *ctx)
|
||||
if (ctx->ocy != ctx->orlower)
|
||||
return;
|
||||
|
||||
if (!tty_pane_full_width(tty, ctx) || tty_fake_bce(tty, wp) ||
|
||||
if (!tty_pane_full_width(tty, ctx) ||
|
||||
tty_fake_bce(tty, wp, ctx->bg) ||
|
||||
!tty_term_has(tty->term, TTYC_CSR)) {
|
||||
if (tty_large_region(tty, ctx))
|
||||
wp->flags |= PANE_REDRAW;
|
||||
@ -955,13 +973,14 @@ tty_cmd_clearendofscreen(struct tty *tty, const struct tty_ctx *ctx)
|
||||
struct screen *s = wp->screen;
|
||||
u_int i, j;
|
||||
|
||||
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_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_term_has(tty->term, TTYC_EL) &&
|
||||
!tty_fake_bce(tty, wp, ctx->bg)) {
|
||||
tty_putcode(tty, TTYC_EL);
|
||||
if (ctx->ocy != screen_size_y(s) - 1) {
|
||||
tty_cursor_pane(tty, ctx, 0, ctx->ocy + 1);
|
||||
@ -995,7 +1014,8 @@ tty_cmd_clearstartofscreen(struct tty *tty, const struct tty_ctx *ctx)
|
||||
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)) {
|
||||
tty_term_has(tty->term, TTYC_EL) &&
|
||||
!tty_fake_bce(tty, wp, ctx->bg)) {
|
||||
for (i = 0; i < ctx->ocy; i++) {
|
||||
tty_putcode(tty, TTYC_EL);
|
||||
tty_emulate_repeat(tty, TTYC_CUD, TTYC_CUD1, 1);
|
||||
@ -1017,13 +1037,14 @@ tty_cmd_clearscreen(struct tty *tty, const struct tty_ctx *ctx)
|
||||
struct screen *s = wp->screen;
|
||||
u_int i, j;
|
||||
|
||||
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_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)) {
|
||||
tty_term_has(tty->term, TTYC_EL) &&
|
||||
!tty_fake_bce(tty, wp, ctx->bg)) {
|
||||
for (i = 0; i < screen_size_y(s); i++) {
|
||||
tty_putcode(tty, TTYC_EL);
|
||||
if (i != screen_size_y(s) - 1) {
|
||||
@ -1721,3 +1742,13 @@ tty_default_colours(struct grid_cell *gc, const struct window_pane *wp)
|
||||
gc->bg = wgc->bg;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tty_default_attributes(struct tty *tty, const 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);
|
||||
}
|
||||
|
Reference in New Issue
Block a user