summaryrefslogtreecommitdiff
path: root/usr.bin/tmux/grid.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin/tmux/grid.c')
-rw-r--r--usr.bin/tmux/grid.c98
1 files changed, 64 insertions, 34 deletions
diff --git a/usr.bin/tmux/grid.c b/usr.bin/tmux/grid.c
index 29f7d194b8b..fe81172a662 100644
--- a/usr.bin/tmux/grid.c
+++ b/usr.bin/tmux/grid.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: grid.c,v 1.121 2021/02/05 12:29:18 nicm Exp $ */
+/* $OpenBSD: grid.c,v 1.122 2021/12/21 14:57:28 nicm Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -826,6 +826,56 @@ grid_string_cells_bg(const struct grid_cell *gc, int *values)
return (n);
}
+/* Get underscore colour sequence. */
+static size_t
+grid_string_cells_us(const struct grid_cell *gc, int *values)
+{
+ size_t n;
+ u_char r, g, b;
+
+ n = 0;
+ if (gc->us & COLOUR_FLAG_256) {
+ values[n++] = 58;
+ values[n++] = 5;
+ values[n++] = gc->us & 0xff;
+ } else if (gc->us & COLOUR_FLAG_RGB) {
+ values[n++] = 58;
+ values[n++] = 2;
+ colour_split_rgb(gc->us, &r, &g, &b);
+ values[n++] = r;
+ values[n++] = g;
+ values[n++] = b;
+ }
+ return (n);
+}
+
+/* Add on SGR code. */
+static void
+grid_string_cells_add_code(char *buf, size_t len, u_int n, int *s, int *newc,
+ int *oldc, size_t nnewc, size_t noldc, int escape_c0)
+{
+ u_int i;
+ char tmp[64];
+
+ if (nnewc != 0 &&
+ (nnewc != noldc ||
+ memcmp(newc, oldc, nnewc * sizeof newc[0]) != 0 ||
+ (n != 0 && s[0] == 0))) {
+ if (escape_c0)
+ strlcat(buf, "\\033[", len);
+ else
+ strlcat(buf, "\033[", len);
+ for (i = 0; i < nnewc; i++) {
+ if (i + 1 < nnewc)
+ xsnprintf(tmp, sizeof tmp, "%d;", newc[i]);
+ else
+ xsnprintf(tmp, sizeof tmp, "%d", newc[i]);
+ strlcat(buf, tmp, len);
+ }
+ strlcat(buf, "m", len);
+ }
+}
+
/*
* Returns ANSI code to set particular attributes (colour, bold and so on)
* given a current state.
@@ -861,7 +911,9 @@ grid_string_cells_code(const struct grid_cell *lastgc,
/* If any attribute is removed, begin with 0. */
for (i = 0; i < nitems(attrs); i++) {
- if (!(attr & attrs[i].mask) && (lastattr & attrs[i].mask)) {
+ if (((~attr & attrs[i].mask) &&
+ (lastattr & attrs[i].mask)) ||
+ (lastgc->us != 0 && gc->us == 0)) {
s[n++] = 0;
lastattr &= GRID_ATTR_CHARSET;
break;
@@ -897,42 +949,20 @@ grid_string_cells_code(const struct grid_cell *lastgc,
/* If the foreground colour changed, write its parameters. */
nnewc = grid_string_cells_fg(gc, newc);
noldc = grid_string_cells_fg(lastgc, oldc);
- if (nnewc != noldc ||
- memcmp(newc, oldc, nnewc * sizeof newc[0]) != 0 ||
- (n != 0 && s[0] == 0)) {
- if (escape_c0)
- strlcat(buf, "\\033[", len);
- else
- strlcat(buf, "\033[", len);
- for (i = 0; i < nnewc; i++) {
- if (i + 1 < nnewc)
- xsnprintf(tmp, sizeof tmp, "%d;", newc[i]);
- else
- xsnprintf(tmp, sizeof tmp, "%d", newc[i]);
- strlcat(buf, tmp, len);
- }
- strlcat(buf, "m", len);
- }
+ grid_string_cells_add_code(buf, len, n, s, newc, oldc, nnewc, noldc,
+ escape_c0);
/* If the background colour changed, append its parameters. */
nnewc = grid_string_cells_bg(gc, newc);
noldc = grid_string_cells_bg(lastgc, oldc);
- if (nnewc != noldc ||
- memcmp(newc, oldc, nnewc * sizeof newc[0]) != 0 ||
- (n != 0 && s[0] == 0)) {
- if (escape_c0)
- strlcat(buf, "\\033[", len);
- else
- strlcat(buf, "\033[", len);
- for (i = 0; i < nnewc; i++) {
- if (i + 1 < nnewc)
- xsnprintf(tmp, sizeof tmp, "%d;", newc[i]);
- else
- xsnprintf(tmp, sizeof tmp, "%d", newc[i]);
- strlcat(buf, tmp, len);
- }
- strlcat(buf, "m", len);
- }
+ grid_string_cells_add_code(buf, len, n, s, newc, oldc, nnewc, noldc,
+ escape_c0);
+
+ /* If the underscore colour changed, append its parameters. */
+ nnewc = grid_string_cells_us(gc, newc);
+ noldc = grid_string_cells_us(lastgc, oldc);
+ grid_string_cells_add_code(buf, len, n, s, newc, oldc, nnewc, noldc,
+ escape_c0);
/* Append shift in/shift out if needed. */
if ((attr & GRID_ATTR_CHARSET) && !(lastattr & GRID_ATTR_CHARSET)) {