mirror of
https://github.com/tmate-io/tmate.git
synced 2024-11-26 01:54:14 +01:00
Support for RGB colour, using the extended cell mechanism to avoid
wasting unnecessary space. The 'Tc' flag must be set in the external TERM entry (using terminal-overrides or a custom terminfo entry), if not tmux will map to the closest of the 256 or 16 colour palettes. Mostly from Suraj N Kurapati, based on a diff originally by someone else.
This commit is contained in:
parent
b5b5221c13
commit
427b820426
11
grid.c
11
grid.c
@ -37,7 +37,7 @@
|
|||||||
|
|
||||||
/* Default grid cell data. */
|
/* Default grid cell data. */
|
||||||
const struct grid_cell grid_default_cell = {
|
const struct grid_cell grid_default_cell = {
|
||||||
0, 0, 8, 8, { { ' ' }, 0, 1, 1 }
|
0, 0, { .fg = 8 }, { .bg = 8 }, { { ' ' }, 0, 1, 1 }
|
||||||
};
|
};
|
||||||
const struct grid_cell_entry grid_default_entry = {
|
const struct grid_cell_entry grid_default_entry = {
|
||||||
0, { .data = { 0, 8, 8, ' ' } }
|
0, { .data = { 0, 8, 8, ' ' } }
|
||||||
@ -284,6 +284,7 @@ grid_set_cell(struct grid *gd, u_int px, u_int py, const struct grid_cell *gc)
|
|||||||
struct grid_line *gl;
|
struct grid_line *gl;
|
||||||
struct grid_cell_entry *gce;
|
struct grid_cell_entry *gce;
|
||||||
struct grid_cell *gcp;
|
struct grid_cell *gcp;
|
||||||
|
int extended;
|
||||||
|
|
||||||
if (grid_check_y(gd, py) != 0)
|
if (grid_check_y(gd, py) != 0)
|
||||||
return;
|
return;
|
||||||
@ -293,8 +294,12 @@ grid_set_cell(struct grid *gd, u_int px, u_int py, const struct grid_cell *gc)
|
|||||||
gl = &gd->linedata[py];
|
gl = &gd->linedata[py];
|
||||||
gce = &gl->celldata[px];
|
gce = &gl->celldata[px];
|
||||||
|
|
||||||
if ((gce->flags & GRID_FLAG_EXTENDED) || gc->data.size != 1 ||
|
extended = (gce->flags & GRID_FLAG_EXTENDED);
|
||||||
gc->data.width != 1) {
|
if (!extended && (gc->data.size != 1 || gc->data.width != 1))
|
||||||
|
extended = 1;
|
||||||
|
if (!extended && (gc->flags & (GRID_FLAG_FGRGB|GRID_FLAG_BGRGB)))
|
||||||
|
extended = 1;
|
||||||
|
if (extended) {
|
||||||
if (~gce->flags & GRID_FLAG_EXTENDED) {
|
if (~gce->flags & GRID_FLAG_EXTENDED) {
|
||||||
gl->extddata = xreallocarray(gl->extddata,
|
gl->extddata = xreallocarray(gl->extddata,
|
||||||
gl->extdsize + 1, sizeof *gl->extddata);
|
gl->extdsize + 1, sizeof *gl->extddata);
|
||||||
|
35
input.c
35
input.c
@ -1629,18 +1629,20 @@ input_csi_dispatch_sgr_256(struct input_ctx *ictx, int fgbg, u_int *i)
|
|||||||
c = input_get(ictx, *i, 0, -1);
|
c = input_get(ictx, *i, 0, -1);
|
||||||
if (c == -1) {
|
if (c == -1) {
|
||||||
if (fgbg == 38) {
|
if (fgbg == 38) {
|
||||||
gc->flags &= ~GRID_FLAG_FG256;
|
gc->flags &= ~(GRID_FLAG_FG256|GRID_FLAG_FGRGB);
|
||||||
gc->fg = 8;
|
gc->fg = 8;
|
||||||
} else if (fgbg == 48) {
|
} else if (fgbg == 48) {
|
||||||
gc->flags &= ~GRID_FLAG_BG256;
|
gc->flags &= ~(GRID_FLAG_BG256|GRID_FLAG_BGRGB);
|
||||||
gc->bg = 8;
|
gc->bg = 8;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (fgbg == 38) {
|
if (fgbg == 38) {
|
||||||
gc->flags |= GRID_FLAG_FG256;
|
gc->flags |= GRID_FLAG_FG256;
|
||||||
|
gc->flags &= ~GRID_FLAG_FGRGB;
|
||||||
gc->fg = c;
|
gc->fg = c;
|
||||||
} else if (fgbg == 48) {
|
} else if (fgbg == 48) {
|
||||||
gc->flags |= GRID_FLAG_BG256;
|
gc->flags |= GRID_FLAG_BG256;
|
||||||
|
gc->flags &= ~GRID_FLAG_BGRGB;
|
||||||
gc->bg = c;
|
gc->bg = c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1651,7 +1653,7 @@ void
|
|||||||
input_csi_dispatch_sgr_rgb(struct input_ctx *ictx, int fgbg, u_int *i)
|
input_csi_dispatch_sgr_rgb(struct input_ctx *ictx, int fgbg, u_int *i)
|
||||||
{
|
{
|
||||||
struct grid_cell *gc = &ictx->cell.cell;
|
struct grid_cell *gc = &ictx->cell.cell;
|
||||||
int c, r, g, b;
|
int r, g, b;
|
||||||
|
|
||||||
(*i)++;
|
(*i)++;
|
||||||
r = input_get(ictx, *i, 0, -1);
|
r = input_get(ictx, *i, 0, -1);
|
||||||
@ -1666,13 +1668,18 @@ input_csi_dispatch_sgr_rgb(struct input_ctx *ictx, int fgbg, u_int *i)
|
|||||||
if (b == -1 || b > 255)
|
if (b == -1 || b > 255)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
c = colour_find_rgb(r, g, b);
|
|
||||||
if (fgbg == 38) {
|
if (fgbg == 38) {
|
||||||
gc->flags |= GRID_FLAG_FG256;
|
gc->flags &= ~GRID_FLAG_FG256;
|
||||||
gc->fg = c;
|
gc->flags |= GRID_FLAG_FGRGB;
|
||||||
|
gc->fg_rgb.r = r;
|
||||||
|
gc->fg_rgb.g = g;
|
||||||
|
gc->fg_rgb.b = b;
|
||||||
} else if (fgbg == 48) {
|
} else if (fgbg == 48) {
|
||||||
gc->flags |= GRID_FLAG_BG256;
|
gc->flags &= ~GRID_FLAG_BG256;
|
||||||
gc->bg = c;
|
gc->flags |= GRID_FLAG_BGRGB;
|
||||||
|
gc->bg_rgb.r = r;
|
||||||
|
gc->bg_rgb.g = g;
|
||||||
|
gc->bg_rgb.b = b;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1754,11 +1761,11 @@ input_csi_dispatch_sgr(struct input_ctx *ictx)
|
|||||||
case 35:
|
case 35:
|
||||||
case 36:
|
case 36:
|
||||||
case 37:
|
case 37:
|
||||||
gc->flags &= ~GRID_FLAG_FG256;
|
gc->flags &= ~(GRID_FLAG_FG256|GRID_FLAG_FGRGB);
|
||||||
gc->fg = n - 30;
|
gc->fg = n - 30;
|
||||||
break;
|
break;
|
||||||
case 39:
|
case 39:
|
||||||
gc->flags &= ~GRID_FLAG_FG256;
|
gc->flags &= ~(GRID_FLAG_FG256|GRID_FLAG_FGRGB);
|
||||||
gc->fg = 8;
|
gc->fg = 8;
|
||||||
break;
|
break;
|
||||||
case 40:
|
case 40:
|
||||||
@ -1769,11 +1776,11 @@ input_csi_dispatch_sgr(struct input_ctx *ictx)
|
|||||||
case 45:
|
case 45:
|
||||||
case 46:
|
case 46:
|
||||||
case 47:
|
case 47:
|
||||||
gc->flags &= ~GRID_FLAG_BG256;
|
gc->flags &= ~(GRID_FLAG_BG256|GRID_FLAG_BGRGB);
|
||||||
gc->bg = n - 40;
|
gc->bg = n - 40;
|
||||||
break;
|
break;
|
||||||
case 49:
|
case 49:
|
||||||
gc->flags &= ~GRID_FLAG_BG256;
|
gc->flags &= ~(GRID_FLAG_BG256|GRID_FLAG_BGRGB);
|
||||||
gc->bg = 8;
|
gc->bg = 8;
|
||||||
break;
|
break;
|
||||||
case 90:
|
case 90:
|
||||||
@ -1784,7 +1791,7 @@ input_csi_dispatch_sgr(struct input_ctx *ictx)
|
|||||||
case 95:
|
case 95:
|
||||||
case 96:
|
case 96:
|
||||||
case 97:
|
case 97:
|
||||||
gc->flags &= ~GRID_FLAG_FG256;
|
gc->flags &= ~(GRID_FLAG_FG256|GRID_FLAG_FGRGB);
|
||||||
gc->fg = n;
|
gc->fg = n;
|
||||||
break;
|
break;
|
||||||
case 100:
|
case 100:
|
||||||
@ -1795,7 +1802,7 @@ input_csi_dispatch_sgr(struct input_ctx *ictx)
|
|||||||
case 105:
|
case 105:
|
||||||
case 106:
|
case 106:
|
||||||
case 107:
|
case 107:
|
||||||
gc->flags &= ~GRID_FLAG_BG256;
|
gc->flags &= ~(GRID_FLAG_BG256|GRID_FLAG_BGRGB);
|
||||||
gc->bg = n - 10;
|
gc->bg = n - 10;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
12
tmux.1
12
tmux.1
@ -2921,7 +2921,7 @@ and poor for interactive programs such as shells.
|
|||||||
.Op Ic on | off
|
.Op Ic on | off
|
||||||
.Xc
|
.Xc
|
||||||
Allow programs to change the window name using a terminal escape
|
Allow programs to change the window name using a terminal escape
|
||||||
sequence (\\033k...\\033\\\\).
|
sequence (\eek...\ee\e\e).
|
||||||
The default is on.
|
The default is on.
|
||||||
.Pp
|
.Pp
|
||||||
.It Xo Ic alternate-screen
|
.It Xo Ic alternate-screen
|
||||||
@ -4024,7 +4024,7 @@ This command only works from outside
|
|||||||
.El
|
.El
|
||||||
.Sh TERMINFO EXTENSIONS
|
.Sh TERMINFO EXTENSIONS
|
||||||
.Nm
|
.Nm
|
||||||
understands some extensions to
|
understands some unofficial extensions to
|
||||||
.Xr terminfo 5 :
|
.Xr terminfo 5 :
|
||||||
.Bl -tag -width Ds
|
.Bl -tag -width Ds
|
||||||
.It Em Cs , Cr
|
.It Em Cs , Cr
|
||||||
@ -4048,10 +4048,12 @@ $ printf '\e033[4 q'
|
|||||||
If
|
If
|
||||||
.Em Se
|
.Em Se
|
||||||
is not set, \&Ss with argument 0 will be used to reset the cursor style instead.
|
is not set, \&Ss with argument 0 will be used to reset the cursor style instead.
|
||||||
|
.It Em \&Tc
|
||||||
|
Indicate that the terminal supports the
|
||||||
|
.Ql direct colour
|
||||||
|
RGB escape sequence (for example, \ee[38;2;255;255;255m).
|
||||||
.It Em \&Ms
|
.It Em \&Ms
|
||||||
This sequence can be used by
|
Store the current buffer in the host terminal's selection (clipboard).
|
||||||
.Nm
|
|
||||||
to store the current buffer in the host terminal's selection (clipboard).
|
|
||||||
See the
|
See the
|
||||||
.Em set-clipboard
|
.Em set-clipboard
|
||||||
option above and the
|
option above and the
|
||||||
|
20
tmux.h
20
tmux.h
@ -385,6 +385,7 @@ enum tty_code_code {
|
|||||||
TTYC_SMSO, /* enter_standout_mode, so */
|
TTYC_SMSO, /* enter_standout_mode, so */
|
||||||
TTYC_SMUL, /* enter_underline_mode, us */
|
TTYC_SMUL, /* enter_underline_mode, us */
|
||||||
TTYC_SS, /* set cursor style, Ss */
|
TTYC_SS, /* set cursor style, Ss */
|
||||||
|
TTYC_TC, /* 24-bit "true" colour, Tc */
|
||||||
TTYC_TSL, /* to_status_line, tsl */
|
TTYC_TSL, /* to_status_line, tsl */
|
||||||
TTYC_VPA, /* row_address, cv */
|
TTYC_VPA, /* row_address, cv */
|
||||||
TTYC_XENL, /* eat_newline_glitch, xn */
|
TTYC_XENL, /* eat_newline_glitch, xn */
|
||||||
@ -641,16 +642,31 @@ enum utf8_state {
|
|||||||
#define GRID_FLAG_BG256 0x2
|
#define GRID_FLAG_BG256 0x2
|
||||||
#define GRID_FLAG_PADDING 0x4
|
#define GRID_FLAG_PADDING 0x4
|
||||||
#define GRID_FLAG_EXTENDED 0x8
|
#define GRID_FLAG_EXTENDED 0x8
|
||||||
|
#define GRID_FLAG_FGRGB 0x10
|
||||||
|
#define GRID_FLAG_BGRGB 0x20
|
||||||
|
|
||||||
/* Grid line flags. */
|
/* Grid line flags. */
|
||||||
#define GRID_LINE_WRAPPED 0x1
|
#define GRID_LINE_WRAPPED 0x1
|
||||||
|
|
||||||
|
/* Grid cell RGB colours. */
|
||||||
|
struct grid_cell_rgb {
|
||||||
|
u_char r;
|
||||||
|
u_char g;
|
||||||
|
u_char b;
|
||||||
|
};
|
||||||
|
|
||||||
/* Grid cell data. */
|
/* Grid cell data. */
|
||||||
struct grid_cell {
|
struct grid_cell {
|
||||||
u_char flags;
|
u_char flags;
|
||||||
u_char attr;
|
u_char attr;
|
||||||
u_char fg;
|
union {
|
||||||
u_char bg;
|
u_char fg;
|
||||||
|
struct grid_cell_rgb fg_rgb;
|
||||||
|
};
|
||||||
|
union {
|
||||||
|
u_char bg;
|
||||||
|
struct grid_cell_rgb bg_rgb;
|
||||||
|
};
|
||||||
struct utf8_data data;
|
struct utf8_data data;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -251,6 +251,7 @@ const struct tty_term_code_entry tty_term_codes[] = {
|
|||||||
[TTYC_SMSO] = { TTYCODE_STRING, "smso" },
|
[TTYC_SMSO] = { TTYCODE_STRING, "smso" },
|
||||||
[TTYC_SMUL] = { TTYCODE_STRING, "smul" },
|
[TTYC_SMUL] = { TTYCODE_STRING, "smul" },
|
||||||
[TTYC_SS] = { TTYCODE_STRING, "Ss" },
|
[TTYC_SS] = { TTYCODE_STRING, "Ss" },
|
||||||
|
[TTYC_TC] = { TTYCODE_FLAG, "Tc" },
|
||||||
[TTYC_TSL] = { TTYCODE_STRING, "tsl" },
|
[TTYC_TSL] = { TTYCODE_STRING, "tsl" },
|
||||||
[TTYC_VPA] = { TTYCODE_STRING, "vpa" },
|
[TTYC_VPA] = { TTYCODE_STRING, "vpa" },
|
||||||
[TTYC_XENL] = { TTYCODE_FLAG, "xenl" },
|
[TTYC_XENL] = { TTYCODE_FLAG, "xenl" },
|
||||||
|
185
tty.c
185
tty.c
@ -36,8 +36,15 @@ static int tty_log_fd = -1;
|
|||||||
void tty_read_callback(struct bufferevent *, void *);
|
void tty_read_callback(struct bufferevent *, void *);
|
||||||
void tty_error_callback(struct bufferevent *, short, void *);
|
void tty_error_callback(struct bufferevent *, short, void *);
|
||||||
|
|
||||||
|
static int tty_same_fg(const struct grid_cell *, const struct grid_cell *);
|
||||||
|
static int tty_same_bg(const struct grid_cell *, const struct grid_cell *);
|
||||||
|
static int tty_same_colours(const struct grid_cell *, const struct grid_cell *);
|
||||||
|
static int tty_is_fg(const struct grid_cell *, int);
|
||||||
|
static int tty_is_bg(const struct grid_cell *, int);
|
||||||
|
|
||||||
void tty_set_italics(struct tty *);
|
void tty_set_italics(struct tty *);
|
||||||
int tty_try_256(struct tty *, u_char, const char *);
|
int tty_try_256(struct tty *, u_char, const char *);
|
||||||
|
int tty_try_rgb(struct tty *, const struct grid_cell_rgb *, const char *);
|
||||||
|
|
||||||
void tty_colours(struct tty *, const struct grid_cell *);
|
void tty_colours(struct tty *, const struct grid_cell *);
|
||||||
void tty_check_fg(struct tty *, struct grid_cell *);
|
void tty_check_fg(struct tty *, struct grid_cell *);
|
||||||
@ -61,6 +68,74 @@ void tty_default_colours(struct grid_cell *, const struct window_pane *);
|
|||||||
#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)
|
((ctx)->xoff == 0 && screen_size_x((ctx)->wp->screen) >= (tty)->sx)
|
||||||
|
|
||||||
|
static int
|
||||||
|
tty_same_fg(const struct grid_cell *gc1, const struct grid_cell *gc2)
|
||||||
|
{
|
||||||
|
int flags1, flags2;
|
||||||
|
|
||||||
|
flags1 = (gc1->flags & (GRID_FLAG_FG256|GRID_FLAG_FGRGB));
|
||||||
|
flags2 = (gc2->flags & (GRID_FLAG_FG256|GRID_FLAG_FGRGB));
|
||||||
|
|
||||||
|
if (flags1 != flags2)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
if (flags1 & GRID_FLAG_FGRGB) {
|
||||||
|
if (gc1->fg_rgb.r != gc2->fg_rgb.r)
|
||||||
|
return (0);
|
||||||
|
if (gc1->fg_rgb.g != gc2->fg_rgb.g)
|
||||||
|
return (0);
|
||||||
|
if (gc1->fg_rgb.b != gc2->fg_rgb.b)
|
||||||
|
return (0);
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
return (gc1->fg == gc2->fg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
tty_same_bg(const struct grid_cell *gc1, const struct grid_cell *gc2)
|
||||||
|
{
|
||||||
|
int flags1, flags2;
|
||||||
|
|
||||||
|
flags1 = (gc1->flags & (GRID_FLAG_BG256|GRID_FLAG_BGRGB));
|
||||||
|
flags2 = (gc2->flags & (GRID_FLAG_BG256|GRID_FLAG_BGRGB));
|
||||||
|
|
||||||
|
if (flags1 != flags2)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
if (flags1 & GRID_FLAG_BGRGB) {
|
||||||
|
if (gc1->bg_rgb.r != gc2->bg_rgb.r)
|
||||||
|
return (0);
|
||||||
|
if (gc1->bg_rgb.g != gc2->bg_rgb.g)
|
||||||
|
return (0);
|
||||||
|
if (gc1->bg_rgb.b != gc2->bg_rgb.b)
|
||||||
|
return (0);
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
return (gc1->bg == gc2->bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
tty_same_colours(const struct grid_cell *gc1, const struct grid_cell *gc2)
|
||||||
|
{
|
||||||
|
return (tty_same_fg(gc1, gc2) && tty_same_bg(gc1, gc2));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
tty_is_fg(const struct grid_cell *gc, int c)
|
||||||
|
{
|
||||||
|
if (gc->flags & (GRID_FLAG_FG256|GRID_FLAG_FGRGB))
|
||||||
|
return (0);
|
||||||
|
return (gc->fg == c);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
tty_is_bg(const struct grid_cell *gc, int c)
|
||||||
|
{
|
||||||
|
if (gc->flags & (GRID_FLAG_BG256|GRID_FLAG_BGRGB))
|
||||||
|
return (0);
|
||||||
|
return (gc->bg == c);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
tty_create_log(void)
|
tty_create_log(void)
|
||||||
{
|
{
|
||||||
@ -1423,12 +1498,10 @@ void
|
|||||||
tty_colours(struct tty *tty, const struct grid_cell *gc)
|
tty_colours(struct tty *tty, const struct grid_cell *gc)
|
||||||
{
|
{
|
||||||
struct grid_cell *tc = &tty->cell;
|
struct grid_cell *tc = &tty->cell;
|
||||||
u_char fg = gc->fg, bg = gc->bg, flags = gc->flags;
|
|
||||||
int have_ax, fg_default, bg_default;
|
int have_ax, fg_default, bg_default;
|
||||||
|
|
||||||
/* No changes? Nothing is necessary. */
|
/* No changes? Nothing is necessary. */
|
||||||
if (fg == tc->fg && bg == tc->bg &&
|
if (tty_same_colours(gc, tc))
|
||||||
((flags ^ tc->flags) & (GRID_FLAG_FG256|GRID_FLAG_BG256)) == 0)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1437,8 +1510,8 @@ tty_colours(struct tty *tty, const struct grid_cell *gc)
|
|||||||
* case if only one is default need to fall onward to set the other
|
* case if only one is default need to fall onward to set the other
|
||||||
* colour.
|
* colour.
|
||||||
*/
|
*/
|
||||||
fg_default = (fg == 8 && !(flags & GRID_FLAG_FG256));
|
fg_default = tty_is_fg(gc, 8);
|
||||||
bg_default = (bg == 8 && !(flags & GRID_FLAG_BG256));
|
bg_default = tty_is_bg(gc, 8);
|
||||||
if (fg_default || bg_default) {
|
if (fg_default || bg_default) {
|
||||||
/*
|
/*
|
||||||
* If don't have AX but do have op, send sgr0 (op can't
|
* If don't have AX but do have op, send sgr0 (op can't
|
||||||
@ -1451,48 +1524,52 @@ tty_colours(struct tty *tty, const struct grid_cell *gc)
|
|||||||
if (!have_ax && tty_term_has(tty->term, TTYC_OP))
|
if (!have_ax && tty_term_has(tty->term, TTYC_OP))
|
||||||
tty_reset(tty);
|
tty_reset(tty);
|
||||||
else {
|
else {
|
||||||
if (fg_default &&
|
if (fg_default && !tty_is_fg(tc, 8)) {
|
||||||
(tc->fg != 8 || tc->flags & GRID_FLAG_FG256)) {
|
|
||||||
if (have_ax)
|
if (have_ax)
|
||||||
tty_puts(tty, "\033[39m");
|
tty_puts(tty, "\033[39m");
|
||||||
else if (tc->fg != 7 ||
|
else if (!tty_is_fg(tc, 7))
|
||||||
tc->flags & GRID_FLAG_FG256)
|
|
||||||
tty_putcode1(tty, TTYC_SETAF, 7);
|
tty_putcode1(tty, TTYC_SETAF, 7);
|
||||||
tc->fg = 8;
|
tc->fg = 8;
|
||||||
tc->flags &= ~GRID_FLAG_FG256;
|
tc->flags &= ~(GRID_FLAG_FG256|GRID_FLAG_FGRGB);
|
||||||
}
|
}
|
||||||
if (bg_default &&
|
if (bg_default && !tty_is_bg(tc, 8)) {
|
||||||
(tc->bg != 8 || tc->flags & GRID_FLAG_BG256)) {
|
|
||||||
if (have_ax)
|
if (have_ax)
|
||||||
tty_puts(tty, "\033[49m");
|
tty_puts(tty, "\033[49m");
|
||||||
else if (tc->bg != 0 ||
|
else if (!tty_is_bg(tc, 0))
|
||||||
tc->flags & GRID_FLAG_BG256)
|
|
||||||
tty_putcode1(tty, TTYC_SETAB, 0);
|
tty_putcode1(tty, TTYC_SETAB, 0);
|
||||||
tc->bg = 8;
|
tc->bg = 8;
|
||||||
tc->flags &= ~GRID_FLAG_BG256;
|
tc->flags &= ~(GRID_FLAG_BG256|GRID_FLAG_BGRGB);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the foreground colour. */
|
/* Set the foreground colour. */
|
||||||
if (!fg_default && (fg != tc->fg ||
|
if (!fg_default && !tty_same_fg(gc, tc))
|
||||||
((flags & GRID_FLAG_FG256) != (tc->flags & GRID_FLAG_FG256))))
|
|
||||||
tty_colours_fg(tty, gc);
|
tty_colours_fg(tty, gc);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set the background colour. This must come after the foreground as
|
* Set the background colour. This must come after the foreground as
|
||||||
* tty_colour_fg() can call tty_reset().
|
* tty_colour_fg() can call tty_reset().
|
||||||
*/
|
*/
|
||||||
if (!bg_default && (bg != tc->bg ||
|
if (!bg_default && !tty_same_bg(gc, tc))
|
||||||
((flags & GRID_FLAG_BG256) != (tc->flags & GRID_FLAG_BG256))))
|
|
||||||
tty_colours_bg(tty, gc);
|
tty_colours_bg(tty, gc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
tty_check_fg(struct tty *tty, struct grid_cell *gc)
|
tty_check_fg(struct tty *tty, struct grid_cell *gc)
|
||||||
{
|
{
|
||||||
u_int colours;
|
struct grid_cell_rgb *rgb = &gc->fg_rgb;
|
||||||
|
u_int colours;
|
||||||
|
|
||||||
|
/* Is this a 24-bit colour? */
|
||||||
|
if (gc->flags & GRID_FLAG_FGRGB) {
|
||||||
|
/* Not a 24-bit terminal? Translate to 256-colour palette. */
|
||||||
|
if (!tty_term_flag(tty->term, TTYC_TC)) {
|
||||||
|
gc->flags &= ~GRID_FLAG_FGRGB;
|
||||||
|
gc->flags |= GRID_FLAG_FG256;
|
||||||
|
gc->fg = colour_find_rgb(rgb->r, rgb->g, rgb->b);
|
||||||
|
}
|
||||||
|
}
|
||||||
colours = tty_term_number(tty->term, TTYC_COLORS);
|
colours = tty_term_number(tty->term, TTYC_COLORS);
|
||||||
|
|
||||||
/* Is this a 256-colour colour? */
|
/* Is this a 256-colour colour? */
|
||||||
@ -1524,8 +1601,18 @@ tty_check_fg(struct tty *tty, struct grid_cell *gc)
|
|||||||
void
|
void
|
||||||
tty_check_bg(struct tty *tty, struct grid_cell *gc)
|
tty_check_bg(struct tty *tty, struct grid_cell *gc)
|
||||||
{
|
{
|
||||||
u_int colours;
|
struct grid_cell_rgb *rgb = &gc->bg_rgb;
|
||||||
|
u_int colours;
|
||||||
|
|
||||||
|
/* Is this a 24-bit colour? */
|
||||||
|
if (gc->flags & GRID_FLAG_BGRGB) {
|
||||||
|
/* Not a 24-bit terminal? Translate to 256-colour palette. */
|
||||||
|
if (!tty_term_flag(tty->term, TTYC_TC)) {
|
||||||
|
gc->flags &= ~GRID_FLAG_BGRGB;
|
||||||
|
gc->flags |= GRID_FLAG_BG256;
|
||||||
|
gc->bg = colour_find_rgb(rgb->r, rgb->g, rgb->b);
|
||||||
|
}
|
||||||
|
}
|
||||||
colours = tty_term_number(tty->term, TTYC_COLORS);
|
colours = tty_term_number(tty->term, TTYC_COLORS);
|
||||||
|
|
||||||
/* Is this a 256-colour colour? */
|
/* Is this a 256-colour colour? */
|
||||||
@ -1560,12 +1647,21 @@ tty_colours_fg(struct tty *tty, const struct grid_cell *gc)
|
|||||||
u_char fg = gc->fg;
|
u_char fg = gc->fg;
|
||||||
char s[32];
|
char s[32];
|
||||||
|
|
||||||
|
tc->flags &= ~(GRID_FLAG_FG256|GRID_FLAG_FGRGB);
|
||||||
|
|
||||||
|
/* Is this a 24-bit colour? */
|
||||||
|
if (gc->flags & GRID_FLAG_FGRGB) {
|
||||||
|
if (tty_try_rgb(tty, &gc->fg_rgb, "38") == 0)
|
||||||
|
goto save_fg;
|
||||||
|
/* Should not get here, already converted in tty_check_fg. */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Is this a 256-colour colour? */
|
/* Is this a 256-colour colour? */
|
||||||
if (gc->flags & GRID_FLAG_FG256) {
|
if (gc->flags & GRID_FLAG_FG256) {
|
||||||
/* Try as 256 colours. */
|
|
||||||
if (tty_try_256(tty, fg, "38") == 0)
|
if (tty_try_256(tty, fg, "38") == 0)
|
||||||
goto save_fg;
|
goto save_fg;
|
||||||
/* Else already handled by tty_check_fg. */
|
/* Should not get here, already converted in tty_check_fg. */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1581,9 +1677,12 @@ tty_colours_fg(struct tty *tty, const struct grid_cell *gc)
|
|||||||
|
|
||||||
save_fg:
|
save_fg:
|
||||||
/* Save the new values in the terminal current cell. */
|
/* Save the new values in the terminal current cell. */
|
||||||
tc->fg = fg;
|
if (gc->flags & GRID_FLAG_FGRGB)
|
||||||
tc->flags &= ~GRID_FLAG_FG256;
|
memcpy(&tc->fg_rgb, &gc->fg_rgb, sizeof tc->fg_rgb);
|
||||||
tc->flags |= gc->flags & GRID_FLAG_FG256;
|
else
|
||||||
|
tc->fg = fg;
|
||||||
|
tc->flags &= ~(GRID_FLAG_FGRGB|GRID_FLAG_FG256);
|
||||||
|
tc->flags |= (gc->flags & (GRID_FLAG_FG256|GRID_FLAG_FGRGB));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1593,12 +1692,19 @@ tty_colours_bg(struct tty *tty, const struct grid_cell *gc)
|
|||||||
u_char bg = gc->bg;
|
u_char bg = gc->bg;
|
||||||
char s[32];
|
char s[32];
|
||||||
|
|
||||||
|
/* Is this a 24-bit colour? */
|
||||||
|
if (gc->flags & GRID_FLAG_BGRGB) {
|
||||||
|
if (tty_try_rgb(tty, &gc->bg_rgb, "48") == 0)
|
||||||
|
goto save_bg;
|
||||||
|
/* Should not get here, already converted in tty_check_bg. */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Is this a 256-colour colour? */
|
/* Is this a 256-colour colour? */
|
||||||
if (gc->flags & GRID_FLAG_BG256) {
|
if (gc->flags & GRID_FLAG_BG256) {
|
||||||
/* Try as 256 colours. */
|
|
||||||
if (tty_try_256(tty, bg, "48") == 0)
|
if (tty_try_256(tty, bg, "48") == 0)
|
||||||
goto save_bg;
|
goto save_bg;
|
||||||
/* Else already handled by tty_check_bg. */
|
/* Should not get here, already converted in tty_check_bg. */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1614,9 +1720,12 @@ tty_colours_bg(struct tty *tty, const struct grid_cell *gc)
|
|||||||
|
|
||||||
save_bg:
|
save_bg:
|
||||||
/* Save the new values in the terminal current cell. */
|
/* Save the new values in the terminal current cell. */
|
||||||
tc->bg = bg;
|
if (gc->flags & GRID_FLAG_BGRGB)
|
||||||
tc->flags &= ~GRID_FLAG_BG256;
|
memcpy(&tc->bg_rgb, &gc->bg_rgb, sizeof tc->bg_rgb);
|
||||||
tc->flags |= gc->flags & GRID_FLAG_BG256;
|
else
|
||||||
|
tc->bg = bg;
|
||||||
|
tc->flags &= ~(GRID_FLAG_BGRGB|GRID_FLAG_BG256);
|
||||||
|
tc->flags |= (gc->flags & (GRID_FLAG_BG256|GRID_FLAG_BGRGB));
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -1656,6 +1765,20 @@ fallback:
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
tty_try_rgb(struct tty *tty, const struct grid_cell_rgb *rgb, const char *type)
|
||||||
|
{
|
||||||
|
char s[32];
|
||||||
|
|
||||||
|
if (!tty_term_flag(tty->term, TTYC_TC))
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
xsnprintf(s, sizeof s, "\033[%s;2;%hhu;%hhu;%hhum", type, rgb->r,
|
||||||
|
rgb->g, rgb->b);
|
||||||
|
tty_puts(tty, s);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
tty_default_colours(struct grid_cell *gc, const struct window_pane *wp)
|
tty_default_colours(struct grid_cell *gc, const struct window_pane *wp)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user