X Tutup
Skip to content

Commit 427b820

Browse files
author
nicm
committed
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.
1 parent b5b5221 commit 427b820

File tree

6 files changed

+209
-55
lines changed

6 files changed

+209
-55
lines changed

grid.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737

3838
/* Default grid cell data. */
3939
const struct grid_cell grid_default_cell = {
40-
0, 0, 8, 8, { { ' ' }, 0, 1, 1 }
40+
0, 0, { .fg = 8 }, { .bg = 8 }, { { ' ' }, 0, 1, 1 }
4141
};
4242
const struct grid_cell_entry grid_default_entry = {
4343
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)
284284
struct grid_line *gl;
285285
struct grid_cell_entry *gce;
286286
struct grid_cell *gcp;
287+
int extended;
287288

288289
if (grid_check_y(gd, py) != 0)
289290
return;
@@ -293,8 +294,12 @@ grid_set_cell(struct grid *gd, u_int px, u_int py, const struct grid_cell *gc)
293294
gl = &gd->linedata[py];
294295
gce = &gl->celldata[px];
295296

296-
if ((gce->flags & GRID_FLAG_EXTENDED) || gc->data.size != 1 ||
297-
gc->data.width != 1) {
297+
extended = (gce->flags & GRID_FLAG_EXTENDED);
298+
if (!extended && (gc->data.size != 1 || gc->data.width != 1))
299+
extended = 1;
300+
if (!extended && (gc->flags & (GRID_FLAG_FGRGB|GRID_FLAG_BGRGB)))
301+
extended = 1;
302+
if (extended) {
298303
if (~gce->flags & GRID_FLAG_EXTENDED) {
299304
gl->extddata = xreallocarray(gl->extddata,
300305
gl->extdsize + 1, sizeof *gl->extddata);

input.c

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1629,18 +1629,20 @@ input_csi_dispatch_sgr_256(struct input_ctx *ictx, int fgbg, u_int *i)
16291629
c = input_get(ictx, *i, 0, -1);
16301630
if (c == -1) {
16311631
if (fgbg == 38) {
1632-
gc->flags &= ~GRID_FLAG_FG256;
1632+
gc->flags &= ~(GRID_FLAG_FG256|GRID_FLAG_FGRGB);
16331633
gc->fg = 8;
16341634
} else if (fgbg == 48) {
1635-
gc->flags &= ~GRID_FLAG_BG256;
1635+
gc->flags &= ~(GRID_FLAG_BG256|GRID_FLAG_BGRGB);
16361636
gc->bg = 8;
16371637
}
16381638
} else {
16391639
if (fgbg == 38) {
16401640
gc->flags |= GRID_FLAG_FG256;
1641+
gc->flags &= ~GRID_FLAG_FGRGB;
16411642
gc->fg = c;
16421643
} else if (fgbg == 48) {
16431644
gc->flags |= GRID_FLAG_BG256;
1645+
gc->flags &= ~GRID_FLAG_BGRGB;
16441646
gc->bg = c;
16451647
}
16461648
}
@@ -1651,7 +1653,7 @@ void
16511653
input_csi_dispatch_sgr_rgb(struct input_ctx *ictx, int fgbg, u_int *i)
16521654
{
16531655
struct grid_cell *gc = &ictx->cell.cell;
1654-
int c, r, g, b;
1656+
int r, g, b;
16551657

16561658
(*i)++;
16571659
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)
16661668
if (b == -1 || b > 255)
16671669
return;
16681670

1669-
c = colour_find_rgb(r, g, b);
16701671
if (fgbg == 38) {
1671-
gc->flags |= GRID_FLAG_FG256;
1672-
gc->fg = c;
1672+
gc->flags &= ~GRID_FLAG_FG256;
1673+
gc->flags |= GRID_FLAG_FGRGB;
1674+
gc->fg_rgb.r = r;
1675+
gc->fg_rgb.g = g;
1676+
gc->fg_rgb.b = b;
16731677
} else if (fgbg == 48) {
1674-
gc->flags |= GRID_FLAG_BG256;
1675-
gc->bg = c;
1678+
gc->flags &= ~GRID_FLAG_BG256;
1679+
gc->flags |= GRID_FLAG_BGRGB;
1680+
gc->bg_rgb.r = r;
1681+
gc->bg_rgb.g = g;
1682+
gc->bg_rgb.b = b;
16761683
}
16771684
}
16781685

@@ -1754,11 +1761,11 @@ input_csi_dispatch_sgr(struct input_ctx *ictx)
17541761
case 35:
17551762
case 36:
17561763
case 37:
1757-
gc->flags &= ~GRID_FLAG_FG256;
1764+
gc->flags &= ~(GRID_FLAG_FG256|GRID_FLAG_FGRGB);
17581765
gc->fg = n - 30;
17591766
break;
17601767
case 39:
1761-
gc->flags &= ~GRID_FLAG_FG256;
1768+
gc->flags &= ~(GRID_FLAG_FG256|GRID_FLAG_FGRGB);
17621769
gc->fg = 8;
17631770
break;
17641771
case 40:
@@ -1769,11 +1776,11 @@ input_csi_dispatch_sgr(struct input_ctx *ictx)
17691776
case 45:
17701777
case 46:
17711778
case 47:
1772-
gc->flags &= ~GRID_FLAG_BG256;
1779+
gc->flags &= ~(GRID_FLAG_BG256|GRID_FLAG_BGRGB);
17731780
gc->bg = n - 40;
17741781
break;
17751782
case 49:
1776-
gc->flags &= ~GRID_FLAG_BG256;
1783+
gc->flags &= ~(GRID_FLAG_BG256|GRID_FLAG_BGRGB);
17771784
gc->bg = 8;
17781785
break;
17791786
case 90:
@@ -1784,7 +1791,7 @@ input_csi_dispatch_sgr(struct input_ctx *ictx)
17841791
case 95:
17851792
case 96:
17861793
case 97:
1787-
gc->flags &= ~GRID_FLAG_FG256;
1794+
gc->flags &= ~(GRID_FLAG_FG256|GRID_FLAG_FGRGB);
17881795
gc->fg = n;
17891796
break;
17901797
case 100:
@@ -1795,7 +1802,7 @@ input_csi_dispatch_sgr(struct input_ctx *ictx)
17951802
case 105:
17961803
case 106:
17971804
case 107:
1798-
gc->flags &= ~GRID_FLAG_BG256;
1805+
gc->flags &= ~(GRID_FLAG_BG256|GRID_FLAG_BGRGB);
17991806
gc->bg = n - 10;
18001807
break;
18011808
}

tmux.1

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2921,7 +2921,7 @@ and poor for interactive programs such as shells.
29212921
.Op Ic on | off
29222922
.Xc
29232923
Allow programs to change the window name using a terminal escape
2924-
sequence (\\033k...\\033\\\\).
2924+
sequence (\eek...\ee\e\e).
29252925
The default is on.
29262926
.Pp
29272927
.It Xo Ic alternate-screen
@@ -4024,7 +4024,7 @@ This command only works from outside
40244024
.El
40254025
.Sh TERMINFO EXTENSIONS
40264026
.Nm
4027-
understands some extensions to
4027+
understands some unofficial extensions to
40284028
.Xr terminfo 5 :
40294029
.Bl -tag -width Ds
40304030
.It Em Cs , Cr
@@ -4048,10 +4048,12 @@ $ printf '\e033[4 q'
40484048
If
40494049
.Em Se
40504050
is not set, \&Ss with argument 0 will be used to reset the cursor style instead.
4051+
.It Em \&Tc
4052+
Indicate that the terminal supports the
4053+
.Ql direct colour
4054+
RGB escape sequence (for example, \ee[38;2;255;255;255m).
40514055
.It Em \&Ms
4052-
This sequence can be used by
4053-
.Nm
4054-
to store the current buffer in the host terminal's selection (clipboard).
4056+
Store the current buffer in the host terminal's selection (clipboard).
40554057
See the
40564058
.Em set-clipboard
40574059
option above and the

tmux.h

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,7 @@ enum tty_code_code {
385385
TTYC_SMSO, /* enter_standout_mode, so */
386386
TTYC_SMUL, /* enter_underline_mode, us */
387387
TTYC_SS, /* set cursor style, Ss */
388+
TTYC_TC, /* 24-bit "true" colour, Tc */
388389
TTYC_TSL, /* to_status_line, tsl */
389390
TTYC_VPA, /* row_address, cv */
390391
TTYC_XENL, /* eat_newline_glitch, xn */
@@ -641,16 +642,31 @@ enum utf8_state {
641642
#define GRID_FLAG_BG256 0x2
642643
#define GRID_FLAG_PADDING 0x4
643644
#define GRID_FLAG_EXTENDED 0x8
645+
#define GRID_FLAG_FGRGB 0x10
646+
#define GRID_FLAG_BGRGB 0x20
644647

645648
/* Grid line flags. */
646649
#define GRID_LINE_WRAPPED 0x1
647650

651+
/* Grid cell RGB colours. */
652+
struct grid_cell_rgb {
653+
u_char r;
654+
u_char g;
655+
u_char b;
656+
};
657+
648658
/* Grid cell data. */
649659
struct grid_cell {
650660
u_char flags;
651661
u_char attr;
652-
u_char fg;
653-
u_char bg;
662+
union {
663+
u_char fg;
664+
struct grid_cell_rgb fg_rgb;
665+
};
666+
union {
667+
u_char bg;
668+
struct grid_cell_rgb bg_rgb;
669+
};
654670
struct utf8_data data;
655671

656672
};

tty-term.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,7 @@ const struct tty_term_code_entry tty_term_codes[] = {
251251
[TTYC_SMSO] = { TTYCODE_STRING, "smso" },
252252
[TTYC_SMUL] = { TTYCODE_STRING, "smul" },
253253
[TTYC_SS] = { TTYCODE_STRING, "Ss" },
254+
[TTYC_TC] = { TTYCODE_FLAG, "Tc" },
254255
[TTYC_TSL] = { TTYCODE_STRING, "tsl" },
255256
[TTYC_VPA] = { TTYCODE_STRING, "vpa" },
256257
[TTYC_XENL] = { TTYCODE_FLAG, "xenl" },

0 commit comments

Comments
 (0)
X Tutup