mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-04 00:56:10 +00:00 
			
		
		
		
	Support for extended underline styles on terminals which offer them,
enabled by adding the Smulx capability with terminal-overrides (add something like ',vte*:Smulx=\E[4\:%p1%dm'). GitHub issue 1492.
This commit is contained in:
		
							
								
								
									
										56
									
								
								attributes.c
									
									
									
									
									
								
							
							
						
						
									
										56
									
								
								attributes.c
									
									
									
									
									
								
							@@ -25,13 +25,13 @@
 | 
				
			|||||||
const char *
 | 
					const char *
 | 
				
			||||||
attributes_tostring(int attr)
 | 
					attributes_tostring(int attr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	static char	buf[128];
 | 
						static char	buf[512];
 | 
				
			||||||
	size_t		len;
 | 
						size_t		len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (attr == 0)
 | 
						if (attr == 0)
 | 
				
			||||||
		return ("none");
 | 
							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_BRIGHT) ? "bright," : "",
 | 
				
			||||||
	    (attr & GRID_ATTR_DIM) ? "dim," : "",
 | 
						    (attr & GRID_ATTR_DIM) ? "dim," : "",
 | 
				
			||||||
	    (attr & GRID_ATTR_UNDERSCORE) ? "underscore," : "",
 | 
						    (attr & GRID_ATTR_UNDERSCORE) ? "underscore," : "",
 | 
				
			||||||
@@ -39,7 +39,11 @@ attributes_tostring(int attr)
 | 
				
			|||||||
	    (attr & GRID_ATTR_REVERSE) ? "reverse," : "",
 | 
						    (attr & GRID_ATTR_REVERSE) ? "reverse," : "",
 | 
				
			||||||
	    (attr & GRID_ATTR_HIDDEN) ? "hidden," : "",
 | 
						    (attr & GRID_ATTR_HIDDEN) ? "hidden," : "",
 | 
				
			||||||
	    (attr & GRID_ATTR_ITALICS) ? "italics," : "",
 | 
						    (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)
 | 
						if (len > 0)
 | 
				
			||||||
		buf[len - 1] = '\0';
 | 
							buf[len - 1] = '\0';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -52,6 +56,25 @@ attributes_fromstring(const char *str)
 | 
				
			|||||||
	const char	delimiters[] = " ,|";
 | 
						const char	delimiters[] = " ,|";
 | 
				
			||||||
	int		attr;
 | 
						int		attr;
 | 
				
			||||||
	size_t		end;
 | 
						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)
 | 
						if (*str == '\0' || strcspn(str, delimiters) == 0)
 | 
				
			||||||
		return (-1);
 | 
							return (-1);
 | 
				
			||||||
