mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-04 00:56:10 +00:00 
			
		
		
		
	Support xterm(1) cursor colour change sequences through terminfo(5) Cc
(set) and Cr (reset) extensions. Originally by Sean Estabrooks, tweaked by me and Ailin Nemui.
This commit is contained in:
		
							
								
								
									
										36
									
								
								input.c
									
									
									
									
									
								
							
							
						
						
									
										36
									
								
								input.c
									
									
									
									
									
								
							@@ -1445,17 +1445,39 @@ input_enter_osc(struct input_ctx *ictx)
 | 
			
		||||
void
 | 
			
		||||
input_exit_osc(struct input_ctx *ictx)
 | 
			
		||||
{
 | 
			
		||||
	u_char *p = ictx->input_buf;
 | 
			
		||||
	int	option;
 | 
			
		||||
 | 
			
		||||
	if (ictx->flags & INPUT_DISCARD)
 | 
			
		||||
		return;
 | 
			
		||||
	log_debug("%s: \"%s\"", __func__, ictx->input_buf);
 | 
			
		||||
 | 
			
		||||
	if (ictx->input_len < 2 || ictx->input_buf[1] != ';')
 | 
			
		||||
		return;
 | 
			
		||||
	if (ictx->input_buf[0] != '0' && ictx->input_buf[0] != '2')
 | 
			
		||||
	if (ictx->input_len < 1 || *p < '0' || *p > '9')
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	screen_set_title(ictx->ctx.s, ictx->input_buf + 2);
 | 
			
		||||
	server_status_window(ictx->wp->window);
 | 
			
		||||
	log_debug("%s: \"%s\"", __func__, p);
 | 
			
		||||
 | 
			
		||||
	option = 0;
 | 
			
		||||
	while (*p >= '0' && *p <= '9')
 | 
			
		||||
		option = option * 10 + *p++ - '0';
 | 
			
		||||
	if (*p == ';')
 | 
			
		||||
		p++;
 | 
			
		||||
 | 
			
		||||
	switch (option) {
 | 
			
		||||
	case 0:
 | 
			
		||||
	case 2:
 | 
			
		||||
		screen_set_title(ictx->ctx.s, p);
 | 
			
		||||
		server_status_window(ictx->wp->window);
 | 
			
		||||
		break;
 | 
			
		||||
	case 12:
 | 
			
		||||
		screen_set_cursor_colour(ictx->ctx.s, p);
 | 
			
		||||
		break;
 | 
			
		||||
	case 112:
 | 
			
		||||
		if (*p == '\0') /* No arguments allowed. */
 | 
			
		||||
			screen_set_cursor_colour(ictx->ctx.s, "");
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		log_debug("%s: unknown '%u'", __func__, option);
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* APC string started. */
 | 
			
		||||
 
 | 
			
		||||
@@ -366,13 +366,14 @@ const struct options_table_entry session_options_table[] = {
 | 
			
		||||
	{ .name = "terminal-overrides",
 | 
			
		||||
	  .type = OPTIONS_TABLE_STRING,
 | 
			
		||||
	  .default_str = "*88col*:colors=88,*256col*:colors=256"
 | 
			
		||||
	  		 ",xterm*:XT:Ms=\\E]52;%p1%s;%p2%s\\007"
 | 
			
		||||
	                 ",xterm*:XT:Ms=\\E]52;%p1%s;%p2%s\\007"
 | 
			
		||||
	                 ":Cc=\\E]12;%p1%s\\007:Cr=\\E]112\\007"
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	{ .name = "update-environment",
 | 
			
		||||
	  .type = OPTIONS_TABLE_STRING,
 | 
			
		||||
	  .default_str = "DISPLAY SSH_ASKPASS SSH_AUTH_SOCK SSH_AGENT_PID "
 | 
			
		||||
	                    "SSH_CONNECTION WINDOWID XAUTHORITY"
 | 
			
		||||
	                 "SSH_CONNECTION WINDOWID XAUTHORITY"
 | 
			
		||||
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										10
									
								
								screen.c
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								screen.c
									
									
									
									
									
								
							@@ -40,6 +40,7 @@ screen_init(struct screen *s, u_int sx, u_int sy, u_int hlimit)
 | 
			
		||||
	else
 | 
			
		||||
		s->title = xstrdup("");
 | 
			
		||||
 | 
			
		||||
	s->ccolour = xstrdup("");
 | 
			
		||||
	s->tabs = NULL;
 | 
			
		||||
 | 
			
		||||
	screen_reinit(s);
 | 
			
		||||
@@ -71,6 +72,7 @@ screen_free(struct screen *s)
 | 
			
		||||
	if (s->tabs != NULL)
 | 
			
		||||
		xfree(s->tabs);
 | 
			
		||||
	xfree(s->title);
 | 
			
		||||
	xfree(s->ccolour);
 | 
			
		||||
	grid_destroy(s->grid);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -89,6 +91,14 @@ screen_reset_tabs(struct screen *s)
 | 
			
		||||
		bit_set(s->tabs, i);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Set screen cursor colour. */
 | 
			
		||||
void
 | 
			
		||||
screen_set_cursor_colour(struct screen *s, const char *colour_string)
 | 
			
		||||
{
 | 
			
		||||
	xfree(s->ccolour);
 | 
			
		||||
	s->ccolour = xstrdup(colour_string);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Set screen title. */
 | 
			
		||||
void
 | 
			
		||||
screen_set_title(struct screen *s, const char *title)
 | 
			
		||||
 
 | 
			
		||||
@@ -521,7 +521,7 @@ server_client_reset_state(struct client *c)
 | 
			
		||||
		mode &= ~MODE_MOUSE_UTF8;
 | 
			
		||||
 | 
			
		||||
	/* Set the terminal mode and reset attributes. */
 | 
			
		||||
	tty_update_mode(&c->tty, mode);
 | 
			
		||||
	tty_update_mode(&c->tty, mode, s);
 | 
			
		||||
	tty_reset(&c->tty);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										9
									
								
								tmux.1
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								tmux.1
									
									
									
									
									
								
							@@ -2832,6 +2832,15 @@ See the
 | 
			
		||||
option above and the
 | 
			
		||||
.Xr xterm 1
 | 
			
		||||
man page.
 | 
			
		||||
.It Em Cc, Cr
 | 
			
		||||
The first takes one string argument and is used to set the cursor colour;
 | 
			
		||||
the second takes no arguments and restores the default cursor colour.
 | 
			
		||||
If they present, a sequence such as this may be used to change the
 | 
			
		||||
cursor colour from inside
 | 
			
		||||
.Nm :
 | 
			
		||||
.Bd -literal -offset indent
 | 
			
		||||
$ printf '\e033]12;red\e033\e\e'
 | 
			
		||||
.Ed
 | 
			
		||||
.El
 | 
			
		||||
.Sh FILES
 | 
			
		||||
.Bl -tag -width "/etc/tmux.confXXX" -compact
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										12
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								tmux.h
									
									
									
									
									
								
							@@ -183,10 +183,12 @@ enum tty_code_code {
 | 
			
		||||
	TTYC_BEL,	/* bell, bl */
 | 
			
		||||
	TTYC_BLINK,	/* enter_blink_mode, mb */
 | 
			
		||||
	TTYC_BOLD,	/* enter_bold_mode, md */
 | 
			
		||||
	TTYC_CC,	/* set colour cursor, Cc */
 | 
			
		||||
	TTYC_CIVIS,	/* cursor_invisible, vi */
 | 
			
		||||
	TTYC_CLEAR,	/* clear_screen, cl */
 | 
			
		||||
	TTYC_CNORM,	/* cursor_normal, ve */
 | 
			
		||||
	TTYC_COLORS,	/* max_colors, Co */
 | 
			
		||||
	TTYC_CR,	/* restore cursor colour, Cr */
 | 
			
		||||
	TTYC_CSR,	/* change_scroll_region, cs */
 | 
			
		||||
	TTYC_CUB,	/* parm_left_cursor, LE */
 | 
			
		||||
	TTYC_CUB1,	/* cursor_left, le */
 | 
			
		||||
@@ -714,6 +716,8 @@ struct screen {
 | 
			
		||||
	u_int		 cx;		/* cursor x */
 | 
			
		||||
	u_int		 cy;		/* cursor y */
 | 
			
		||||
 | 
			
		||||
	char		*ccolour;	/* cursor colour string */
 | 
			
		||||
 | 
			
		||||
	u_int		 rupper;	/* scroll region top */
 | 
			
		||||
	u_int		 rlower;	/* scroll region bottom */
 | 
			
		||||
 | 
			
		||||
@@ -1010,6 +1014,7 @@ struct tty {
 | 
			
		||||
 | 
			
		||||
	u_int		 cx;
 | 
			
		||||
	u_int		 cy;
 | 
			
		||||
	char		*ccolour;
 | 
			
		||||
 | 
			
		||||
	int		 mode;
 | 
			
		||||
 | 
			
		||||
@@ -1414,6 +1419,7 @@ void	tty_cursor(struct tty *, u_int, u_int);
 | 
			
		||||
void	tty_putcode(struct tty *, enum tty_code_code);
 | 
			
		||||
void	tty_putcode1(struct tty *, enum tty_code_code, int);
 | 
			
		||||
void	tty_putcode2(struct tty *, enum tty_code_code, int, int);
 | 
			
		||||
void	tty_putcode_ptr1(struct tty *, enum tty_code_code, const void *);
 | 
			
		||||
void	tty_putcode_ptr2(struct tty *, enum tty_code_code, const void *, const void *);
 | 
			
		||||
void	tty_puts(struct tty *, const char *);
 | 
			
		||||
void	tty_putc(struct tty *, u_char);
 | 
			
		||||
@@ -1423,7 +1429,8 @@ int	tty_resize(struct tty *);
 | 
			
		||||
void	tty_start_tty(struct tty *);
 | 
			
		||||
void	tty_stop_tty(struct tty *);
 | 
			
		||||
void	tty_set_title(struct tty *, const char *);
 | 
			
		||||
void	tty_update_mode(struct tty *, int);
 | 
			
		||||
void	tty_update_mode(struct tty *, int, struct screen *);
 | 
			
		||||
void	tty_force_cursor_colour(struct tty *, const char *);
 | 
			
		||||
void	tty_draw_line(struct tty *, struct screen *, u_int, u_int, u_int);
 | 
			
		||||
int	tty_open(struct tty *, const char *, char **);
 | 
			
		||||
void	tty_close(struct tty *);
 | 
			
		||||
@@ -1459,6 +1466,8 @@ const char	*tty_term_string(struct tty_term *, enum tty_code_code);
 | 
			
		||||
const char	*tty_term_string1(struct tty_term *, enum tty_code_code, int);
 | 
			
		||||
const char	*tty_term_string2(
 | 
			
		||||
		     struct tty_term *, enum tty_code_code, int, int);
 | 
			
		||||
const char	*tty_term_ptr1(
 | 
			
		||||
		     struct tty_term *, enum tty_code_code, const void *);
 | 
			
		||||
const char	*tty_term_ptr2(
 | 
			
		||||
		     struct tty_term *, enum tty_code_code, const void *, const void *);
 | 
			
		||||
int		 tty_term_number(struct tty_term *, enum tty_code_code);
 | 
			
		||||
@@ -1841,6 +1850,7 @@ void	 screen_init(struct screen *, u_int, u_int, u_int);
 | 
			
		||||
void	 screen_reinit(struct screen *);
 | 
			
		||||
void	 screen_free(struct screen *);
 | 
			
		||||
void	 screen_reset_tabs(struct screen *);
 | 
			
		||||
void	 screen_set_cursor_colour(struct screen *, const char *);
 | 
			
		||||
void	 screen_set_title(struct screen *, const char *);
 | 
			
		||||
void	 screen_resize(struct screen *, u_int, u_int);
 | 
			
		||||
void	 screen_set_selection(struct screen *,
 | 
			
		||||
 
 | 
			
		||||
@@ -38,10 +38,12 @@ const struct tty_term_code_entry tty_term_codes[NTTYCODE] = {
 | 
			
		||||
	{ TTYC_BEL, TTYCODE_STRING, "bel" },
 | 
			
		||||
	{ TTYC_BLINK, TTYCODE_STRING, "blink" },
 | 
			
		||||
	{ TTYC_BOLD, TTYCODE_STRING, "bold" },
 | 
			
		||||
	{ TTYC_CC, TTYCODE_STRING, "Cc" },
 | 
			
		||||
	{ TTYC_CIVIS, TTYCODE_STRING, "civis" },
 | 
			
		||||
	{ TTYC_CLEAR, TTYCODE_STRING, "clear" },
 | 
			
		||||
	{ TTYC_CNORM, TTYCODE_STRING, "cnorm" },
 | 
			
		||||
	{ TTYC_COLORS, TTYCODE_NUMBER, "colors" },
 | 
			
		||||
	{ TTYC_CR, TTYCODE_STRING, "Cr" },
 | 
			
		||||
	{ TTYC_CSR, TTYCODE_STRING, "csr" },
 | 
			
		||||
	{ TTYC_CUB, TTYCODE_STRING, "cub" },
 | 
			
		||||
	{ TTYC_CUB1, TTYCODE_STRING, "cub1" },
 | 
			
		||||
@@ -493,6 +495,12 @@ tty_term_string2(struct tty_term *term, enum tty_code_code code, int a, int b)
 | 
			
		||||
	return (tparm((char *) tty_term_string(term, code), a, b));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char *
 | 
			
		||||
tty_term_ptr1(struct tty_term *term, enum tty_code_code code, const void *a)
 | 
			
		||||
{
 | 
			
		||||
	return (tparm((char *) tty_term_string(term, code), a));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char *
 | 
			
		||||
tty_term_ptr2(struct tty_term *term, enum tty_code_code code, const void *a, const void *b)
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										34
									
								
								tty.c
									
									
									
									
									
								
							
							
						
						
									
										34
									
								
								tty.c
									
									
									
									
									
								
							@@ -69,6 +69,7 @@ tty_init(struct tty *tty, int fd, char *term)
 | 
			
		||||
	if ((path = ttyname(fd)) == NULL)
 | 
			
		||||
		fatalx("ttyname failed");
 | 
			
		||||
	tty->path = xstrdup(path);
 | 
			
		||||
	tty->ccolour = xstrdup("");
 | 
			
		||||
 | 
			
		||||
	tty->flags = 0;
 | 
			
		||||
	tty->term_flags = 0;
 | 
			
		||||
@@ -210,6 +211,8 @@ tty_start_tty(struct tty *tty)
 | 
			
		||||
	tty->mode = MODE_CURSOR;
 | 
			
		||||
 | 
			
		||||
	tty->flags |= TTY_STARTED;
 | 
			
		||||
 | 
			
		||||
	tty_force_cursor_colour(tty, "");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -241,6 +244,7 @@ tty_stop_tty(struct tty *tty)
 | 
			
		||||
	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_CLEAR));
 | 
			
		||||
	tty_raw(tty, tty_term_string(tty->term, TTYC_CR));
 | 
			
		||||
 | 
			
		||||
	tty_raw(tty, tty_term_string(tty->term, TTYC_CNORM));
 | 
			
		||||
	if (tty_term_has(tty->term, TTYC_KMOUS))
 | 
			
		||||
@@ -280,6 +284,7 @@ tty_free(struct tty *tty)
 | 
			
		||||
{
 | 
			
		||||
	tty_close(tty);
 | 
			
		||||
 | 
			
		||||
	xfree(tty->ccolour);
 | 
			
		||||
	if (tty->path != NULL)
 | 
			
		||||
		xfree(tty->path);
 | 
			
		||||
	if (tty->termname != NULL)
 | 
			
		||||
@@ -314,6 +319,13 @@ tty_putcode2(struct tty *tty, enum tty_code_code code, int a, int b)
 | 
			
		||||
	tty_puts(tty, tty_term_string2(tty->term, code, a, b));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
tty_putcode_ptr1(struct tty *tty, enum tty_code_code code, const void *a)
 | 
			
		||||
{
 | 
			
		||||
	if (a != NULL)
 | 
			
		||||
		tty_puts(tty, tty_term_ptr1(tty->term, code, a));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
tty_putcode_ptr2(struct tty *tty, enum tty_code_code code, const void *a, const void *b)
 | 
			
		||||
{
 | 
			
		||||
@@ -389,10 +401,24 @@ tty_set_title(struct tty *tty, const char *title)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
tty_update_mode(struct tty *tty, int mode)
 | 
			
		||||
tty_force_cursor_colour(struct tty *tty, const char *ccolour)
 | 
			
		||||
{
 | 
			
		||||
	if (*ccolour == '\0')
 | 
			
		||||
		tty_putcode(tty, TTYC_CR);
 | 
			
		||||
	else
 | 
			
		||||
		tty_putcode_ptr1(tty, TTYC_CC, ccolour);
 | 
			
		||||
	xfree(tty->ccolour);
 | 
			
		||||
	tty->ccolour = xstrdup(ccolour);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
tty_update_mode(struct tty *tty, int mode, struct screen *s)
 | 
			
		||||
{
 | 
			
		||||
	int	changed;
 | 
			
		||||
 | 
			
		||||
	if (strcmp(s->ccolour, tty->ccolour))
 | 
			
		||||
		tty_force_cursor_colour(tty, s->ccolour);
 | 
			
		||||
 | 
			
		||||
	if (tty->flags & TTY_NOCURSOR)
 | 
			
		||||
		mode &= ~MODE_CURSOR;
 | 
			
		||||
 | 
			
		||||
@@ -486,7 +512,7 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy)
 | 
			
		||||
	const struct grid_utf8	*gu;
 | 
			
		||||
	u_int			 i, sx;
 | 
			
		||||
 | 
			
		||||
	tty_update_mode(tty, tty->mode & ~MODE_CURSOR);
 | 
			
		||||
	tty_update_mode(tty, tty->mode & ~MODE_CURSOR, s);
 | 
			
		||||
 | 
			
		||||
	sx = screen_size_x(s);
 | 
			
		||||
	if (sx > s->grid->linedata[s->grid->hsize + py].cellsize)
 | 
			
		||||
@@ -526,7 +552,7 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (sx >= tty->sx) {
 | 
			
		||||
		tty_update_mode(tty, tty->mode);
 | 
			
		||||
		tty_update_mode(tty, tty->mode, s);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	tty_reset(tty);
 | 
			
		||||
@@ -538,7 +564,7 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy)
 | 
			
		||||
		for (i = sx; i < screen_size_x(s); i++)
 | 
			
		||||
			tty_putc(tty, ' ');
 | 
			
		||||
	}
 | 
			
		||||
	tty_update_mode(tty, tty->mode);
 | 
			
		||||
	tty_update_mode(tty, tty->mode, s);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user