mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-04 09:44:18 +00:00 
			
		
		
		
	Check the terminfo(5) U8 capability and disable using UTF-8 for ACS if
it is present and zero. This is useful for users with terminals or fonts that do not correctly support UTF-8 line drawing characters. GitHub issue 927, reported by Hiroaki Yamazoe and Akinori Hattori.
This commit is contained in:
		
							
								
								
									
										2
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								tmux.h
									
									
									
									
									
								
							@@ -401,6 +401,7 @@ enum tty_code_code {
 | 
				
			|||||||
	TTYC_SS,	/* set cursor style, Ss */
 | 
						TTYC_SS,	/* set cursor style, Ss */
 | 
				
			||||||
	TTYC_TC,	/* 24-bit "true" colour, Tc */
 | 
						TTYC_TC,	/* 24-bit "true" colour, Tc */
 | 
				
			||||||
	TTYC_TSL,	/* to_status_line, tsl */
 | 
						TTYC_TSL,	/* to_status_line, tsl */
 | 
				
			||||||
 | 
						TTYC_U8,
 | 
				
			||||||
	TTYC_VPA,	/* row_address, cv */
 | 
						TTYC_VPA,	/* row_address, cv */
 | 
				
			||||||
	TTYC_XENL,	/* eat_newline_glitch, xn */
 | 
						TTYC_XENL,	/* eat_newline_glitch, xn */
 | 
				
			||||||
	TTYC_XT,	/* xterm(1)-compatible title, XT */
 | 
						TTYC_XT,	/* xterm(1)-compatible title, XT */
 | 
				
			||||||
@@ -1701,6 +1702,7 @@ int		 tty_term_flag(struct tty_term *, enum tty_code_code);
 | 
				
			|||||||
const char	*tty_term_describe(struct tty_term *, enum tty_code_code);
 | 
					const char	*tty_term_describe(struct tty_term *, enum tty_code_code);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* tty-acs.c */
 | 
					/* tty-acs.c */
 | 
				
			||||||
 | 
					int		 tty_acs_needed(struct tty *);
 | 
				
			||||||
const char	*tty_acs_get(struct tty *, u_char);
 | 
					const char	*tty_acs_get(struct tty *, u_char);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* tty-keys.c */
 | 
					/* tty-keys.c */
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										37
									
								
								tty-acs.c
									
									
									
									
									
								
							
							
						
						
									
										37
									
								
								tty-acs.c
									
									
									
									
									
								
							@@ -74,23 +74,48 @@ tty_acs_cmp(const void *key, const void *value)
 | 
				
			|||||||
	return (ch - entry->key);
 | 
						return (ch - entry->key);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Should this terminal use ACS instead of UTF-8 line drawing? */
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					tty_acs_needed(struct tty *tty)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (tty == NULL)
 | 
				
			||||||
 | 
							return (0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * If the U8 flag is present, it marks whether a terminal supports
 | 
				
			||||||
 | 
						 * UTF-8 and ACS together.
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * If it is present and zero, we force ACS - this gives users a way to
 | 
				
			||||||
 | 
						 * turn off UTF-8 line drawing.
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * If it is nonzero, we can fall through to the default and use UTF-8
 | 
				
			||||||
 | 
						 * line drawing on UTF-8 terminals.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						if (tty_term_has(tty->term, TTYC_U8) &&
 | 
				
			||||||
 | 
						    tty_term_number(tty->term, TTYC_U8) == 0)
 | 
				
			||||||
 | 
							return (1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (tty->flags & TTY_UTF8)
 | 
				
			||||||
 | 
							return (0);
 | 
				
			||||||
 | 
						return (1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Retrieve ACS to output as a string. */
 | 
					/* Retrieve ACS to output as a string. */
 | 
				
			||||||
const char *
 | 
					const char *
 | 
				
			||||||
tty_acs_get(struct tty *tty, u_char ch)
 | 
					tty_acs_get(struct tty *tty, u_char ch)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct tty_acs_entry *entry;
 | 
						struct tty_acs_entry	*entry;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* If not a UTF-8 terminal, use the ACS set. */
 | 
						/* Use the ACS set instead of UTF-8 if needed. */
 | 
				
			||||||
	if (tty != NULL && !(tty->flags & TTY_UTF8)) {
 | 
						if (tty_acs_needed(tty)) {
 | 
				
			||||||
		if (tty->term->acs[ch][0] == '\0')
 | 
							if (tty->term->acs[ch][0] == '\0')
 | 
				
			||||||
			return (NULL);
 | 
								return (NULL);
 | 
				
			||||||
		return (&tty->term->acs[ch][0]);
 | 
							return (&tty->term->acs[ch][0]);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Otherwise look up the UTF-8 translation. */
 | 
						/* Otherwise look up the UTF-8 translation. */
 | 
				
			||||||
	entry = bsearch(&ch,
 | 
						entry = bsearch(&ch, tty_acs_table, nitems(tty_acs_table),
 | 
				
			||||||
	    tty_acs_table, nitems(tty_acs_table), sizeof tty_acs_table[0],
 | 
						    sizeof tty_acs_table[0], tty_acs_cmp);
 | 
				
			||||||
	    tty_acs_cmp);
 | 
					 | 
				
			||||||
	if (entry == NULL)
 | 
						if (entry == NULL)
 | 
				
			||||||
		return (NULL);
 | 
							return (NULL);
 | 
				
			||||||
	return (entry->string);
 | 
						return (entry->string);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -254,6 +254,7 @@ static const struct tty_term_code_entry tty_term_codes[] = {
 | 
				
			|||||||
	[TTYC_TC] = { TTYCODE_FLAG, "Tc" },
 | 
						[TTYC_TC] = { TTYCODE_FLAG, "Tc" },
 | 
				
			||||||
	[TTYC_TSL] = { TTYCODE_STRING, "tsl" },
 | 
						[TTYC_TSL] = { TTYCODE_STRING, "tsl" },
 | 
				
			||||||
	[TTYC_VPA] = { TTYCODE_STRING, "vpa" },
 | 
						[TTYC_VPA] = { TTYCODE_STRING, "vpa" },
 | 
				
			||||||
 | 
						[TTYC_U8] = { TTYCODE_NUMBER, "U8" },
 | 
				
			||||||
	[TTYC_XENL] = { TTYCODE_FLAG, "xenl" },
 | 
						[TTYC_XENL] = { TTYCODE_FLAG, "xenl" },
 | 
				
			||||||
	[TTYC_XT] = { TTYCODE_FLAG, "XT" },
 | 
						[TTYC_XT] = { TTYCODE_FLAG, "XT" },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										19
									
								
								tty.c
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								tty.c
									
									
									
									
									
								
							@@ -71,8 +71,6 @@ static void	tty_default_colours(struct grid_cell *,
 | 
				
			|||||||
static void	tty_default_attributes(struct tty *, const struct window_pane *,
 | 
					static void	tty_default_attributes(struct tty *, const struct window_pane *,
 | 
				
			||||||
		    u_int);
 | 
							    u_int);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define tty_use_acs(tty) \
 | 
					 | 
				
			||||||
	(tty_term_has((tty)->term, TTYC_ACSC) && !((tty)->flags & TTY_UTF8))
 | 
					 | 
				
			||||||
#define tty_use_margin(tty) \
 | 
					#define tty_use_margin(tty) \
 | 
				
			||||||
	((tty)->term_type == TTY_VT420)
 | 
						((tty)->term_type == TTY_VT420)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -278,7 +276,8 @@ tty_open(struct tty *tty, char **cause)
 | 
				
			|||||||
void
 | 
					void
 | 
				
			||||||
tty_start_tty(struct tty *tty)
 | 
					tty_start_tty(struct tty *tty)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct termios	tio;
 | 
						struct client	*c = tty->client;
 | 
				
			||||||
 | 
						struct termios	 tio;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (tty->fd != -1 && tcgetattr(tty->fd, &tty->tio) == 0) {
 | 
						if (tty->fd != -1 && tcgetattr(tty->fd, &tty->tio) == 0) {
 | 
				
			||||||
		setblocking(tty->fd, 0);
 | 
							setblocking(tty->fd, 0);
 | 
				
			||||||
@@ -299,10 +298,14 @@ tty_start_tty(struct tty *tty)
 | 
				
			|||||||
	tty_putcode(tty, TTYC_SMCUP);
 | 
						tty_putcode(tty, TTYC_SMCUP);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tty_putcode(tty, TTYC_SMKX);
 | 
						tty_putcode(tty, TTYC_SMKX);
 | 
				
			||||||
	if (tty_use_acs(tty))
 | 
					 | 
				
			||||||
		tty_putcode(tty, TTYC_ENACS);
 | 
					 | 
				
			||||||
	tty_putcode(tty, TTYC_CLEAR);
 | 
						tty_putcode(tty, TTYC_CLEAR);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (tty_acs_needed(tty)) {
 | 
				
			||||||
 | 
							log_debug("%s: using capabilities for ACS", c->name);
 | 
				
			||||||
 | 
							tty_putcode(tty, TTYC_ENACS);
 | 
				
			||||||
 | 
						} else
 | 
				
			||||||
 | 
							log_debug("%s: using UTF-8 for ACS", c->name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tty_putcode(tty, TTYC_CNORM);
 | 
						tty_putcode(tty, TTYC_CNORM);
 | 
				
			||||||
	if (tty_term_has(tty->term, TTYC_KMOUS))
 | 
						if (tty_term_has(tty->term, TTYC_KMOUS))
 | 
				
			||||||
		tty_puts(tty, "\033[?1000l\033[?1002l\033[?1006l\033[?1005l");
 | 
							tty_puts(tty, "\033[?1000l\033[?1002l\033[?1006l\033[?1005l");
 | 
				
			||||||
@@ -351,7 +354,7 @@ tty_stop_tty(struct tty *tty)
 | 
				
			|||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tty_raw(tty, tty_term_string2(tty->term, TTYC_CSR, 0, ws.ws_row - 1));
 | 
						tty_raw(tty, tty_term_string2(tty->term, TTYC_CSR, 0, ws.ws_row - 1));
 | 
				
			||||||
	if (tty_use_acs(tty))
 | 
						if (tty_acs_needed(tty))
 | 
				
			||||||
		tty_raw(tty, tty_term_string(tty->term, TTYC_RMACS));
 | 
							tty_raw(tty, tty_term_string(tty->term, TTYC_RMACS));
 | 
				
			||||||
	tty_raw(tty, tty_term_string(tty->term, TTYC_SGR0));
 | 
						tty_raw(tty, tty_term_string(tty->term, TTYC_SGR0));
 | 
				
			||||||
	tty_raw(tty, tty_term_string(tty->term, TTYC_RMKX));
 | 
						tty_raw(tty, tty_term_string(tty->term, TTYC_RMKX));
 | 
				
			||||||
@@ -1417,7 +1420,7 @@ tty_reset(struct tty *tty)
 | 
				
			|||||||
	struct grid_cell	*gc = &tty->cell;
 | 
						struct grid_cell	*gc = &tty->cell;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!grid_cells_equal(gc, &grid_default_cell)) {
 | 
						if (!grid_cells_equal(gc, &grid_default_cell)) {
 | 
				
			||||||
		if ((gc->attr & GRID_ATTR_CHARSET) && tty_use_acs(tty))
 | 
							if ((gc->attr & GRID_ATTR_CHARSET) && tty_acs_needed(tty))
 | 
				
			||||||
			tty_putcode(tty, TTYC_RMACS);
 | 
								tty_putcode(tty, TTYC_RMACS);
 | 
				
			||||||
		tty_putcode(tty, TTYC_SGR0);
 | 
							tty_putcode(tty, TTYC_SGR0);
 | 
				
			||||||
		memcpy(gc, &grid_default_cell, sizeof *gc);
 | 
							memcpy(gc, &grid_default_cell, sizeof *gc);
 | 
				
			||||||
@@ -1767,7 +1770,7 @@ tty_attributes(struct tty *tty, const struct grid_cell *gc,
 | 
				
			|||||||
		tty_putcode(tty, TTYC_INVIS);
 | 
							tty_putcode(tty, TTYC_INVIS);
 | 
				
			||||||
	if (changed & GRID_ATTR_STRIKETHROUGH)
 | 
						if (changed & GRID_ATTR_STRIKETHROUGH)
 | 
				
			||||||
		tty_putcode(tty, TTYC_SMXX);
 | 
							tty_putcode(tty, TTYC_SMXX);
 | 
				
			||||||
	if ((changed & GRID_ATTR_CHARSET) && tty_use_acs(tty))
 | 
						if ((changed & GRID_ATTR_CHARSET) && tty_acs_needed(tty))
 | 
				
			||||||
		tty_putcode(tty, TTYC_SMACS);
 | 
							tty_putcode(tty, TTYC_SMACS);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user