mirror of
https://github.com/tmux/tmux.git
synced 2024-12-04 19:58:48 +00:00
Add support for underscore colours with Setulc capability, mostly from
Kai Moschcau.
This commit is contained in:
parent
3a6d90adad
commit
dae2868d12
84
colour.c
84
colour.c
@ -230,11 +230,85 @@ colour_fromstring(const char *s)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* Convert 256 colour palette to 16. */
|
||||
u_char
|
||||
colour_256to16(u_char c)
|
||||
/* Convert 256 colour to RGB colour. */
|
||||
int
|
||||
colour_256toRGB(int c)
|
||||
{
|
||||
static const u_char table[256] = {
|
||||
static const int table[256] = {
|
||||
0x000000, 0x800000, 0x008000, 0x808000,
|
||||
0x000080, 0x800080, 0x008080, 0xc0c0c0,
|
||||
0x808080, 0xff0000, 0x00ff00, 0xffff00,
|
||||
0x0000ff, 0xff00ff, 0x00ffff, 0xffffff,
|
||||
0x000000, 0x00005f, 0x000087, 0x0000af,
|
||||
0x0000d7, 0x0000ff, 0x005f00, 0x005f5f,
|
||||
0x005f87, 0x005faf, 0x005fd7, 0x005fff,
|
||||
0x008700, 0x00875f, 0x008787, 0x0087af,
|
||||
0x0087d7, 0x0087ff, 0x00af00, 0x00af5f,
|
||||
0x00af87, 0x00afaf, 0x00afd7, 0x00afff,
|
||||
0x00d700, 0x00d75f, 0x00d787, 0x00d7af,
|
||||
0x00d7d7, 0x00d7ff, 0x00ff00, 0x00ff5f,
|
||||
0x00ff87, 0x00ffaf, 0x00ffd7, 0x00ffff,
|
||||
0x5f0000, 0x5f005f, 0x5f0087, 0x5f00af,
|
||||
0x5f00d7, 0x5f00ff, 0x5f5f00, 0x5f5f5f,
|
||||
0x5f5f87, 0x5f5faf, 0x5f5fd7, 0x5f5fff,
|
||||
0x5f8700, 0x5f875f, 0x5f8787, 0x5f87af,
|
||||
0x5f87d7, 0x5f87ff, 0x5faf00, 0x5faf5f,
|
||||
0x5faf87, 0x5fafaf, 0x5fafd7, 0x5fafff,
|
||||
0x5fd700, 0x5fd75f, 0x5fd787, 0x5fd7af,
|
||||
0x5fd7d7, 0x5fd7ff, 0x5fff00, 0x5fff5f,
|
||||
0x5fff87, 0x5fffaf, 0x5fffd7, 0x5fffff,
|
||||
0x870000, 0x87005f, 0x870087, 0x8700af,
|
||||
0x8700d7, 0x8700ff, 0x875f00, 0x875f5f,
|
||||
0x875f87, 0x875faf, 0x875fd7, 0x875fff,
|
||||
0x878700, 0x87875f, 0x878787, 0x8787af,
|
||||
0x8787d7, 0x8787ff, 0x87af00, 0x87af5f,
|
||||
0x87af87, 0x87afaf, 0x87afd7, 0x87afff,
|
||||
0x87d700, 0x87d75f, 0x87d787, 0x87d7af,
|
||||
0x87d7d7, 0x87d7ff, 0x87ff00, 0x87ff5f,
|
||||
0x87ff87, 0x87ffaf, 0x87ffd7, 0x87ffff,
|
||||
0xaf0000, 0xaf005f, 0xaf0087, 0xaf00af,
|
||||
0xaf00d7, 0xaf00ff, 0xaf5f00, 0xaf5f5f,
|
||||
0xaf5f87, 0xaf5faf, 0xaf5fd7, 0xaf5fff,
|
||||
0xaf8700, 0xaf875f, 0xaf8787, 0xaf87af,
|
||||
0xaf87d7, 0xaf87ff, 0xafaf00, 0xafaf5f,
|
||||
0xafaf87, 0xafafaf, 0xafafd7, 0xafafff,
|
||||
0xafd700, 0xafd75f, 0xafd787, 0xafd7af,
|
||||
0xafd7d7, 0xafd7ff, 0xafff00, 0xafff5f,
|
||||
0xafff87, 0xafffaf, 0xafffd7, 0xafffff,
|
||||
0xd70000, 0xd7005f, 0xd70087, 0xd700af,
|
||||
0xd700d7, 0xd700ff, 0xd75f00, 0xd75f5f,
|
||||
0xd75f87, 0xd75faf, 0xd75fd7, 0xd75fff,
|
||||
0xd78700, 0xd7875f, 0xd78787, 0xd787af,
|
||||
0xd787d7, 0xd787ff, 0xd7af00, 0xd7af5f,
|
||||
0xd7af87, 0xd7afaf, 0xd7afd7, 0xd7afff,
|
||||
0xd7d700, 0xd7d75f, 0xd7d787, 0xd7d7af,
|
||||
0xd7d7d7, 0xd7d7ff, 0xd7ff00, 0xd7ff5f,
|
||||
0xd7ff87, 0xd7ffaf, 0xd7ffd7, 0xd7ffff,
|
||||
0xff0000, 0xff005f, 0xff0087, 0xff00af,
|
||||
0xff00d7, 0xff00ff, 0xff5f00, 0xff5f5f,
|
||||
0xff5f87, 0xff5faf, 0xff5fd7, 0xff5fff,
|
||||
0xff8700, 0xff875f, 0xff8787, 0xff87af,
|
||||
0xff87d7, 0xff87ff, 0xffaf00, 0xffaf5f,
|
||||
0xffaf87, 0xffafaf, 0xffafd7, 0xffafff,
|
||||
0xffd700, 0xffd75f, 0xffd787, 0xffd7af,
|
||||
0xffd7d7, 0xffd7ff, 0xffff00, 0xffff5f,
|
||||
0xffff87, 0xffffaf, 0xffffd7, 0xffffff,
|
||||
0x080808, 0x121212, 0x1c1c1c, 0x262626,
|
||||
0x303030, 0x3a3a3a, 0x444444, 0x4e4e4e,
|
||||
0x585858, 0x626262, 0x6c6c6c, 0x767676,
|
||||
0x808080, 0x8a8a8a, 0x949494, 0x9e9e9e,
|
||||
0xa8a8a8, 0xb2b2b2, 0xbcbcbc, 0xc6c6c6,
|
||||
0xd0d0d0, 0xdadada, 0xe4e4e4, 0xeeeeee
|
||||
};
|
||||
|
||||
return (table[c & 0xff] | COLOUR_FLAG_RGB);
|
||||
}
|
||||
|
||||
/* Convert 256 colour to 16 colour. */
|
||||
int
|
||||
colour_256to16(int c)
|
||||
{
|
||||
static const char table[256] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
0, 4, 4, 4, 12, 12, 2, 6, 4, 4, 12, 12, 2, 2, 6, 4,
|
||||
12, 12, 2, 2, 2, 6, 12, 12, 10, 10, 10, 10, 14, 12, 10, 10,
|
||||
@ -253,5 +327,5 @@ colour_256to16(u_char c)
|
||||
8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 15, 15, 15, 15, 15, 15
|
||||
};
|
||||
|
||||
return (table[c]);
|
||||
return (table[c & 0xff]);
|
||||
}
|
||||
|
6
grid.c
6
grid.c
@ -37,12 +37,12 @@
|
||||
|
||||
/* Default grid cell data. */
|
||||
const struct grid_cell grid_default_cell = {
|
||||
0, 0, 8, 8, { { ' ' }, 0, 1, 1 }
|
||||
0, 0, 8, 8, 0, { { ' ' }, 0, 1, 1 }
|
||||
};
|
||||
|
||||
/* Cleared grid cell data. */
|
||||
const struct grid_cell grid_cleared_cell = {
|
||||
GRID_FLAG_CLEARED, 0, 8, 8, { { ' ' }, 0, 1, 1 }
|
||||
GRID_FLAG_CLEARED, 0, 8, 8, 0, { { ' ' }, 0, 1, 1 }
|
||||
};
|
||||
static const struct grid_cell_entry grid_cleared_entry = {
|
||||
GRID_FLAG_CLEARED, { .data = { 0, 8, 8, ' ' } }
|
||||
@ -82,6 +82,8 @@ grid_need_extended_cell(const struct grid_cell_entry *gce,
|
||||
return (1);
|
||||
if ((gc->fg & COLOUR_FLAG_RGB) || (gc->bg & COLOUR_FLAG_RGB))
|
||||
return (1);
|
||||
if (gc->us != 0) /* only supports 256 or RGB */
|
||||
return (1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
11
input.c
11
input.c
@ -1829,6 +1829,8 @@ input_csi_dispatch_sgr_256_do(struct input_ctx *ictx, int fgbg, int c)
|
||||
gc->fg = c | COLOUR_FLAG_256;
|
||||
else if (fgbg == 48)
|
||||
gc->bg = c | COLOUR_FLAG_256;
|
||||
else if (fgbg == 58)
|
||||
gc->us = c | COLOUR_FLAG_256;
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
@ -1862,6 +1864,8 @@ input_csi_dispatch_sgr_rgb_do(struct input_ctx *ictx, int fgbg, int r, int g,
|
||||
gc->fg = colour_join_rgb(r, g, b);
|
||||
else if (fgbg == 48)
|
||||
gc->bg = colour_join_rgb(r, g, b);
|
||||
else if (fgbg == 58)
|
||||
gc->us = colour_join_rgb(r, g, b);
|
||||
return (1);
|
||||
}
|
||||
|
||||
@ -1938,7 +1942,7 @@ input_csi_dispatch_sgr_colon(struct input_ctx *ictx, u_int i)
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (n < 2 || (p[0] != 38 && p[0] != 48))
|
||||
if (n < 2 || (p[0] != 38 && p[0] != 48 && p[0] != 58))
|
||||
return;
|
||||
switch (p[1]) {
|
||||
case 2:
|
||||
@ -1983,7 +1987,7 @@ input_csi_dispatch_sgr(struct input_ctx *ictx)
|
||||
if (n == -1)
|
||||
continue;
|
||||
|
||||
if (n == 38 || n == 48) {
|
||||
if (n == 38 || n == 48 || n == 58) {
|
||||
i++;
|
||||
switch (input_get(ictx, i, 0, -1)) {
|
||||
case 2:
|
||||
@ -2078,6 +2082,9 @@ input_csi_dispatch_sgr(struct input_ctx *ictx)
|
||||
case 55:
|
||||
gc->attr &= ~GRID_ATTR_OVERLINE;
|
||||
break;
|
||||
case 59:
|
||||
gc->us = 0;
|
||||
break;
|
||||
case 90:
|
||||
case 91:
|
||||
case 92:
|
||||
|
@ -36,7 +36,7 @@ static const struct grid_cell *screen_write_combine(struct screen_write_ctx *,
|
||||
const struct utf8_data *, u_int *);
|
||||
|
||||
static const struct grid_cell screen_write_pad_cell = {
|
||||
GRID_FLAG_PADDING, 0, 8, 8, { { 0 }, 0, 0, 0 }
|
||||
GRID_FLAG_PADDING, 0, 8, 8, 0, { { 0 }, 0, 0, 0 }
|
||||
};
|
||||
|
||||
struct screen_write_collect_item {
|
||||
|
2
style.c
2
style.c
@ -30,7 +30,7 @@
|
||||
|
||||
/* Default style. */
|
||||
static struct style style_default = {
|
||||
{ 0, 0, 8, 8, { { ' ' }, 0, 1, 1 } },
|
||||
{ 0, 0, 8, 8, 0, { { ' ' }, 0, 1, 1 } },
|
||||
|
||||
STYLE_ALIGN_DEFAULT,
|
||||
STYLE_LIST_OFF,
|
||||
|
30
tmux.1
30
tmux.1
@ -5044,11 +5044,33 @@ $ printf '\e033]12;red\e033\e\e'
|
||||
.Ed
|
||||
.It Em \&Smol
|
||||
Enable the overline attribute.
|
||||
The capability is usually SGR 53 and can be added to
|
||||
.Ic terminal-overrides
|
||||
as:
|
||||
.Bd -literal -offset indent
|
||||
Smol=\eE[53m
|
||||
.Ed
|
||||
.It Em \&Smulx
|
||||
Set a styled underline.
|
||||
The single parameter is one of: 0 for no underline, 1 for normal
|
||||
underline, 2 for double underline, 3 for curly underline, 4 for dotted
|
||||
underline and 5 for dashed underline.
|
||||
Set a styled underscore.
|
||||
The single parameter is one of: 0 for no underscore, 1 for normal
|
||||
underscore, 2 for double underscore, 3 for curly underscore, 4 for dotted
|
||||
underscore and 5 for dashed underscore.
|
||||
The capability can typically be added to
|
||||
.Ic terminal-overrides
|
||||
as:
|
||||
.Bd -literal -offset indent
|
||||
Smulx=\eE[4::%p1%dm
|
||||
.Ed
|
||||
.It Em \&Setulc
|
||||
Set the underscore colour.
|
||||
The argument is (red * 65536) + (green * 256) + blue where each is between 0
|
||||
and 255.
|
||||
The capability can typically be added to
|
||||
.Ic terminal-overrides
|
||||
as:
|
||||
.Bd -literal -offset indent
|
||||
Setulc=\eE[58::2::%p1%{65536}%/%d::%p1%{256}%/%{255}%&%d::%p1%{255}%&%d%;m
|
||||
.Ed
|
||||
.It Em \&Ss , Se
|
||||
Set or reset the cursor style.
|
||||
If set, a sequence such as this may be used
|
||||
|
5
tmux.h
5
tmux.h
@ -427,6 +427,7 @@ enum tty_code_code {
|
||||
TTYC_SETAF,
|
||||
TTYC_SETRGBB,
|
||||
TTYC_SETRGBF,
|
||||
TTYC_SETULC,
|
||||
TTYC_SGR0,
|
||||
TTYC_SITM,
|
||||
TTYC_SMACS,
|
||||
@ -599,6 +600,7 @@ struct grid_cell {
|
||||
u_short attr;
|
||||
int fg;
|
||||
int bg;
|
||||
int us;
|
||||
struct utf8_data data;
|
||||
};
|
||||
struct grid_cell_entry {
|
||||
@ -2194,7 +2196,8 @@ int colour_join_rgb(u_char, u_char, u_char);
|
||||
void colour_split_rgb(int, u_char *, u_char *, u_char *);
|
||||
const char *colour_tostring(int);
|
||||
int colour_fromstring(const char *s);
|
||||
u_char colour_256to16(u_char);
|
||||
int colour_256toRGB(int);
|
||||
int colour_256to16(int);
|
||||
|
||||
/* attributes.c */
|
||||
const char *attributes_tostring(int);
|
||||
|
@ -246,6 +246,7 @@ static const struct tty_term_code_entry tty_term_codes[] = {
|
||||
[TTYC_SETAF] = { TTYCODE_STRING, "setaf" },
|
||||
[TTYC_SETRGBB] = { TTYCODE_STRING, "setrgbb" },
|
||||
[TTYC_SETRGBF] = { TTYCODE_STRING, "setrgbf" },
|
||||
[TTYC_SETULC] = { TTYCODE_STRING, "Setulc" },
|
||||
[TTYC_SE] = { TTYCODE_STRING, "Se" },
|
||||
[TTYC_SGR0] = { TTYCODE_STRING, "sgr0" },
|
||||
[TTYC_SITM] = { TTYCODE_STRING, "sitm" },
|
||||
|
64
tty.c
64
tty.c
@ -49,8 +49,11 @@ static void tty_check_fg(struct tty *, struct window_pane *,
|
||||
struct grid_cell *);
|
||||
static void tty_check_bg(struct tty *, struct window_pane *,
|
||||
struct grid_cell *);
|
||||
static void tty_check_us(struct tty *, struct window_pane *,
|
||||
struct grid_cell *);
|
||||
static void tty_colours_fg(struct tty *, const struct grid_cell *);
|
||||
static void tty_colours_bg(struct tty *, const struct grid_cell *);
|
||||
static void tty_colours_us(struct tty *, const struct grid_cell *);
|
||||
|
||||
static void tty_region_pane(struct tty *, const struct tty_ctx *, u_int,
|
||||
u_int);
|
||||
@ -1287,6 +1290,7 @@ tty_draw_line(struct tty *tty, struct window_pane *wp, struct screen *s,
|
||||
gcp->attr != last.attr ||
|
||||
gcp->fg != last.fg ||
|
||||
gcp->bg != last.bg ||
|
||||
gcp->us != last.us ||
|
||||
ux + width + gcp->data.width > nx ||
|
||||
(sizeof buf) - len < gcp->data.size)) {
|
||||
tty_attributes(tty, &last, wp);
|
||||
@ -2135,7 +2139,8 @@ tty_attributes(struct tty *tty, const struct grid_cell *gc,
|
||||
~(wp->flags & PANE_STYLECHANGED) &&
|
||||
gc->attr == tty->last_cell.attr &&
|
||||
gc->fg == tty->last_cell.fg &&
|
||||
gc->bg == tty->last_cell.bg)
|
||||
gc->bg == tty->last_cell.bg &&
|
||||
gc->us == tty->last_cell.us)
|
||||
return;
|
||||
tty->last_wp = (wp != NULL ? (int)wp->id : -1);
|
||||
memcpy(&tty->last_cell, gc, sizeof tty->last_cell);
|
||||
@ -2163,14 +2168,18 @@ tty_attributes(struct tty *tty, const struct grid_cell *gc,
|
||||
/* Fix up the colours if necessary. */
|
||||
tty_check_fg(tty, wp, &gc2);
|
||||
tty_check_bg(tty, wp, &gc2);
|
||||
tty_check_us(tty, wp, &gc2);
|
||||
|
||||
/* If any bits are being cleared, reset everything. */
|
||||
if (tc->attr & ~gc2.attr)
|
||||
/*
|
||||
* If any bits are being cleared or the underline colour is now default,
|
||||
* reset everything.
|
||||
*/
|
||||
if ((tc->attr & ~gc2.attr) || (tc->us != gc2.us && gc2.us == 0))
|
||||
tty_reset(tty);
|
||||
|
||||
/*
|
||||
* Set the colours. This may call tty_reset() (so it comes next) and
|
||||
* may add to (NOT remove) the desired attributes by changing new_attr.
|
||||
* may add to (NOT remove) the desired attributes.
|
||||
*/
|
||||
tty_colours(tty, &gc2);
|
||||
|
||||
@ -2223,7 +2232,7 @@ tty_colours(struct tty *tty, const struct grid_cell *gc)
|
||||
int have_ax;
|
||||
|
||||
/* No changes? Nothing is necessary. */
|
||||
if (gc->fg == tc->fg && gc->bg == tc->bg)
|
||||
if (gc->fg == tc->fg && gc->bg == tc->bg && gc->us == tc->us)
|
||||
return;
|
||||
|
||||
/*
|
||||
@ -2271,6 +2280,10 @@ tty_colours(struct tty *tty, const struct grid_cell *gc)
|
||||
*/
|
||||
if (!COLOUR_DEFAULT(gc->bg) && gc->bg != tc->bg)
|
||||
tty_colours_bg(tty, gc);
|
||||
|
||||
/* Set the underscore color. */
|
||||
if (gc->us != tc->us)
|
||||
tty_colours_us(tty, gc);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -2385,6 +2398,22 @@ tty_check_bg(struct tty *tty, struct window_pane *wp, struct grid_cell *gc)
|
||||
gc->bg -= 90;
|
||||
}
|
||||
|
||||
static void
|
||||
tty_check_us(__unused struct tty *tty, struct window_pane *wp, struct grid_cell *gc)
|
||||
{
|
||||
int c;
|
||||
|
||||
/* Perform substitution if this pane has a palette. */
|
||||
if (~gc->flags & GRID_FLAG_NOPALETTE) {
|
||||
if ((c = window_pane_get_palette(wp, gc->us)) != -1)
|
||||
gc->us = c;
|
||||
}
|
||||
|
||||
/* Underscore colour is set as RGB so convert a 256 colour to RGB. */
|
||||
if (gc->us & COLOUR_FLAG_256)
|
||||
gc->us = colour_256toRGB (gc->us);
|
||||
}
|
||||
|
||||
static void
|
||||
tty_colours_fg(struct tty *tty, const struct grid_cell *gc)
|
||||
{
|
||||
@ -2449,6 +2478,31 @@ save_bg:
|
||||
tc->bg = gc->bg;
|
||||
}
|
||||
|
||||
static void
|
||||
tty_colours_us(struct tty *tty, const struct grid_cell *gc)
|
||||
{
|
||||
struct grid_cell *tc = &tty->cell;
|
||||
u_int c;
|
||||
u_char r, g, b;
|
||||
|
||||
/* Must be an RGB colour - this should never happen. */
|
||||
if (~gc->us & COLOUR_FLAG_RGB)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Setulc follows the ncurses(3) one argument "direct colour"
|
||||
* capability format. Calculate the colour value.
|
||||
*/
|
||||
colour_split_rgb(gc->us, &r, &g, &b);
|
||||
c = (65536 * r) + (256 * g) + b;
|
||||
|
||||
/* Write the colour. */
|
||||
tty_putcode1(tty, TTYC_SETULC, c);
|
||||
|
||||
/* Save the new values in the terminal current cell. */
|
||||
tc->us = gc->us;
|
||||
}
|
||||
|
||||
static int
|
||||
tty_try_colour(struct tty *tty, int colour, const char *type)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user