@@ -64,24 +87,15 @@ attributes_fromstring(const char *str)
 | 
				
			|||||||
	attr = 0;
 | 
						attr = 0;
 | 
				
			||||||
	do {
 | 
						do {
 | 
				
			||||||
		end = strcspn(str, delimiters);
 | 
							end = strcspn(str, delimiters);
 | 
				
			||||||
		if ((end == 6 && strncasecmp(str, "bright", end) == 0) ||
 | 
							for (i = 0; i < nitems(table); i++) {
 | 
				
			||||||
		    (end == 4 && strncasecmp(str, "bold", end) == 0))
 | 
								if (end != strlen(table[i].name))
 | 
				
			||||||
			attr |= GRID_ATTR_BRIGHT;
 | 
									continue;
 | 
				
			||||||
		else if (end == 3 && strncasecmp(str, "dim", end) == 0)
 | 
								if (strncasecmp(str, table[i].name, end) == 0) {
 | 
				
			||||||
			attr |= GRID_ATTR_DIM;
 | 
									attr |= table[i].attr;
 | 
				
			||||||
		else if (end == 10 && strncasecmp(str, "underscore", end) == 0)
 | 
									break;
 | 
				
			||||||
			attr |= GRID_ATTR_UNDERSCORE;
 | 
								}
 | 
				
			||||||
		else if (end == 5 && strncasecmp(str, "blink", end) == 0)
 | 
							}
 | 
				
			||||||
			attr |= GRID_ATTR_BLINK;
 | 
							if (i == nitems(table))
 | 
				
			||||||
		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
 | 
					 | 
				
			||||||
			return (-1);
 | 
								return (-1);
 | 
				
			||||||
		str += end + strspn(str + end, delimiters);
 | 
							str += end + strspn(str + end, delimiters);
 | 
				
			||||||
	} while (*str != '\0');
 | 
						} while (*str != '\0');
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										16
									
								
								grid.c
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								grid.c
									
									
									
									
									
								
							@@ -764,7 +764,11 @@ grid_string_cells_code(const struct grid_cell *lastgc,
 | 
				
			|||||||
		{ GRID_ATTR_BLINK, 5 },
 | 
							{ GRID_ATTR_BLINK, 5 },
 | 
				
			||||||
		{ GRID_ATTR_REVERSE, 7 },
 | 
							{ GRID_ATTR_REVERSE, 7 },
 | 
				
			||||||
		{ GRID_ATTR_HIDDEN, 8 },
 | 
							{ 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;
 | 
						n = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -790,11 +794,15 @@ grid_string_cells_code(const struct grid_cell *lastgc,
 | 
				
			|||||||
		else
 | 
							else
 | 
				
			||||||
			strlcat(buf, "\033[", len);
 | 
								strlcat(buf, "\033[", len);
 | 
				
			||||||
		for (i = 0; i < n; i++) {
 | 
							for (i = 0; i < n; i++) {
 | 
				
			||||||
			if (i + 1 < n)
 | 
								if (s[i] < 10)
 | 
				
			||||||
				xsnprintf(tmp, sizeof tmp, "%d;", s[i]);
 | 
					 | 
				
			||||||
			else
 | 
					 | 
				
			||||||
				xsnprintf(tmp, sizeof tmp, "%d", s[i]);
 | 
									xsnprintf(tmp, sizeof tmp, "%d", s[i]);
 | 
				
			||||||
 | 
								else {
 | 
				
			||||||
 | 
									xsnprintf(tmp, sizeof tmp, "%d:%d", s[i] / 10,
 | 
				
			||||||
 | 
									    s[i] % 10);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			strlcat(buf, tmp, len);
 | 
								strlcat(buf, tmp, len);
 | 
				
			||||||
 | 
								if (i + 1 < n)
 | 
				
			||||||
 | 
									strlcat(buf, ";", len);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		strlcat(buf, "m", len);
 | 
							strlcat(buf, "m", len);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										46
									
								
								input.c
									
									
									
									
									
								
							
							
						
						
									
										46
									
								
								input.c
									
									
									
									
									
								
							@@ -1835,10 +1835,11 @@ input_csi_dispatch_sgr_rgb(struct input_ctx *ictx, int fgbg, u_int *i)
 | 
				
			|||||||
static void
 | 
					static void
 | 
				
			||||||
input_csi_dispatch_sgr_colon(struct input_ctx *ictx, u_int i)
 | 
					input_csi_dispatch_sgr_colon(struct input_ctx *ictx, u_int i)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	char		*s = ictx->param_list[i].str, *copy, *ptr, *out;
 | 
						struct grid_cell	*gc = &ictx->cell.cell;
 | 
				
			||||||
	int		 p[8];
 | 
						char			*s = ictx->param_list[i].str, *copy, *ptr, *out;
 | 
				
			||||||
	u_int		 n;
 | 
						int			 p[8];
 | 
				
			||||||
	const char	*errstr;
 | 
						u_int			 n;
 | 
				
			||||||
 | 
						const char		*errstr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (n = 0; n < nitems(p); n++)
 | 
						for (n = 0; n < nitems(p); n++)
 | 
				
			||||||
		p[n] = -1;
 | 
							p[n] = -1;
 | 
				
			||||||
@@ -1857,7 +1858,39 @@ input_csi_dispatch_sgr_colon(struct input_ctx *ictx, u_int i)
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	free(copy);
 | 
						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;
 | 
							return;
 | 
				
			||||||
	if (p[1] == -1)
 | 
						if (p[1] == -1)
 | 
				
			||||||
		i = 2;
 | 
							i = 2;
 | 
				
			||||||
@@ -1927,6 +1960,7 @@ input_csi_dispatch_sgr(struct input_ctx *ictx)
 | 
				
			|||||||
			gc->attr |= GRID_ATTR_ITALICS;
 | 
								gc->attr |= GRID_ATTR_ITALICS;
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case 4:
 | 
							case 4:
 | 
				
			||||||
 | 
								gc->attr &= ~GRID_ATTR_ALL_UNDERSCORE;
 | 
				
			||||||
			gc->attr |= GRID_ATTR_UNDERSCORE;
 | 
								gc->attr |= GRID_ATTR_UNDERSCORE;
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case 5:
 | 
							case 5:
 | 
				
			||||||
@@ -1948,7 +1982,7 @@ input_csi_dispatch_sgr(struct input_ctx *ictx)
 | 
				
			|||||||
			gc->attr &= ~GRID_ATTR_ITALICS;
 | 
								gc->attr &= ~GRID_ATTR_ITALICS;
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case 24:
 | 
							case 24:
 | 
				
			||||||
			gc->attr &= ~GRID_ATTR_UNDERSCORE;
 | 
								gc->attr &= ~GRID_ATTR_ALL_UNDERSCORE;
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case 25:
 | 
							case 25:
 | 
				
			||||||
			gc->attr &= ~GRID_ATTR_BLINK;
 | 
								gc->attr &= ~GRID_ATTR_BLINK;
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										11
									
								
								tmux.1
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								tmux.1
									
									
									
									
									
								
							@@ -2769,8 +2769,12 @@ or a comma-delimited list of one or more of:
 | 
				
			|||||||
.Ic reverse ,
 | 
					.Ic reverse ,
 | 
				
			||||||
.Ic hidden ,
 | 
					.Ic hidden ,
 | 
				
			||||||
.Ic italics ,
 | 
					.Ic italics ,
 | 
				
			||||||
 | 
					.Ic strikethrough ,
 | 
				
			||||||
 | 
					.Ic double-underscore
 | 
				
			||||||
 | 
					.Ic curly-underscore
 | 
				
			||||||
 | 
					.Ic dotted-underscore
 | 
				
			||||||
or
 | 
					or
 | 
				
			||||||
.Ic strikethrough
 | 
					.Ic dashed-underscore
 | 
				
			||||||
to turn an attribute on, or an attribute prefixed with
 | 
					to turn an attribute on, or an attribute prefixed with
 | 
				
			||||||
.Ql no
 | 
					.Ql no
 | 
				
			||||||
to turn one off.
 | 
					to turn one off.
 | 
				
			||||||
@@ -4419,6 +4423,11 @@ to change the cursor colour from inside
 | 
				
			|||||||
.Bd -literal -offset indent
 | 
					.Bd -literal -offset indent
 | 
				
			||||||
$ printf '\e033]12;red\e033\e\e'
 | 
					$ printf '\e033]12;red\e033\e\e'
 | 
				
			||||||
.Ed
 | 
					.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
 | 
					.It Em \&Ss , Se
 | 
				
			||||||
Set or reset the cursor style.
 | 
					Set or reset the cursor style.
 | 
				
			||||||
If set, a sequence such as this may be used
 | 
					If set, a sequence such as this may be used
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										13
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								tmux.h
									
									
									
									
									
								
							@@ -421,6 +421,7 @@ enum tty_code_code {
 | 
				
			|||||||
	TTYC_SMCUP,
 | 
						TTYC_SMCUP,
 | 
				
			||||||
	TTYC_SMKX,
 | 
						TTYC_SMKX,
 | 
				
			||||||
	TTYC_SMSO,
 | 
						TTYC_SMSO,
 | 
				
			||||||
 | 
						TTYC_SMULX,
 | 
				
			||||||
	TTYC_SMUL,
 | 
						TTYC_SMUL,
 | 
				
			||||||
	TTYC_SMXX,
 | 
						TTYC_SMXX,
 | 
				
			||||||
	TTYC_SS,
 | 
						TTYC_SS,
 | 
				
			||||||
@@ -546,6 +547,18 @@ enum utf8_state {
 | 
				
			|||||||
#define GRID_ATTR_ITALICS 0x40
 | 
					#define GRID_ATTR_ITALICS 0x40
 | 
				
			||||||
#define GRID_ATTR_CHARSET 0x80	/* alternative character set */
 | 
					#define GRID_ATTR_CHARSET 0x80	/* alternative character set */
 | 
				
			||||||
#define GRID_ATTR_STRIKETHROUGH 0x100
 | 
					#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. */
 | 
					/* Grid flags. */
 | 
				
			||||||
#define GRID_FLAG_FG256 0x1
 | 
					#define GRID_FLAG_FG256 0x1
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										48
									
								
								tty-term.c
									
									
									
									
									
								
							
							
						
						
									
										48
									
								
								tty-term.c
									
									
									
									
									
								
							@@ -253,6 +253,7 @@ static const struct tty_term_code_entry tty_term_codes[] = {
 | 
				
			|||||||
	[TTYC_SMCUP] = { TTYCODE_STRING, "smcup" },
 | 
						[TTYC_SMCUP] = { TTYCODE_STRING, "smcup" },
 | 
				
			||||||
	[TTYC_SMKX] = { TTYCODE_STRING, "smkx" },
 | 
						[TTYC_SMKX] = { TTYCODE_STRING, "smkx" },
 | 
				
			||||||
	[TTYC_SMSO] = { TTYCODE_STRING, "smso" },
 | 
						[TTYC_SMSO] = { TTYCODE_STRING, "smso" },
 | 
				
			||||||
 | 
						[TTYC_SMULX] = { TTYCODE_STRING, "Smulx" },
 | 
				
			||||||
	[TTYC_SMUL] = { TTYCODE_STRING, "smul" },
 | 
						[TTYC_SMUL] = { TTYCODE_STRING, "smul" },
 | 
				
			||||||
	[TTYC_SMXX] =  { TTYCODE_STRING, "smxx" },
 | 
						[TTYC_SMXX] =  { TTYCODE_STRING, "smxx" },
 | 
				
			||||||
	[TTYC_SS] = { TTYCODE_STRING, "Ss" },
 | 
						[TTYC_SS] = { TTYCODE_STRING, "Ss" },
 | 
				
			||||||
@@ -299,25 +300,53 @@ tty_term_strip(const char *s)
 | 
				
			|||||||
	return (xstrdup(buf));
 | 
						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
 | 
					static void
 | 
				
			||||||
tty_term_override(struct tty_term *term, const char *override)
 | 
					tty_term_override(struct tty_term *term, const char *override)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	const struct tty_term_code_entry	*ent;
 | 
						const struct tty_term_code_entry	*ent;
 | 
				
			||||||
	struct tty_code				*code;
 | 
						struct tty_code				*code;
 | 
				
			||||||
	char					*next, *s, *copy, *cp, *value;
 | 
						size_t                                   offset = 0;
 | 
				
			||||||
 | 
						char					*cp, *value, *s;
 | 
				
			||||||
	const char				*errstr;
 | 
						const char				*errstr;
 | 
				
			||||||
	u_int					 i;
 | 
						u_int					 i;
 | 
				
			||||||
	int					 n, remove;
 | 
						int					 n, remove;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	copy = next = xstrdup(override);
 | 
						s = tty_term_override_next(override, &offset);
 | 
				
			||||||
 | 
						if (s == NULL || fnmatch(s, term->name, 0) != 0)
 | 
				
			||||||
	s = strsep(&next, ":");
 | 
					 | 
				
			||||||
	if (s == NULL || next == NULL || fnmatch(s, term->name, 0) != 0) {
 | 
					 | 
				
			||||||
		free(copy);
 | 
					 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	while ((s = strsep(&next, ":")) != NULL) {
 | 
						while ((s = tty_term_override_next(override, &offset)) != NULL) {
 | 
				
			||||||
		if (*s == '\0')
 | 
							if (*s == '\0')
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		value = NULL;
 | 
							value = NULL;
 | 
				
			||||||
@@ -338,6 +367,8 @@ tty_term_override(struct tty_term *term, const char *override)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		if (remove)
 | 
							if (remove)
 | 
				
			||||||
			log_debug("%s override: %s@", term->name, s);
 | 
								log_debug("%s override: %s@", term->name, s);
 | 
				
			||||||
 | 
							else if (*value == '\0')
 | 
				
			||||||
 | 
								log_debug("%s override: %s", term->name, s);
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
			log_debug("%s override: %s=%s", term->name, s, value);
 | 
								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(value);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	free(s);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct tty_term *
 | 
					struct tty_term *
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										15
									
								
								tty.c
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								tty.c
									
									
									
									
									
								
							@@ -1832,8 +1832,19 @@ tty_attributes(struct tty *tty, const struct grid_cell *gc,
 | 
				
			|||||||
		tty_putcode(tty, TTYC_DIM);
 | 
							tty_putcode(tty, TTYC_DIM);
 | 
				
			||||||
	if (changed & GRID_ATTR_ITALICS)
 | 
						if (changed & GRID_ATTR_ITALICS)
 | 
				
			||||||
		tty_set_italics(tty);
 | 
							tty_set_italics(tty);
 | 
				
			||||||
	if (changed & GRID_ATTR_UNDERSCORE)
 | 
						if (changed & GRID_ATTR_ALL_UNDERSCORE) {
 | 
				
			||||||
		tty_putcode(tty, TTYC_SMUL);
 | 
							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)
 | 
						if (changed & GRID_ATTR_BLINK)
 | 
				
			||||||
		tty_putcode(tty, TTYC_BLINK);
 | 
							tty_putcode(tty, TTYC_BLINK);
 | 
				
			||||||
	if (changed & GRID_ATTR_REVERSE) {
 | 
						if (changed & GRID_ATTR_REVERSE) {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user