diff options
-rw-r--r-- | attributes.c | 56 | ||||
-rw-r--r-- | grid.c | 16 | ||||
-rw-r--r-- | input.c | 46 | ||||
-rw-r--r-- | tmux.1 | 11 | ||||
-rw-r--r-- | tmux.h | 13 | ||||
-rw-r--r-- | tty-term.c | 48 | ||||
-rw-r--r-- | tty.c | 15 |
7 files changed, 162 insertions, 43 deletions
diff --git a/attributes.c b/attributes.c index 1e45e584..1b831733 100644 --- a/attributes.c +++ b/attributes.c @@ -25,13 +25,13 @@ const char * attributes_tostring(int attr) { - static char buf[128]; + static char buf[512]; size_t len; if (attr == 0) return ("none"); - len = xsnprintf(buf, sizeof buf, "%s%s%s%s%s%s%s%s", + len = xsnprintf(buf, sizeof buf, "%s%s%s%s%s%s%s%s%s%s%s%s", (attr & GRID_ATTR_BRIGHT) ? "bright," : "", (attr & GRID_ATTR_DIM) ? "dim," : "", (attr & GRID_ATTR_UNDERSCORE) ? "underscore," : "", @@ -39,7 +39,11 @@ attributes_tostring(int attr) (attr & GRID_ATTR_REVERSE) ? "reverse," : "", (attr & GRID_ATTR_HIDDEN) ? "hidden," : "", (attr & GRID_ATTR_ITALICS) ? "italics," : "", - (attr & GRID_ATTR_STRIKETHROUGH) ? "strikethrough," : ""); + (attr & GRID_ATTR_STRIKETHROUGH) ? "strikethrough," : "", + (attr & GRID_ATTR_UNDERSCORE_2) ? "double-underscore," : "", + (attr & GRID_ATTR_UNDERSCORE_3) ? "curly-underscore," : "", + (attr & GRID_ATTR_UNDERSCORE_4) ? "dotted-underscore," : "", + (attr & GRID_ATTR_UNDERSCORE_5) ? "dashed-underscore," : ""); if (len > 0) buf[len - 1] = '\0'; @@ -52,6 +56,25 @@ attributes_fromstring(const char *str) const char delimiters[] = " ,|"; int attr; size_t end; + u_int i; + struct { + const char* name; + int attr; + } table[] = { + { "bright", GRID_ATTR_BRIGHT }, + { "bold", GRID_ATTR_BRIGHT }, + { "dim", GRID_ATTR_DIM }, + { "underscore", GRID_ATTR_UNDERSCORE }, + { "blink", GRID_ATTR_BLINK }, + { "reverse", GRID_ATTR_REVERSE }, + { "hidden", GRID_ATTR_HIDDEN }, + { "italics", GRID_ATTR_ITALICS }, + { "strikethrough", GRID_ATTR_STRIKETHROUGH }, + { "double-underscore", GRID_ATTR_UNDERSCORE_2 }, + { "curly-underscore", GRID_ATTR_UNDERSCORE_3 }, + { "dotted-underscore", GRID_ATTR_UNDERSCORE_4 }, + { "dashed-underscore", GRID_ATTR_UNDERSCORE_5 } + }; if (*str == '\0' || strcspn(str, delimiters) == 0) return (-1); @@ -64,24 +87,15 @@ attributes_fromstring(const char *str) attr = 0; do { end = strcspn(str, delimiters); - if ((end == 6 && strncasecmp(str, "bright", end) == 0) || - (end == 4 && strncasecmp(str, "bold", end) == 0)) - attr |= GRID_ATTR_BRIGHT; - else if (end == 3 && strncasecmp(str, "dim", end) == 0) - attr |= GRID_ATTR_DIM; - else if (end == 10 && strncasecmp(str, "underscore", end) == 0) - attr |= GRID_ATTR_UNDERSCORE; - else if (end == 5 && strncasecmp(str, "blink", end) == 0) - attr |= GRID_ATTR_BLINK; - else if (end == 7 && strncasecmp(str, "reverse", end) == 0) - attr |= GRID_ATTR_REVERSE; - else if (end == 6 && strncasecmp(str, "hidden", end) == 0) - attr |= GRID_ATTR_HIDDEN; - else if (end == 7 && strncasecmp(str, "italics", end) == 0) - attr |= GRID_ATTR_ITALICS; - else if (end == 13 && strncasecmp(str, "strikethrough", end) == 0) - attr |= GRID_ATTR_STRIKETHROUGH; - else + for (i = 0; i < nitems(table); i++) { + if (end != strlen(table[i].name)) + continue; + if (strncasecmp(str, table[i].name, end) == 0) { + attr |= table[i].attr; + break; + } + } + if (i == nitems(table)) return (-1); str += end + strspn(str + end, delimiters); } while (*str != '\0'); @@ -764,7 +764,11 @@ grid_string_cells_code(const struct grid_cell *lastgc, { GRID_ATTR_BLINK, 5 }, { GRID_ATTR_REVERSE, 7 }, { GRID_ATTR_HIDDEN, 8 }, - { GRID_ATTR_STRIKETHROUGH, 9 } + { GRID_ATTR_STRIKETHROUGH, 9 }, + { GRID_ATTR_UNDERSCORE_2, 42 }, + { GRID_ATTR_UNDERSCORE_3, 43 }, + { GRID_ATTR_UNDERSCORE_4, 44 }, + { GRID_ATTR_UNDERSCORE_5, 45 }, }; n = 0; @@ -790,11 +794,15 @@ grid_string_cells_code(const struct grid_cell *lastgc, else strlcat(buf, "\033[", len); for (i = 0; i < n; i++) { - if (i + 1 < n) - xsnprintf(tmp, sizeof tmp, "%d;", s[i]); - else + if (s[i] < 10) xsnprintf(tmp, sizeof tmp, "%d", s[i]); + else { + xsnprintf(tmp, sizeof tmp, "%d:%d", s[i] / 10, + s[i] % 10); + } strlcat(buf, tmp, len); + if (i + 1 < n) + strlcat(buf, ";", len); } strlcat(buf, "m", len); } @@ -1835,10 +1835,11 @@ input_csi_dispatch_sgr_rgb(struct input_ctx *ictx, int fgbg, u_int *i) static void input_csi_dispatch_sgr_colon(struct input_ctx *ictx, u_int i) { - char *s = ictx->param_list[i].str, *copy, *ptr, *out; - int p[8]; - u_int n; - const char *errstr; + struct grid_cell *gc = &ictx->cell.cell; + char *s = ictx->param_list[i].str, *copy, *ptr, *out; + int p[8]; + u_int n; + const char *errstr; for (n = 0; n < nitems(p); n++) p[n] = -1; @@ -1857,7 +1858,39 @@ input_csi_dispatch_sgr_colon(struct input_ctx *ictx, u_int i) } free(copy); - if (n == 0 || (p[0] != 38 && p[0] != 48)) + if (n == 0) + return; + if (p[0] == 4) { + if (n != 2) + return; + switch (p[1]) { + case 0: + gc->attr &= ~GRID_ATTR_ALL_UNDERSCORE; + break; + case 1: + gc->attr &= ~GRID_ATTR_ALL_UNDERSCORE; + gc->attr |= GRID_ATTR_UNDERSCORE; + break; + case 2: + gc->attr &= ~GRID_ATTR_ALL_UNDERSCORE; + gc->attr |= GRID_ATTR_UNDERSCORE_2; + break; + case 3: + gc->attr &= ~GRID_ATTR_ALL_UNDERSCORE; + gc->attr |= GRID_ATTR_UNDERSCORE_3; + break; + case 4: + gc->attr &= ~GRID_ATTR_ALL_UNDERSCORE; + gc->attr |= GRID_ATTR_UNDERSCORE_4; + break; + case 5: + gc->attr &= ~GRID_ATTR_ALL_UNDERSCORE; + gc->attr |= GRID_ATTR_UNDERSCORE_5; + break; + } + return; + } + if (p[0] != 38 && p[0] != 48) return; if (p[1] == -1) i = 2; @@ -1927,6 +1960,7 @@ input_csi_dispatch_sgr(struct input_ctx *ictx) gc->attr |= GRID_ATTR_ITALICS; break; case 4: + gc->attr &= ~GRID_ATTR_ALL_UNDERSCORE; gc->attr |= GRID_ATTR_UNDERSCORE; break; case 5: @@ -1948,7 +1982,7 @@ input_csi_dispatch_sgr(struct input_ctx *ictx) gc->attr &= ~GRID_ATTR_ITALICS; break; case 24: - gc->attr &= ~GRID_ATTR_UNDERSCORE; + gc->attr &= ~GRID_ATTR_ALL_UNDERSCORE; break; case 25: gc->attr &= ~GRID_ATTR_BLINK; @@ -2769,8 +2769,12 @@ or a comma-delimited list of one or more of: .Ic reverse , .Ic hidden , .Ic italics , +.Ic strikethrough , +.Ic double-underscore +.Ic curly-underscore +.Ic dotted-underscore or -.Ic strikethrough +.Ic dashed-underscore to turn an attribute on, or an attribute prefixed with .Ql no to turn one off. @@ -4419,6 +4423,11 @@ to change the cursor colour from inside .Bd -literal -offset indent $ printf '\e033]12;red\e033\e\e' .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. .It Em \&Ss , Se Set or reset the cursor style. If set, a sequence such as this may be used @@ -421,6 +421,7 @@ enum tty_code_code { TTYC_SMCUP, TTYC_SMKX, TTYC_SMSO, + TTYC_SMULX, TTYC_SMUL, TTYC_SMXX, TTYC_SS, @@ -546,6 +547,18 @@ enum utf8_state { #define GRID_ATTR_ITALICS 0x40 #define GRID_ATTR_CHARSET 0x80 /* alternative character set */ #define GRID_ATTR_STRIKETHROUGH 0x100 +#define GRID_ATTR_UNDERSCORE_2 0x200 +#define GRID_ATTR_UNDERSCORE_3 0x400 +#define GRID_ATTR_UNDERSCORE_4 0x800 +#define GRID_ATTR_UNDERSCORE_5 0x1000 + +/* All underscore attributes. */ +#define GRID_ATTR_ALL_UNDERSCORE \ + (GRID_ATTR_UNDERSCORE| \ + GRID_ATTR_UNDERSCORE_2| \ + GRID_ATTR_UNDERSCORE_3| \ + GRID_ATTR_UNDERSCORE_4| \ + GRID_ATTR_UNDERSCORE_5) /* Grid flags. */ #define GRID_FLAG_FG256 0x1 @@ -253,6 +253,7 @@ static const struct tty_term_code_entry tty_term_codes[] = { [TTYC_SMCUP] = { TTYCODE_STRING, "smcup" }, [TTYC_SMKX] = { TTYCODE_STRING, "smkx" }, [TTYC_SMSO] = { TTYCODE_STRING, "smso" }, + [TTYC_SMULX] = { TTYCODE_STRING, "Smulx" }, [TTYC_SMUL] = { TTYCODE_STRING, "smul" }, [TTYC_SMXX] = { TTYCODE_STRING, "smxx" }, [TTYC_SS] = { TTYCODE_STRING, "Ss" }, @@ -299,25 +300,53 @@ tty_term_strip(const char *s) return (xstrdup(buf)); } +static char * +tty_term_override_next(const char *s, size_t *offset) +{ + static char value[BUFSIZ]; + size_t n = 0, at = *offset; + + if (s[at] == '\0') + return (NULL); + + while (s[at] != '\0') { + if (s[at] == ':') { + if (s[at + 1] == ':') { + value[n++] = ':'; + at += 2; + } else + break; + } else { + value[n++] = s[at]; + at++; + } + if (n == (sizeof value) - 1) + return (NULL); + } + if (s[at] != '\0') + *offset = at + 1; + else + *offset = at; + value[n] = '\0'; + return (value); +} + static void tty_term_override(struct tty_term *term, const char *override) { const struct tty_term_code_entry *ent; struct tty_code *code; - char *next, *s, *copy, *cp, *value; + size_t offset = 0; + char *cp, *value, *s; const char *errstr; u_int i; int n, remove; - copy = next = xstrdup(override); - - s = strsep(&next, ":"); - if (s == NULL || next == NULL || fnmatch(s, term->name, 0) != 0) { - free(copy); + s = tty_term_override_next(override, &offset); + if (s == NULL || fnmatch(s, term->name, 0) != 0) return; - } - while ((s = strsep(&next, ":")) != NULL) { + while ((s = tty_term_override_next(override, &offset)) != NULL) { if (*s == '\0') continue; value = NULL; @@ -338,6 +367,8 @@ tty_term_override(struct tty_term *term, const char *override) if (remove) log_debug("%s override: %s@", term->name, s); + else if (*value == '\0') + log_debug("%s override: %s", term->name, s); else log_debug("%s override: %s=%s", term->name, s, value); @@ -376,7 +407,6 @@ tty_term_override(struct tty_term *term, const char *override) free(value); } - free(s); } struct tty_term * @@ -1832,8 +1832,19 @@ tty_attributes(struct tty *tty, const struct grid_cell *gc, tty_putcode(tty, TTYC_DIM); if (changed & GRID_ATTR_ITALICS) tty_set_italics(tty); - if (changed & GRID_ATTR_UNDERSCORE) - tty_putcode(tty, TTYC_SMUL); + if (changed & GRID_ATTR_ALL_UNDERSCORE) { + if ((changed & GRID_ATTR_UNDERSCORE) || + !tty_term_has(tty->term, TTYC_SMULX)) + tty_putcode(tty, TTYC_SMUL); + else if (changed & GRID_ATTR_UNDERSCORE_2) + tty_putcode1(tty, TTYC_SMULX, 2); + else if (changed & GRID_ATTR_UNDERSCORE_3) + tty_putcode1(tty, TTYC_SMULX, 3); + else if (changed & GRID_ATTR_UNDERSCORE_4) + tty_putcode1(tty, TTYC_SMULX, 4); + else if (changed & GRID_ATTR_UNDERSCORE_5) + tty_putcode1(tty, TTYC_SMULX, 5); + } if (changed & GRID_ATTR_BLINK) tty_putcode(tty, TTYC_BLINK); if (changed & GRID_ATTR_REVERSE) { |