Skip to content

Commit

Permalink
Support for RGB colour, using the extended cell mechanism to avoid
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
nicm committed Jan 29, 2016
1 parent b5b5221 commit 427b820
Show file tree
Hide file tree
Showing 6 changed files with 209 additions and 55 deletions.
11 changes: 8 additions & 3 deletions grid.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@

/* Default grid cell data. */
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 = {
0, { .data = { 0, 8, 8, ' ' } }
Expand Down Expand Up @@ -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_cell_entry *gce;
struct grid_cell *gcp;
int extended;

if (grid_check_y(gd, py) != 0)
return;
Expand All @@ -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];
gce = &gl->celldata[px];

if ((gce->flags & GRID_FLAG_EXTENDED) || gc->data.size != 1 ||
gc->data.width != 1) {
extended = (gce->flags & GRID_FLAG_EXTENDED);
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) {
gl->extddata = xreallocarray(gl->extddata,
gl->extdsize + 1, sizeof *gl->extddata);
Expand Down
35 changes: 21 additions & 14 deletions input.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
if (c == -1) {
if (fgbg == 38) {
gc->flags &= ~GRID_FLAG_FG256;
gc->flags &= ~(GRID_FLAG_FG256|GRID_FLAG_FGRGB);
gc->fg = 8;
} else if (fgbg == 48) {
gc->flags &= ~GRID_FLAG_BG256;
gc->flags &= ~(GRID_FLAG_BG256|GRID_FLAG_BGRGB);
gc->bg = 8;
}
} else {
if (fgbg == 38) {
gc->flags |= GRID_FLAG_FG256;
gc->flags &= ~GRID_FLAG_FGRGB;
gc->fg = c;
} else if (fgbg == 48) {
gc->flags |= GRID_FLAG_BG256;
gc->flags &= ~GRID_FLAG_BGRGB;
gc->bg = c;
}
}
Expand All @@ -1651,7 +1653,7 @@ void
input_csi_dispatch_sgr_rgb(struct input_ctx *ictx, int fgbg, u_int *i)
{
struct grid_cell *gc = &ictx->cell.cell;
int c, r, g, b;
int r, g, b;

(*i)++;
r = input_get(ictx, *i, 0, -1);
Expand All @@ -1666,13 +1668,18 @@ input_csi_dispatch_sgr_rgb(struct input_ctx *ictx, int fgbg, u_int *i)
if (b == -1 || b > 255)
return;

c = colour_find_rgb(r, g, b);
if (fgbg == 38) {
gc->flags |= GRID_FLAG_FG256;
gc->fg = c;
gc->flags &= ~GRID_FLAG_FG256;
gc->flags |= GRID_FLAG_FGRGB;
gc->fg_rgb.r = r;
gc->fg_rgb.g = g;
gc->fg_rgb.b = b;
} else if (fgbg == 48) {
gc->flags |= GRID_FLAG_BG256;
gc->bg = c;
gc->flags &= ~GRID_FLAG_BG256;
gc->flags |= GRID_FLAG_BGRGB;
gc->bg_rgb.r = r;
gc->bg_rgb.g = g;
gc->bg_rgb.b = b;
}
}

Expand Down Expand Up @@ -1754,11 +1761,11 @@ input_csi_dispatch_sgr(struct input_ctx *ictx)
case 35:
case 36:
case 37:
gc->flags &= ~GRID_FLAG_FG256;
gc->flags &= ~(GRID_FLAG_FG256|GRID_FLAG_FGRGB);
gc->fg = n - 30;
break;
case 39:
gc->flags &= ~GRID_FLAG_FG256;
gc->flags &= ~(GRID_FLAG_FG256|GRID_FLAG_FGRGB);
gc->fg = 8;
break;
case 40:
Expand All @@ -1769,11 +1776,11 @@ input_csi_dispatch_sgr(struct input_ctx *ictx)
case 45:
case 46:
case 47:
gc->flags &= ~GRID_FLAG_BG256;
gc->flags &= ~(GRID_FLAG_BG256|GRID_FLAG_BGRGB);
gc->bg = n - 40;
break;
case 49:
gc->flags &= ~GRID_FLAG_BG256;
gc->flags &= ~(GRID_FLAG_BG256|GRID_FLAG_BGRGB);
gc->bg = 8;
break;
case 90:
Expand All @@ -1784,7 +1791,7 @@ input_csi_dispatch_sgr(struct input_ctx *ictx)
case 95:
case 96:
case 97:
gc->flags &= ~GRID_FLAG_FG256;
gc->flags &= ~(GRID_FLAG_FG256|GRID_FLAG_FGRGB);
gc->fg = n;
break;
case 100:
Expand All @@ -1795,7 +1802,7 @@ input_csi_dispatch_sgr(struct input_ctx *ictx)
case 105:
case 106:
case 107:
gc->flags &= ~GRID_FLAG_BG256;
gc->flags &= ~(GRID_FLAG_BG256|GRID_FLAG_BGRGB);
gc->bg = n - 10;
break;
}
Expand Down
12 changes: 7 additions & 5 deletions tmux.1
Original file line number Diff line number Diff line change
Expand Up @@ -2921,7 +2921,7 @@ and poor for interactive programs such as shells.
.Op Ic on | off
.Xc
Allow programs to change the window name using a terminal escape
sequence (\\033k...\\033\\\\).
sequence (\eek...\ee\e\e).
The default is on.
.Pp
.It Xo Ic alternate-screen
Expand Down Expand Up @@ -4024,7 +4024,7 @@ This command only works from outside
.El
.Sh TERMINFO EXTENSIONS
.Nm
understands some extensions to
understands some unofficial extensions to
.Xr terminfo 5 :
.Bl -tag -width Ds
.It Em Cs , Cr
Expand All @@ -4048,10 +4048,12 @@ $ printf '\e033[4 q'
If
.Em Se
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
This sequence can be used by
.Nm
to store the current buffer in the host terminal's selection (clipboard).
Store the current buffer in the host terminal's selection (clipboard).
See the
.Em set-clipboard
option above and the
Expand Down
20 changes: 18 additions & 2 deletions tmux.h
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,7 @@ enum tty_code_code {
TTYC_SMSO, /* enter_standout_mode, so */
TTYC_SMUL, /* enter_underline_mode, us */
TTYC_SS, /* set cursor style, Ss */
TTYC_TC, /* 24-bit "true" colour, Tc */
TTYC_TSL, /* to_status_line, tsl */
TTYC_VPA, /* row_address, cv */
TTYC_XENL, /* eat_newline_glitch, xn */
Expand Down Expand Up @@ -641,16 +642,31 @@ enum utf8_state {
#define GRID_FLAG_BG256 0x2
#define GRID_FLAG_PADDING 0x4
#define GRID_FLAG_EXTENDED 0x8
#define GRID_FLAG_FGRGB 0x10
#define GRID_FLAG_BGRGB 0x20

/* Grid line flags. */
#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. */
struct grid_cell {
u_char flags;
u_char attr;
u_char fg;
u_char bg;
union {
u_char fg;
struct grid_cell_rgb fg_rgb;
};
union {
u_char bg;
struct grid_cell_rgb bg_rgb;
};
struct utf8_data data;

};
Expand Down
1 change: 1 addition & 0 deletions tty-term.c
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@ const struct tty_term_code_entry tty_term_codes[] = {
[TTYC_SMSO] = { TTYCODE_STRING, "smso" },
[TTYC_SMUL] = { TTYCODE_STRING, "smul" },
[TTYC_SS] = { TTYCODE_STRING, "Ss" },
[TTYC_TC] = { TTYCODE_FLAG, "Tc" },
[TTYC_TSL] = { TTYCODE_STRING, "tsl" },
[TTYC_VPA] = { TTYCODE_STRING, "vpa" },
[TTYC_XENL] = { TTYCODE_FLAG, "xenl" },
Expand Down
Loading

0 comments on commit 427b820

Please sign in to comment.