mirror of
				https://github.com/tmux/tmux.git
				synced 2025-10-26 12:27:15 +00:00 
			
		
		
		
	Merge branch 'obsd-master' into master
This commit is contained in:
		| @@ -31,6 +31,8 @@ | |||||||
| #define LIST_CLIENTS_TEMPLATE						\ | #define LIST_CLIENTS_TEMPLATE						\ | ||||||
| 	"#{client_name}: #{session_name} "				\ | 	"#{client_name}: #{session_name} "				\ | ||||||
| 	"[#{client_width}x#{client_height} #{client_termname}] "	\ | 	"[#{client_width}x#{client_height} #{client_termname}] "	\ | ||||||
|  | 	"#{?#{!=:#{client_uid},#{uid}},"				\ | ||||||
|  | 	"[user #{?client_user,#{client_user},#{client_uid},}] ,}"	\ | ||||||
| 	"#{?client_flags,(,}#{client_flags}#{?client_flags,),}" | 	"#{?client_flags,(,}#{client_flags}#{?client_flags,),}" | ||||||
|  |  | ||||||
| static enum cmd_retval	cmd_list_clients_exec(struct cmd *, struct cmdq_item *); | static enum cmd_retval	cmd_list_clients_exec(struct cmd *, struct cmdq_item *); | ||||||
|   | |||||||
| @@ -34,7 +34,7 @@ const struct cmd_entry cmd_refresh_client_entry = { | |||||||
| 	.name = "refresh-client", | 	.name = "refresh-client", | ||||||
| 	.alias = "refresh", | 	.alias = "refresh", | ||||||
|  |  | ||||||
| 	.args = { "A:B:cC:Df:F:lLRSt:U", 0, 1, NULL }, | 	.args = { "A:B:cC:Df:F:l::LRSt:U", 0, 1, NULL }, | ||||||
| 	.usage = "[-cDlLRSU] [-A pane:state] [-B name:what:format] " | 	.usage = "[-cDlLRSU] [-A pane:state] [-B name:what:format] " | ||||||
| 		 "[-C XxY] [-f flags] " CMD_TARGET_CLIENT_USAGE " [adjustment]", | 		 "[-C XxY] [-f flags] " CMD_TARGET_CLIENT_USAGE " [adjustment]", | ||||||
|  |  | ||||||
| @@ -162,6 +162,37 @@ out: | |||||||
| 	free(copy); | 	free(copy); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static enum cmd_retval | ||||||
|  | cmd_refresh_client_clipboard(struct cmd *self, struct cmdq_item *item) | ||||||
|  | { | ||||||
|  | 	struct args		*args = cmd_get_args(self); | ||||||
|  | 	struct client		*tc = cmdq_get_target_client(item); | ||||||
|  | 	const char		*p; | ||||||
|  | 	u_int			 i; | ||||||
|  | 	struct cmd_find_state	 fs; | ||||||
|  |  | ||||||
|  | 	p = args_get(args, 'l'); | ||||||
|  | 	if (p == NULL) { | ||||||
|  | 		if (tc->flags & CLIENT_CLIPBOARDBUFFER) | ||||||
|  | 			return (CMD_RETURN_NORMAL); | ||||||
|  | 		tc->flags |= CLIENT_CLIPBOARDBUFFER; | ||||||
|  | 	} else { | ||||||
|  | 		if (cmd_find_target(&fs, item, p, CMD_FIND_PANE, 0) != 0) | ||||||
|  | 			return (CMD_RETURN_ERROR); | ||||||
|  | 		for (i = 0; i < tc->clipboard_npanes; i++) { | ||||||
|  | 			if (tc->clipboard_panes[i] == fs.wp->id) | ||||||
|  | 				break; | ||||||
|  | 		} | ||||||
|  | 		if (i != tc->clipboard_npanes) | ||||||
|  | 			return (CMD_RETURN_NORMAL); | ||||||
|  | 		tc->clipboard_panes = xreallocarray (tc->clipboard_panes, | ||||||
|  | 		    tc->clipboard_npanes + 1, sizeof *tc->clipboard_panes); | ||||||
|  | 		tc->clipboard_panes[tc->clipboard_npanes++] = fs.wp->id; | ||||||
|  | 	} | ||||||
|  | 	tty_clipboard_query(&tc->tty); | ||||||
|  | 	return (CMD_RETURN_NORMAL); | ||||||
|  | } | ||||||
|  |  | ||||||
| static enum cmd_retval | static enum cmd_retval | ||||||
| cmd_refresh_client_exec(struct cmd *self, struct cmdq_item *item) | cmd_refresh_client_exec(struct cmd *self, struct cmdq_item *item) | ||||||
| { | { | ||||||
| @@ -224,10 +255,8 @@ cmd_refresh_client_exec(struct cmd *self, struct cmdq_item *item) | |||||||
| 		return (CMD_RETURN_NORMAL); | 		return (CMD_RETURN_NORMAL); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if (args_has(args, 'l')) { | 	if (args_has(args, 'l')) | ||||||
| 		tty_send_osc52_query(&tc->tty); | 		return (cmd_refresh_client_clipboard(self, item)); | ||||||
| 		return (CMD_RETURN_NORMAL); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if (args_has(args, 'F')) /* -F is an alias for -f */ | 	if (args_has(args, 'F')) /* -F is an alias for -f */ | ||||||
| 		server_client_set_flags(tc, args_get(args, 'F')); | 		server_client_set_flags(tc, args_get(args, 'F')); | ||||||
|   | |||||||
							
								
								
									
										60
									
								
								format.c
									
									
									
									
									
								
							
							
						
						
									
										60
									
								
								format.c
									
									
									
									
									
								
							| @@ -24,6 +24,7 @@ | |||||||
| #include <fnmatch.h> | #include <fnmatch.h> | ||||||
| #include <libgen.h> | #include <libgen.h> | ||||||
| #include <math.h> | #include <math.h> | ||||||
|  | #include <pwd.h> | ||||||
| #include <regex.h> | #include <regex.h> | ||||||
| #include <stdarg.h> | #include <stdarg.h> | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| @@ -1387,6 +1388,35 @@ format_cb_client_tty(struct format_tree *ft) | |||||||
| 	return (NULL); | 	return (NULL); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /* Callback for client_uid. */ | ||||||
|  | static void * | ||||||
|  | format_cb_client_uid(struct format_tree *ft) | ||||||
|  | { | ||||||
|  | 	uid_t	uid; | ||||||
|  |  | ||||||
|  | 	if (ft->c != NULL) { | ||||||
|  | 		uid = proc_get_peer_uid(ft->c->peer); | ||||||
|  | 		if (uid != (uid_t)-1) | ||||||
|  | 			return (format_printf("%ld", (long)uid)); | ||||||
|  | 	} | ||||||
|  | 	return (NULL); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* Callback for client_user. */ | ||||||
|  | static void * | ||||||
|  | format_cb_client_user(struct format_tree *ft) | ||||||
|  | { | ||||||
|  | 	uid_t		 uid; | ||||||
|  | 	struct passwd	*pw; | ||||||
|  |  | ||||||
|  | 	if (ft->c != NULL) { | ||||||
|  | 		uid = proc_get_peer_uid(ft->c->peer); | ||||||
|  | 		if (uid != (uid_t)-1 && (pw = getpwuid(uid)) != NULL) | ||||||
|  | 			return (xstrdup(pw->pw_name)); | ||||||
|  | 	} | ||||||
|  | 	return (NULL); | ||||||
|  | } | ||||||
|  |  | ||||||
| /* Callback for client_utf8. */ | /* Callback for client_utf8. */ | ||||||
| static void * | static void * | ||||||
| format_cb_client_utf8(struct format_tree *ft) | format_cb_client_utf8(struct format_tree *ft) | ||||||
| @@ -2521,6 +2551,24 @@ format_cb_tree_mode_format(__unused struct format_tree *ft) | |||||||
| 	return (xstrdup(window_tree_mode.default_format)); | 	return (xstrdup(window_tree_mode.default_format)); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /* Callback for uid. */ | ||||||
|  | static void * | ||||||
|  | format_cb_uid(__unused struct format_tree *ft) | ||||||
|  | { | ||||||
|  | 	return (format_printf("%ld", (long)getuid())); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* Callback for user. */ | ||||||
|  | static void * | ||||||
|  | format_cb_user(__unused struct format_tree *ft) | ||||||
|  | { | ||||||
|  | 	struct passwd	*pw; | ||||||
|  |  | ||||||
|  | 	if ((pw = getpwuid(getuid())) != NULL) | ||||||
|  | 		return (xstrdup(pw->pw_name)); | ||||||
|  | 	return NULL; | ||||||
|  | } | ||||||
|  |  | ||||||
| /* Format table type. */ | /* Format table type. */ | ||||||
| enum format_table_type { | enum format_table_type { | ||||||
| 	FORMAT_TABLE_STRING, | 	FORMAT_TABLE_STRING, | ||||||
| @@ -2627,6 +2675,12 @@ static const struct format_table_entry format_table[] = { | |||||||
| 	{ "client_tty", FORMAT_TABLE_STRING, | 	{ "client_tty", FORMAT_TABLE_STRING, | ||||||
| 	  format_cb_client_tty | 	  format_cb_client_tty | ||||||
| 	}, | 	}, | ||||||
|  | 	{ "client_uid", FORMAT_TABLE_STRING, | ||||||
|  | 	  format_cb_client_uid | ||||||
|  | 	}, | ||||||
|  | 	{ "client_user", FORMAT_TABLE_STRING, | ||||||
|  | 	  format_cb_client_user | ||||||
|  | 	}, | ||||||
| 	{ "client_utf8", FORMAT_TABLE_STRING, | 	{ "client_utf8", FORMAT_TABLE_STRING, | ||||||
| 	  format_cb_client_utf8 | 	  format_cb_client_utf8 | ||||||
| 	}, | 	}, | ||||||
| @@ -2906,6 +2960,12 @@ static const struct format_table_entry format_table[] = { | |||||||
| 	{ "tree_mode_format", FORMAT_TABLE_STRING, | 	{ "tree_mode_format", FORMAT_TABLE_STRING, | ||||||
| 	  format_cb_tree_mode_format | 	  format_cb_tree_mode_format | ||||||
| 	}, | 	}, | ||||||
|  | 	{ "uid", FORMAT_TABLE_STRING, | ||||||
|  | 	  format_cb_uid | ||||||
|  | 	}, | ||||||
|  | 	{ "user", FORMAT_TABLE_STRING, | ||||||
|  | 	  format_cb_user | ||||||
|  | 	}, | ||||||
| 	{ "version", FORMAT_TABLE_STRING, | 	{ "version", FORMAT_TABLE_STRING, | ||||||
| 	  format_cb_version | 	  format_cb_version | ||||||
| 	}, | 	}, | ||||||
|   | |||||||
							
								
								
									
										47
									
								
								input.c
									
									
									
									
									
								
							
							
						
						
									
										47
									
								
								input.c
									
									
									
									
									
								
							| @@ -2682,8 +2682,8 @@ input_osc_52(struct input_ctx *ictx, const char *p) | |||||||
| { | { | ||||||
| 	struct window_pane	*wp = ictx->wp; | 	struct window_pane	*wp = ictx->wp; | ||||||
| 	char			*end; | 	char			*end; | ||||||
| 	const char		*buf; | 	const char		*buf = NULL; | ||||||
| 	size_t			 len; | 	size_t			 len = 0; | ||||||
| 	u_char			*out; | 	u_char			*out; | ||||||
| 	int			 outlen, state; | 	int			 outlen, state; | ||||||
| 	struct screen_write_ctx	 ctx; | 	struct screen_write_ctx	 ctx; | ||||||
| @@ -2703,26 +2703,12 @@ input_osc_52(struct input_ctx *ictx, const char *p) | |||||||
| 	log_debug("%s: %s", __func__, end); | 	log_debug("%s: %s", __func__, end); | ||||||
|  |  | ||||||
| 	if (strcmp(end, "?") == 0) { | 	if (strcmp(end, "?") == 0) { | ||||||
| 		if ((pb = paste_get_top(NULL)) != NULL) { | 		if ((pb = paste_get_top(NULL)) != NULL) | ||||||
| 			buf = paste_buffer_data(pb, &len); | 			buf = paste_buffer_data(pb, &len); | ||||||
| 			outlen = 4 * ((len + 2) / 3) + 1; |  | ||||||
| 			out = xmalloc(outlen); |  | ||||||
| 			if ((outlen = b64_ntop(buf, len, out, outlen)) == -1) { |  | ||||||
| 				free(out); |  | ||||||
| 				return; |  | ||||||
| 			} |  | ||||||
| 		} else { |  | ||||||
| 			outlen = 0; |  | ||||||
| 			out = NULL; |  | ||||||
| 		} |  | ||||||
| 		bufferevent_write(ictx->event, "\033]52;;", 6); |  | ||||||
| 		if (outlen != 0) |  | ||||||
| 			bufferevent_write(ictx->event, out, outlen); |  | ||||||
| 		if (ictx->input_end == INPUT_END_BEL) | 		if (ictx->input_end == INPUT_END_BEL) | ||||||
| 			bufferevent_write(ictx->event, "\007", 1); | 			input_reply_clipboard(ictx->event, buf, len, "\007"); | ||||||
| 		else | 		else | ||||||
| 			bufferevent_write(ictx->event, "\033\\", 2); | 			input_reply_clipboard(ictx->event, buf, len, "\033\\"); | ||||||
| 		free(out); |  | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -2780,3 +2766,26 @@ input_osc_104(struct input_ctx *ictx, const char *p) | |||||||
| 		screen_write_fullredraw(&ictx->ctx); | 		screen_write_fullredraw(&ictx->ctx); | ||||||
| 	free(copy); | 	free(copy); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void | ||||||
|  | input_reply_clipboard(struct bufferevent *bev, const char *buf, size_t len, | ||||||
|  |     const char *end) | ||||||
|  | { | ||||||
|  | 	char	*out = NULL; | ||||||
|  | 	size_t	 outlen = 0; | ||||||
|  |  | ||||||
|  | 	if (buf != NULL && len != 0) { | ||||||
|  | 		outlen = 4 * ((len + 2) / 3) + 1; | ||||||
|  | 		out = xmalloc(outlen); | ||||||
|  | 		if ((outlen = b64_ntop(buf, len, out, outlen)) == -1) { | ||||||
|  | 			free(out); | ||||||
|  | 			return; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	bufferevent_write(bev, "\033]52;;", 6); | ||||||
|  | 	if (outlen != 0) | ||||||
|  | 		bufferevent_write(bev, out, outlen); | ||||||
|  | 	bufferevent_write(bev, end, strlen(end)); | ||||||
|  | 	free(out); | ||||||
|  | } | ||||||
|   | |||||||
							
								
								
									
										11
									
								
								proc.c
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								proc.c
									
									
									
									
									
								
							| @@ -56,6 +56,7 @@ struct tmuxpeer { | |||||||
|  |  | ||||||
| 	struct imsgbuf	 ibuf; | 	struct imsgbuf	 ibuf; | ||||||
| 	struct event	 event; | 	struct event	 event; | ||||||
|  | 	uid_t		 uid; | ||||||
|  |  | ||||||
| 	int		 flags; | 	int		 flags; | ||||||
| #define PEER_BAD 0x1 | #define PEER_BAD 0x1 | ||||||
| @@ -308,6 +309,7 @@ proc_add_peer(struct tmuxproc *tp, int fd, | |||||||
|     void (*dispatchcb)(struct imsg *, void *), void *arg) |     void (*dispatchcb)(struct imsg *, void *), void *arg) | ||||||
| { | { | ||||||
| 	struct tmuxpeer	*peer; | 	struct tmuxpeer	*peer; | ||||||
|  | 	gid_t		 gid; | ||||||
|  |  | ||||||
| 	peer = xcalloc(1, sizeof *peer); | 	peer = xcalloc(1, sizeof *peer); | ||||||
| 	peer->parent = tp; | 	peer->parent = tp; | ||||||
| @@ -318,6 +320,9 @@ proc_add_peer(struct tmuxproc *tp, int fd, | |||||||
| 	imsg_init(&peer->ibuf, fd); | 	imsg_init(&peer->ibuf, fd); | ||||||
| 	event_set(&peer->event, fd, EV_READ, proc_event_cb, peer); | 	event_set(&peer->event, fd, EV_READ, proc_event_cb, peer); | ||||||
|  |  | ||||||
|  | 	if (getpeereid(fd, &peer->uid, &gid) != 0) | ||||||
|  | 		peer->uid = (uid_t)-1; | ||||||
|  |  | ||||||
| 	log_debug("add peer %p: %d (%p)", peer, fd, arg); | 	log_debug("add peer %p: %d (%p)", peer, fd, arg); | ||||||
| 	TAILQ_INSERT_TAIL(&tp->peers, peer, entry); | 	TAILQ_INSERT_TAIL(&tp->peers, peer, entry); | ||||||
|  |  | ||||||
| @@ -373,3 +378,9 @@ proc_fork_and_daemon(int *fd) | |||||||
| 		return (pid); | 		return (pid); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | uid_t | ||||||
|  | proc_get_peer_uid(struct tmuxpeer *peer) | ||||||
|  | { | ||||||
|  | 	return (peer->uid); | ||||||
|  | } | ||||||
|   | |||||||
| @@ -422,6 +422,7 @@ server_client_lost(struct client *c) | |||||||
| 	if (c->flags & CLIENT_TERMINAL) | 	if (c->flags & CLIENT_TERMINAL) | ||||||
| 		tty_free(&c->tty); | 		tty_free(&c->tty); | ||||||
| 	free(c->ttyname); | 	free(c->ttyname); | ||||||
|  | 	free(c->clipboard_panes); | ||||||
|  |  | ||||||
| 	free(c->term_name); | 	free(c->term_name); | ||||||
| 	free(c->term_type); | 	free(c->term_type); | ||||||
|   | |||||||
							
								
								
									
										15
									
								
								tmux.1
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								tmux.1
									
									
									
									
									
								
							| @@ -1341,11 +1341,12 @@ and sets an environment variable for the newly created session; it may be | |||||||
| specified multiple times. | specified multiple times. | ||||||
| .Tg refresh | .Tg refresh | ||||||
| .It Xo Ic refresh-client | .It Xo Ic refresh-client | ||||||
| .Op Fl cDlLRSU | .Op Fl cDLRSU | ||||||
| .Op Fl A Ar pane:state | .Op Fl A Ar pane:state | ||||||
| .Op Fl B Ar name:what:format | .Op Fl B Ar name:what:format | ||||||
| .Op Fl C Ar size | .Op Fl C Ar size | ||||||
| .Op Fl f Ar flags | .Op Fl f Ar flags | ||||||
|  | .Op Fl l Op Ar target-pane | ||||||
| .Op Fl t Ar target-client | .Op Fl t Ar target-client | ||||||
| .Op Ar adjustment | .Op Ar adjustment | ||||||
| .Xc | .Xc | ||||||
| @@ -1459,7 +1460,11 @@ sets a comma-separated list of client flags, see | |||||||
| .Fl l | .Fl l | ||||||
| requests the clipboard from the client using the | requests the clipboard from the client using the | ||||||
| .Xr xterm 1 | .Xr xterm 1 | ||||||
| escape sequence and stores it in a new paste buffer. | escape sequence. | ||||||
|  | If | ||||||
|  | Ar target-pane | ||||||
|  | is given, the clipboard is sent (in encoded form), otherwise it is stored in a | ||||||
|  | new paste buffer. | ||||||
| .Pp | .Pp | ||||||
| .Fl L , | .Fl L , | ||||||
| .Fl R , | .Fl R , | ||||||
| @@ -5057,6 +5062,8 @@ The following variables are available, where appropriate: | |||||||
| .It Li "client_termname" Ta "" Ta "Terminal name of client" | .It Li "client_termname" Ta "" Ta "Terminal name of client" | ||||||
| .It Li "client_termtype" Ta "" Ta "Terminal type of client, if available" | .It Li "client_termtype" Ta "" Ta "Terminal type of client, if available" | ||||||
| .It Li "client_tty" Ta "" Ta "Pseudo terminal of client" | .It Li "client_tty" Ta "" Ta "Pseudo terminal of client" | ||||||
|  | .It Li "client_uid" Ta "" Ta "UID of client process" | ||||||
|  | .It Li "client_user" Ta "" Ta "User of client process" | ||||||
| .It Li "client_utf8" Ta "" Ta "1 if client supports UTF-8" | .It Li "client_utf8" Ta "" Ta "1 if client supports UTF-8" | ||||||
| .It Li "client_width" Ta "" Ta "Width of client" | .It Li "client_width" Ta "" Ta "Width of client" | ||||||
| .It Li "client_written" Ta "" Ta "Bytes written to client" | .It Li "client_written" Ta "" Ta "Bytes written to client" | ||||||
| @@ -5174,6 +5181,8 @@ The following variables are available, where appropriate: | |||||||
| .It Li "session_windows" Ta "" Ta "Number of windows in session" | .It Li "session_windows" Ta "" Ta "Number of windows in session" | ||||||
| .It Li "socket_path" Ta "" Ta "Server socket path" | .It Li "socket_path" Ta "" Ta "Server socket path" | ||||||
| .It Li "start_time" Ta "" Ta "Server start time" | .It Li "start_time" Ta "" Ta "Server start time" | ||||||
|  | .It Li "uid" Ta "" Ta "Server UID" | ||||||
|  | .It Li "user" Ta "" Ta "Server user" | ||||||
| .It Li "version" Ta "" Ta "Server version" | .It Li "version" Ta "" Ta "Server version" | ||||||
| .It Li "window_active" Ta "" Ta "1 if window active" | .It Li "window_active" Ta "" Ta "1 if window active" | ||||||
| .It Li "window_active_clients" Ta "" Ta "Number of clients viewing this window" | .It Li "window_active_clients" Ta "" Ta "Number of clients viewing this window" | ||||||
| @@ -5188,7 +5197,6 @@ The following variables are available, where appropriate: | |||||||
| .It Li "window_cell_width" Ta "" Ta "Width of each cell in pixels" | .It Li "window_cell_width" Ta "" Ta "Width of each cell in pixels" | ||||||
| .It Li "window_end_flag" Ta "" Ta "1 if window has the highest index" | .It Li "window_end_flag" Ta "" Ta "1 if window has the highest index" | ||||||
| .It Li "window_flags" Ta "#F" Ta "Window flags with # escaped as ##" | .It Li "window_flags" Ta "#F" Ta "Window flags with # escaped as ##" | ||||||
| .It Li "window_raw_flags" Ta "" Ta "Window flags with nothing escaped" |  | ||||||
| .It Li "window_format" Ta "" Ta "1 if format is for a window" | .It Li "window_format" Ta "" Ta "1 if format is for a window" | ||||||
| .It Li "window_height" Ta "" Ta "Height of window" | .It Li "window_height" Ta "" Ta "Height of window" | ||||||
| .It Li "window_id" Ta "" Ta "Unique window ID" | .It Li "window_id" Ta "" Ta "Unique window ID" | ||||||
| @@ -5203,6 +5211,7 @@ The following variables are available, where appropriate: | |||||||
| .It Li "window_offset_x" Ta "" Ta "X offset into window if larger than client" | .It Li "window_offset_x" Ta "" Ta "X offset into window if larger than client" | ||||||
| .It Li "window_offset_y" Ta "" Ta "Y offset into window if larger than client" | .It Li "window_offset_y" Ta "" Ta "Y offset into window if larger than client" | ||||||
| .It Li "window_panes" Ta "" Ta "Number of panes in window" | .It Li "window_panes" Ta "" Ta "Number of panes in window" | ||||||
|  | .It Li "window_raw_flags" Ta "" Ta "Window flags with nothing escaped" | ||||||
| .It Li "window_silence_flag" Ta "" Ta "1 if window has silence alert" | .It Li "window_silence_flag" Ta "" Ta "1 if window has silence alert" | ||||||
| .It Li "window_stack_index" Ta "" Ta "Index in session most recent stack" | .It Li "window_stack_index" Ta "" Ta "Index in session most recent stack" | ||||||
| .It Li "window_start_flag" Ta "" Ta "1 if window has the lowest index" | .It Li "window_start_flag" Ta "" Ta "1 if window has the lowest index" | ||||||
|   | |||||||
							
								
								
									
										16
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								tmux.h
									
									
									
									
									
								
							| @@ -1332,7 +1332,7 @@ LIST_HEAD(tty_terms, tty_term); | |||||||
| struct tty { | struct tty { | ||||||
| 	struct client	*client; | 	struct client	*client; | ||||||
| 	struct event	 start_timer; | 	struct event	 start_timer; | ||||||
| 	struct event	 query_timer; | 	struct event	 clipboard_timer; | ||||||
|  |  | ||||||
| 	u_int		 sx; | 	u_int		 sx; | ||||||
| 	u_int		 sy; | 	u_int		 sy; | ||||||
| @@ -1765,6 +1765,7 @@ struct client { | |||||||
| #define CLIENT_CONTROL_PAUSEAFTER 0x100000000ULL | #define CLIENT_CONTROL_PAUSEAFTER 0x100000000ULL | ||||||
| #define CLIENT_CONTROL_WAITEXIT 0x200000000ULL | #define CLIENT_CONTROL_WAITEXIT 0x200000000ULL | ||||||
| #define CLIENT_WINDOWSIZECHANGED 0x400000000ULL | #define CLIENT_WINDOWSIZECHANGED 0x400000000ULL | ||||||
|  | #define CLIENT_CLIPBOARDBUFFER 0x800000000ULL | ||||||
| #define CLIENT_ALLREDRAWFLAGS		\ | #define CLIENT_ALLREDRAWFLAGS		\ | ||||||
| 	(CLIENT_REDRAWWINDOW|		\ | 	(CLIENT_REDRAWWINDOW|		\ | ||||||
| 	 CLIENT_REDRAWSTATUS|		\ | 	 CLIENT_REDRAWSTATUS|		\ | ||||||
| @@ -1811,7 +1812,10 @@ struct client { | |||||||
| 	prompt_free_cb		 prompt_freecb; | 	prompt_free_cb		 prompt_freecb; | ||||||
| 	void			*prompt_data; | 	void			*prompt_data; | ||||||
| 	u_int			 prompt_hindex[PROMPT_NTYPES]; | 	u_int			 prompt_hindex[PROMPT_NTYPES]; | ||||||
| 	enum { PROMPT_ENTRY, PROMPT_COMMAND } prompt_mode; | 	enum { | ||||||
|  | 		PROMPT_ENTRY, | ||||||
|  | 		PROMPT_COMMAND | ||||||
|  | 	}			 prompt_mode; | ||||||
| 	struct utf8_data	*prompt_saved; | 	struct utf8_data	*prompt_saved; | ||||||
| #define PROMPT_SINGLE 0x1 | #define PROMPT_SINGLE 0x1 | ||||||
| #define PROMPT_NUMERIC 0x2 | #define PROMPT_NUMERIC 0x2 | ||||||
| @@ -1842,6 +1846,9 @@ struct client { | |||||||
|  |  | ||||||
| 	struct client_files	 files; | 	struct client_files	 files; | ||||||
|  |  | ||||||
|  | 	u_int			*clipboard_panes; | ||||||
|  | 	u_int			 clipboard_npanes; | ||||||
|  |  | ||||||
| 	TAILQ_ENTRY(client)	 entry; | 	TAILQ_ENTRY(client)	 entry; | ||||||
| }; | }; | ||||||
| TAILQ_HEAD(clients, client); | TAILQ_HEAD(clients, client); | ||||||
| @@ -2016,6 +2023,7 @@ void	proc_remove_peer(struct tmuxpeer *); | |||||||
| void	proc_kill_peer(struct tmuxpeer *); | void	proc_kill_peer(struct tmuxpeer *); | ||||||
| void	proc_toggle_log(struct tmuxproc *); | void	proc_toggle_log(struct tmuxproc *); | ||||||
| pid_t	proc_fork_and_daemon(int *); | pid_t	proc_fork_and_daemon(int *); | ||||||
|  | uid_t	proc_get_peer_uid(struct tmuxpeer *); | ||||||
|  |  | ||||||
| /* cfg.c */ | /* cfg.c */ | ||||||
| extern int cfg_finished; | extern int cfg_finished; | ||||||
| @@ -2229,7 +2237,7 @@ void	tty_reset(struct tty *); | |||||||
| void	tty_region_off(struct tty *); | void	tty_region_off(struct tty *); | ||||||
| void	tty_margin_off(struct tty *); | void	tty_margin_off(struct tty *); | ||||||
| void	tty_cursor(struct tty *, u_int, u_int); | void	tty_cursor(struct tty *, u_int, u_int); | ||||||
| void	tty_send_osc52_query(struct tty *); | void	tty_clipboard_query(struct tty *); | ||||||
| void	tty_putcode(struct tty *, enum tty_code_code); | void	tty_putcode(struct tty *, enum tty_code_code); | ||||||
| void	tty_putcode1(struct tty *, enum tty_code_code, int); | void	tty_putcode1(struct tty *, enum tty_code_code, int); | ||||||
| void	tty_putcode2(struct tty *, enum tty_code_code, int, int); | void	tty_putcode2(struct tty *, enum tty_code_code, int, int); | ||||||
| @@ -2675,6 +2683,8 @@ void	 input_parse_pane(struct window_pane *); | |||||||
| void	 input_parse_buffer(struct window_pane *, u_char *, size_t); | void	 input_parse_buffer(struct window_pane *, u_char *, size_t); | ||||||
| void	 input_parse_screen(struct input_ctx *, struct screen *, | void	 input_parse_screen(struct input_ctx *, struct screen *, | ||||||
| 	     screen_write_init_ctx_cb, void *, u_char *, size_t); | 	     screen_write_init_ctx_cb, void *, u_char *, size_t); | ||||||
|  | void	 input_reply_clipboard(struct bufferevent *, const char *, size_t, | ||||||
|  | 	     const char *); | ||||||
|  |  | ||||||
| /* input-key.c */ | /* input-key.c */ | ||||||
| void	 input_key_build(void); | void	 input_key_build(void); | ||||||
|   | |||||||
							
								
								
									
										20
									
								
								tty-keys.c
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								tty-keys.c
									
									
									
									
									
								
							| @@ -1154,12 +1154,14 @@ tty_keys_mouse(struct tty *tty, const char *buf, size_t len, size_t *size, | |||||||
|  * partial. |  * partial. | ||||||
|  */ |  */ | ||||||
| static int | static int | ||||||
| tty_keys_clipboard(__unused struct tty *tty, const char *buf, size_t len, | tty_keys_clipboard(struct tty *tty, const char *buf, size_t len, size_t *size) | ||||||
|     size_t *size) |  | ||||||
| { | { | ||||||
|  | 	struct client		*c = tty->client; | ||||||
|  | 	struct window_pane	*wp; | ||||||
| 	size_t			 end, terminator, needed; | 	size_t			 end, terminator, needed; | ||||||
| 	char			*copy, *out; | 	char			*copy, *out; | ||||||
| 	int			 outlen; | 	int			 outlen; | ||||||
|  | 	u_int			 i; | ||||||
|  |  | ||||||
| 	*size = 0; | 	*size = 0; | ||||||
|  |  | ||||||
| @@ -1221,6 +1223,7 @@ tty_keys_clipboard(__unused struct tty *tty, const char *buf, size_t len, | |||||||
| 	if (~tty->flags & TTY_OSC52QUERY) | 	if (~tty->flags & TTY_OSC52QUERY) | ||||||
| 		return (0); | 		return (0); | ||||||
| 	tty->flags &= ~TTY_OSC52QUERY; | 	tty->flags &= ~TTY_OSC52QUERY; | ||||||
|  | 	evtimer_del(&tty->clipboard_timer); | ||||||
|  |  | ||||||
| 	/* It has to be a string so copy it. */ | 	/* It has to be a string so copy it. */ | ||||||
| 	copy = xmalloc(end + 1); | 	copy = xmalloc(end + 1); | ||||||
| @@ -1237,9 +1240,20 @@ tty_keys_clipboard(__unused struct tty *tty, const char *buf, size_t len, | |||||||
| 	} | 	} | ||||||
| 	free(copy); | 	free(copy); | ||||||
|  |  | ||||||
| 	/* Create a new paste buffer. */ | 	/* Create a new paste buffer and forward to panes. */ | ||||||
| 	log_debug("%s: %.*s", __func__, outlen, out); | 	log_debug("%s: %.*s", __func__, outlen, out); | ||||||
|  | 	if (c->flags & CLIENT_CLIPBOARDBUFFER) { | ||||||
| 		paste_add(NULL, out, outlen); | 		paste_add(NULL, out, outlen); | ||||||
|  | 		c->flags &= ~CLIENT_CLIPBOARDBUFFER; | ||||||
|  | 	} | ||||||
|  | 	for (i = 0; i < c->clipboard_npanes; i++) { | ||||||
|  | 		wp = window_pane_find_by_id(c->clipboard_panes[i]); | ||||||
|  | 		if (wp != NULL) | ||||||
|  | 			input_reply_clipboard(wp->event, out, outlen, "\033\\"); | ||||||
|  | 	} | ||||||
|  | 	free(c->clipboard_panes); | ||||||
|  | 	c->clipboard_panes = NULL; | ||||||
|  | 	c->clipboard_npanes = 0; | ||||||
|  |  | ||||||
| 	return (0); | 	return (0); | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										17
									
								
								tty.c
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								tty.c
									
									
									
									
									
								
							| @@ -2921,24 +2921,29 @@ tty_default_attributes(struct tty *tty, const struct grid_cell *defaults, | |||||||
| } | } | ||||||
|  |  | ||||||
| static void | static void | ||||||
| tty_query_timer_callback(__unused int fd, __unused short events, void *data) | tty_clipboard_query_callback(__unused int fd, __unused short events, void *data) | ||||||
| { | { | ||||||
| 	struct tty	*tty = data; | 	struct tty	*tty = data; | ||||||
|  | 	struct client	*c = tty->client; | ||||||
|  |  | ||||||
|  | 	c->flags &= ~CLIENT_CLIPBOARDBUFFER; | ||||||
|  | 	free(c->clipboard_panes); | ||||||
|  | 	c->clipboard_panes = NULL; | ||||||
|  | 	c->clipboard_npanes = 0; | ||||||
|  |  | ||||||
| 	tty->flags &= ~TTY_OSC52QUERY; | 	tty->flags &= ~TTY_OSC52QUERY; | ||||||
| } | } | ||||||
|  |  | ||||||
| void | void | ||||||
| tty_send_osc52_query(struct tty *tty) | tty_clipboard_query(struct tty *tty) | ||||||
| { | { | ||||||
| 	struct timeval	 tv = { .tv_sec = TTY_QUERY_TIMEOUT }; | 	struct timeval	 tv = { .tv_sec = TTY_QUERY_TIMEOUT }; | ||||||
|  |  | ||||||
| 	if ((~tty->flags & TTY_STARTED) || (tty->flags & TTY_OSC52QUERY)) | 	if ((~tty->flags & TTY_STARTED) || (tty->flags & TTY_OSC52QUERY)) | ||||||
| 		return; | 		return; | ||||||
| 	tty_putcode_ptr2(tty, TTYC_MS, "", "?"); | 	tty_putcode_ptr2(tty, TTYC_MS, "", "?"); | ||||||
|  |  | ||||||
| 	tty->flags |= TTY_OSC52QUERY; | 	tty->flags |= TTY_OSC52QUERY; | ||||||
|  | 	evtimer_set(&tty->clipboard_timer, tty_clipboard_query_callback, tty); | ||||||
| 	evtimer_set(&tty->query_timer, tty_query_timer_callback, tty); | 	evtimer_add(&tty->clipboard_timer, &tv); | ||||||
| 	evtimer_add(&tty->query_timer, &tv); |  | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Thomas Adam
					Thomas Adam