summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornicm <nicm>2019-06-27 15:17:41 +0000
committernicm <nicm>2019-06-27 15:17:41 +0000
commitdae2868d1227b95fd076fb4a5efa6256c7245943 (patch)
treee9c0285c193c9e3463b4e3d45cfd71a7668aedfa
parent3a6d90adadfcd4aa6b513df7f8ae5c4dcc05a6dc (diff)
Add support for underscore colours with Setulc capability, mostly from
Kai Moschcau.
-rw-r--r--colour.c84
-rw-r--r--grid.c6
-rw-r--r--input.c11
-rw-r--r--screen-write.c2
-rw-r--r--style.c2
-rw-r--r--tmux.130
-rw-r--r--tmux.h5
-rw-r--r--tty-term.c1
-rw-r--r--tty.c64
9 files changed, 184 insertions, 21 deletions
diff --git a/colour.c b/colour.c
index eaee6058..c7972878 100644
--- a/colour.c
+++ b/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 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 u_char table[256] = {
+ 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]);
}
diff --git a/grid.c b/grid.c
index d185f364..cddb5871 100644
--- a/grid.c
+++ b/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);
}
diff --git a/input.c b/input.c
index 7df2a7b0..ff8d7a17 100644
--- a/input.c
+++ b/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:
diff --git a/screen-write.c b/screen-write.c
index 174c7a82..631328a3 100644
--- a/screen-write.c
+++ b/screen-write.c
@@ -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 {
diff --git a/style.c b/style.c
index ce78175a..4c6174c7 100644
--- a/style.c
+++ b/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,
diff --git a/tmux.1 b/tmux.1
index f4ba7471..8b093220 100644
--- a/tmux.1
+++ b/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
diff --git a/tmux.h b/tmux.h
index ba257ea8..7126b30f 100644
--- a/tmux.h
+++ b/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);
diff --git a/tty-term.c b/tty-term.c
index 83bfcdc1..39e2b013 100644
--- a/tty-term.c
+++ b/tty-term.c
@@ -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" },
diff --git a/tty.c b/tty.c
index 1c0c88d4..c3e2f0f6 100644
--- a/tty.c
+++ b/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
@@ -2386,6 +2399,22 @@ tty_check_bg(struct tty *tty, struct window_pane *wp, struct grid_cell *gc)
}
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)
{
struct grid_cell *tc = &tty->cell;
@@ -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)
{