mirror of
				https://github.com/tmux/tmux.git
				synced 2025-10-26 12:27:15 +00:00 
			
		
		
		
	Support for extended underline styles, 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); | ||||||
| 	} | 	} | ||||||
|   | |||||||
							
								
								
									
										38
									
								
								input.c
									
									
									
									
									
								
							
							
						
						
									
										38
									
								
								input.c
									
									
									
									
									
								
							| @@ -1835,6 +1835,7 @@ 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) | ||||||
| { | { | ||||||
|  | 	struct grid_cell	*gc = &ictx->cell.cell; | ||||||
| 	char			*s = ictx->param_list[i].str, *copy, *ptr, *out; | 	char			*s = ictx->param_list[i].str, *copy, *ptr, *out; | ||||||
| 	int			 p[8]; | 	int			 p[8]; | ||||||
| 	u_int			 n; | 	u_int			 n; | ||||||
| @@ -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
									
									
									
									
									
								
							| @@ -2857,8 +2857,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. | ||||||
| @@ -4525,6 +4529,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
									
									
									
									
									
								
							| @@ -429,6 +429,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, | ||||||
| @@ -554,6 +555,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 | ||||||
|   | |||||||
							
								
								
									
										45
									
								
								tty-term.c
									
									
									
									
									
								
							
							
						
						
									
										45
									
								
								tty-term.c
									
									
									
									
									
								
							| @@ -256,6 +256,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" }, | ||||||
| @@ -302,25 +303,50 @@ 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' && s[at] != ':') { | ||||||
|  | 		if (s[at] == '\\' && s[at + 1] == ':') { | ||||||
|  | 			value[n++] = ':'; | ||||||
|  | 			at += 2; | ||||||
|  | 		} 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; | ||||||
| @@ -341,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); | ||||||
|  |  | ||||||
| @@ -379,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 * | ||||||
|   | |||||||
							
								
								
									
										13
									
								
								tty.c
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								tty.c
									
									
									
									
									
								
							| @@ -2163,8 +2163,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) { | ||||||
|  | 		if ((changed & GRID_ATTR_UNDERSCORE) || | ||||||
|  | 		    !tty_term_has(tty->term, TTYC_SMULX)) | ||||||
| 			tty_putcode(tty, TTYC_SMUL); | 			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
	 Nicholas Marriott
					Nicholas Marriott