mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-04 00:56:10 +00:00 
			
		
		
		
	Import tmux, a terminal multiplexor allowing (among other things) a single
terminal to be switched between several different windows and programs displayed on one terminal be detached from one terminal and moved to another. ok deraadt pirofti
This commit is contained in:
		
							
								
								
									
										48
									
								
								Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								Makefile
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,48 @@
 | 
				
			|||||||
 | 
					# $OpenBSD$
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.PATH:	${.CURDIR}/..
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PROG=	tmux
 | 
				
			||||||
 | 
					SRCS=	arg.c attributes.c buffer-poll.c buffer.c cfg.c client-fn.c \
 | 
				
			||||||
 | 
						client-msg.c client.c clock.c cmd-attach-session.c cmd-bind-key.c \
 | 
				
			||||||
 | 
						cmd-break-pane.c cmd-choose-session.c cmd-choose-window.c \
 | 
				
			||||||
 | 
						cmd-clear-history.c cmd-clock-mode.c cmd-command-prompt.c \
 | 
				
			||||||
 | 
						cmd-confirm-before.c cmd-copy-buffer.c cmd-copy-mode.c \
 | 
				
			||||||
 | 
						cmd-delete-buffer.c cmd-detach-client.c cmd-down-pane.c \
 | 
				
			||||||
 | 
						cmd-find-window.c cmd-generic.c cmd-has-session.c cmd-kill-pane.c \
 | 
				
			||||||
 | 
						cmd-kill-server.c cmd-kill-session.c cmd-kill-window.c \
 | 
				
			||||||
 | 
						cmd-last-window.c cmd-link-window.c cmd-list-buffers.c \
 | 
				
			||||||
 | 
						cmd-list-clients.c cmd-list-commands.c cmd-list-keys.c \
 | 
				
			||||||
 | 
						cmd-list-sessions.c cmd-list-windows.c cmd-list.c cmd-load-buffer.c \
 | 
				
			||||||
 | 
						cmd-lock-server.c cmd-move-window.c cmd-new-session.c cmd-new-window.c \
 | 
				
			||||||
 | 
						cmd-next-layout.c cmd-next-window.c cmd-paste-buffer.c \
 | 
				
			||||||
 | 
						cmd-previous-layout.c cmd-previous-window.c cmd-refresh-client.c \
 | 
				
			||||||
 | 
						cmd-rename-session.c cmd-rename-window.c cmd-resize-pane.c \
 | 
				
			||||||
 | 
						cmd-respawn-window.c cmd-rotate-window.c cmd-save-buffer.c \
 | 
				
			||||||
 | 
						cmd-scroll-mode.c cmd-select-layout.c cmd-select-pane.c \
 | 
				
			||||||
 | 
						cmd-select-prompt.c cmd-select-window.c cmd-send-keys.c \
 | 
				
			||||||
 | 
						cmd-send-prefix.c cmd-server-info.c cmd-set-buffer.c cmd-set-option.c \
 | 
				
			||||||
 | 
						cmd-set-password.c cmd-set-window-option.c cmd-show-buffer.c \
 | 
				
			||||||
 | 
						cmd-show-options.c cmd-show-window-options.c cmd-source-file.c \
 | 
				
			||||||
 | 
						cmd-split-window.c cmd-start-server.c cmd-string.c \
 | 
				
			||||||
 | 
						cmd-suspend-client.c cmd-swap-pane.c cmd-swap-window.c \
 | 
				
			||||||
 | 
						cmd-switch-client.c cmd-unbind-key.c cmd-unlink-window.c \
 | 
				
			||||||
 | 
						cmd-up-pane.c cmd.c colour.c grid-view.c grid.c input-keys.c \
 | 
				
			||||||
 | 
						input.c key-bindings.c key-string.c layout-manual.c layout.c log.c \
 | 
				
			||||||
 | 
						mode-key.c names.c options-cmd.c options.c paste.c procname.c \
 | 
				
			||||||
 | 
						resize.c screen-redraw.c screen-write.c screen.c server-fn.c \
 | 
				
			||||||
 | 
						server-msg.c server.c session.c status.c tmux.c tty-keys.c tty-term.c \
 | 
				
			||||||
 | 
						tty-write.c tty.c utf8.c util.c window-choose.c window-clock.c \
 | 
				
			||||||
 | 
						window-copy.c window-more.c window-scroll.c window.c xmalloc.c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CFLAGS+= -Wno-long-long -Wall -W -Wnested-externs -Wformat=2
 | 
				
			||||||
 | 
					CFLAGS+= -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations
 | 
				
			||||||
 | 
					CFLAGS+= -Wwrite-strings -Wshadow -Wpointer-arith -Wsign-compare
 | 
				
			||||||
 | 
					CFLAGS+= -Wundef -Wbad-function-cast -Winline -Wcast-align
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					LDADD=  -lutil -lncurses
 | 
				
			||||||
 | 
					DPADD=  ${LIBUTIL}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					MAN=	tmux.1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.include <bsd.prog.mk>
 | 
				
			||||||
							
								
								
									
										194
									
								
								arg.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										194
									
								
								arg.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,194 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <fnmatch.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct client	*arg_lookup_client(const char *);
 | 
				
			||||||
 | 
					struct session	*arg_lookup_session(const char *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct client *
 | 
				
			||||||
 | 
					arg_lookup_client(const char *name)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct client	*c;
 | 
				
			||||||
 | 
						u_int		 i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
 | 
				
			||||||
 | 
							c = ARRAY_ITEM(&clients, i);
 | 
				
			||||||
 | 
							if (c != NULL && strcmp(name, c->tty.path) == 0)
 | 
				
			||||||
 | 
								return (c);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (NULL);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct session *
 | 
				
			||||||
 | 
					arg_lookup_session(const char *name)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct session	*s, *newest = NULL;
 | 
				
			||||||
 | 
						struct timeval	*tv;
 | 
				
			||||||
 | 
						u_int		 i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tv = NULL;
 | 
				
			||||||
 | 
						for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
 | 
				
			||||||
 | 
							s = ARRAY_ITEM(&sessions, i);
 | 
				
			||||||
 | 
							if (s == NULL || fnmatch(name, s->name, 0) != 0)
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (tv == NULL || timercmp(&s->tv, tv, >)) {
 | 
				
			||||||
 | 
								newest = s;
 | 
				
			||||||
 | 
								tv = &s->tv;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (newest);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct client *
 | 
				
			||||||
 | 
					arg_parse_client(const char *arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct client	*c;
 | 
				
			||||||
 | 
						char		*arg2;
 | 
				
			||||||
 | 
						size_t		 n;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (arg != NULL && (arg[0] != ':' || arg[1] != '\0')) {
 | 
				
			||||||
 | 
							arg2 = xstrdup(arg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Trim a trailing : if any from the argument. */
 | 
				
			||||||
 | 
							n = strlen(arg2);
 | 
				
			||||||
 | 
							if (arg2[n - 1] == ':')
 | 
				
			||||||
 | 
								arg2[n - 1] = '\0';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Try and look up the client name. */
 | 
				
			||||||
 | 
							c = arg_lookup_client(arg2);
 | 
				
			||||||
 | 
							xfree(arg2);
 | 
				
			||||||
 | 
							return (c);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (NULL);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct session *
 | 
				
			||||||
 | 
					arg_parse_session(const char *arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct session	*s;
 | 
				
			||||||
 | 
						struct client	*c;
 | 
				
			||||||
 | 
						char		*arg2;
 | 
				
			||||||
 | 
						size_t		 n;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (arg != NULL && (arg[0] != ':' || arg[1] != '\0')) {
 | 
				
			||||||
 | 
							arg2 = xstrdup(arg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Trim a trailing : if any from the argument. */
 | 
				
			||||||
 | 
							n = strlen(arg2);
 | 
				
			||||||
 | 
							if (arg2[n - 1] == ':')
 | 
				
			||||||
 | 
								arg2[n - 1] = '\0';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* See if the argument matches a session. */
 | 
				
			||||||
 | 
							if ((s = arg_lookup_session(arg2)) != NULL) {
 | 
				
			||||||
 | 
								xfree(arg2);
 | 
				
			||||||
 | 
								return (s);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* If not try a client. */
 | 
				
			||||||
 | 
							if ((c = arg_lookup_client(arg2)) != NULL) {
 | 
				
			||||||
 | 
								xfree(arg2);
 | 
				
			||||||
 | 
								return (c->session);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							xfree(arg2);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (NULL);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					arg_parse_window(const char *arg, struct session **s, int *idx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char		*arg2, *ptr;
 | 
				
			||||||
 | 
						const char	*errstr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						*idx = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Handle no argument or a single :. */
 | 
				
			||||||
 | 
						if (arg == NULL || (arg[0] == ':' && arg[1] == '\0')) {
 | 
				
			||||||
 | 
							*s = arg_parse_session(NULL);
 | 
				
			||||||
 | 
							return (0);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Find the separator if any. */
 | 
				
			||||||
 | 
						arg2 = xstrdup(arg);
 | 
				
			||||||
 | 
						ptr = strrchr(arg2, ':');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * If it is first, this means no session name, so use current session
 | 
				
			||||||
 | 
						 * and try to convert the rest as index.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						if (ptr == arg2) {
 | 
				
			||||||
 | 
							*idx = strtonum(ptr + 1, 0, INT_MAX, &errstr);
 | 
				
			||||||
 | 
							if (errstr != NULL) {
 | 
				
			||||||
 | 
								xfree(arg2);
 | 
				
			||||||
 | 
								return (1);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							xfree(arg2);
 | 
				
			||||||
 | 
							*s = arg_parse_session(NULL);
 | 
				
			||||||
 | 
							return (0);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* If missing, try as an index, else look up immediately. */
 | 
				
			||||||
 | 
						if (ptr == NULL) {
 | 
				
			||||||
 | 
							*idx = strtonum(arg2, 0, INT_MAX, &errstr);
 | 
				
			||||||
 | 
							if (errstr == NULL) {
 | 
				
			||||||
 | 
								/* This is good as an index; use current session. */
 | 
				
			||||||
 | 
								xfree(arg2);
 | 
				
			||||||
 | 
								*s = arg_parse_session(NULL);
 | 
				
			||||||
 | 
								return (0);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							*idx = -1;
 | 
				
			||||||
 | 
							goto lookup;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* If last, strip it and look up as a session. */
 | 
				
			||||||
 | 
						if (ptr[1] == '\0') {
 | 
				
			||||||
 | 
							*ptr = '\0';
 | 
				
			||||||
 | 
							goto lookup;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Present but not first and not last. Break and convert both. */
 | 
				
			||||||
 | 
						*ptr = '\0';
 | 
				
			||||||
 | 
						*idx = strtonum(ptr + 1, 0, INT_MAX, &errstr);
 | 
				
			||||||
 | 
						if (errstr != NULL) {
 | 
				
			||||||
 | 
							xfree(arg2);
 | 
				
			||||||
 | 
							return (1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					lookup:
 | 
				
			||||||
 | 
						/* Look up as session. */
 | 
				
			||||||
 | 
						*s = arg_parse_session(arg2);
 | 
				
			||||||
 | 
						xfree(arg2);
 | 
				
			||||||
 | 
						if (*s == NULL)
 | 
				
			||||||
 | 
							return (1);
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										119
									
								
								array.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								array.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,119 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2006 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef ARRAY_H
 | 
				
			||||||
 | 
					#define ARRAY_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define ARRAY_DECL(n, c)						\
 | 
				
			||||||
 | 
						struct n {							\
 | 
				
			||||||
 | 
							c	*list;						\
 | 
				
			||||||
 | 
							u_int	 num;						\
 | 
				
			||||||
 | 
							size_t	 space;						\
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define ARRAY_ITEM(a, i) ((a)->list[i])
 | 
				
			||||||
 | 
					#define ARRAY_ITEMSIZE(a) (sizeof *(a)->list)
 | 
				
			||||||
 | 
					#define ARRAY_INITIALSPACE(a) (10 * ARRAY_ITEMSIZE(a))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define ARRAY_ENSURE(a, n) do {						\
 | 
				
			||||||
 | 
						if (UINT_MAX - (n) < (a)->num)					\
 | 
				
			||||||
 | 
							fatalx("number too big");				\
 | 
				
			||||||
 | 
						if (SIZE_MAX / ((a)->num + (n)) < ARRAY_ITEMSIZE(a))		\
 | 
				
			||||||
 | 
							fatalx("size too big");					\
 | 
				
			||||||
 | 
						if ((a)->space == 0) {						\
 | 
				
			||||||
 | 
						       	(a)->space = ARRAY_INITIALSPACE(a);			\
 | 
				
			||||||
 | 
							(a)->list = xrealloc((a)->list, 1, (a)->space);		\
 | 
				
			||||||
 | 
						}								\
 | 
				
			||||||
 | 
						while ((a)->space <= ((a)->num + (n)) * ARRAY_ITEMSIZE(a)) {	\
 | 
				
			||||||
 | 
							(a)->list = xrealloc((a)->list, 2, (a)->space);		\
 | 
				
			||||||
 | 
							(a)->space *= 2;					\
 | 
				
			||||||
 | 
						}								\
 | 
				
			||||||
 | 
					} while (0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define ARRAY_EMPTY(a) ((a) == NULL || (a)->num == 0)
 | 
				
			||||||
 | 
					#define ARRAY_LENGTH(a) ((a)->num)
 | 
				
			||||||
 | 
					#define ARRAY_DATA(a) ((a)->list)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define ARRAY_FIRST(a) ARRAY_ITEM(a, 0)
 | 
				
			||||||
 | 
					#define ARRAY_LAST(a) ARRAY_ITEM(a, (a)->num - 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define ARRAY_INIT(a) do {						\
 | 
				
			||||||
 | 
						(a)->num = 0;							\
 | 
				
			||||||
 | 
						(a)->list = NULL;		 				\
 | 
				
			||||||
 | 
						(a)->space = 0;							\
 | 
				
			||||||
 | 
					} while (0)
 | 
				
			||||||
 | 
					#define ARRAY_CLEAR(a) do {						\
 | 
				
			||||||
 | 
						(a)->num = 0;							\
 | 
				
			||||||
 | 
					} while (0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define ARRAY_SET(a, i, s) do {						\
 | 
				
			||||||
 | 
						(a)->list[i] = s;						\
 | 
				
			||||||
 | 
					} while (0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define ARRAY_ADD(a, s) do {						\
 | 
				
			||||||
 | 
						ARRAY_ENSURE(a, 1);						\
 | 
				
			||||||
 | 
						(a)->list[(a)->num] = s;					\
 | 
				
			||||||
 | 
						(a)->num++;							\
 | 
				
			||||||
 | 
					} while (0)
 | 
				
			||||||
 | 
					#define ARRAY_INSERT(a, i, s) do {					\
 | 
				
			||||||
 | 
						ARRAY_ENSURE(a, 1);						\
 | 
				
			||||||
 | 
						if ((i) < (a)->num) {						\
 | 
				
			||||||
 | 
							memmove((a)->list + (i) + 1, (a)->list + (i), 		\
 | 
				
			||||||
 | 
							    ARRAY_ITEMSIZE(a) * ((a)->num - (i)));		\
 | 
				
			||||||
 | 
						}								\
 | 
				
			||||||
 | 
						(a)->list[i] = s;						\
 | 
				
			||||||
 | 
						(a)->num++;							\
 | 
				
			||||||
 | 
					} while (0)
 | 
				
			||||||
 | 
					#define ARRAY_REMOVE(a, i) do {						\
 | 
				
			||||||
 | 
						if ((i) < (a)->num - 1) {					\
 | 
				
			||||||
 | 
							memmove((a)->list + (i), (a)->list + (i) + 1, 		\
 | 
				
			||||||
 | 
							    ARRAY_ITEMSIZE(a) * ((a)->num - (i) - 1));		\
 | 
				
			||||||
 | 
						}								\
 | 
				
			||||||
 | 
						(a)->num--;							\
 | 
				
			||||||
 | 
					        if ((a)->num == 0)						\
 | 
				
			||||||
 | 
							ARRAY_FREE(a);						\
 | 
				
			||||||
 | 
					} while (0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define ARRAY_EXPAND(a, n) do {						\
 | 
				
			||||||
 | 
						ARRAY_ENSURE(a, n);						\
 | 
				
			||||||
 | 
						(a)->num += n;							\
 | 
				
			||||||
 | 
					} while (0)
 | 
				
			||||||
 | 
					#define ARRAY_TRUNC(a, n) do {						\
 | 
				
			||||||
 | 
						if ((a)->num > n)						\
 | 
				
			||||||
 | 
							(a)->num -= n;				       		\
 | 
				
			||||||
 | 
						else								\
 | 
				
			||||||
 | 
							ARRAY_FREE(a);						\
 | 
				
			||||||
 | 
					} while (0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define ARRAY_CONCAT(a, b) do {						\
 | 
				
			||||||
 | 
						ARRAY_ENSURE(a, (b)->num);					\
 | 
				
			||||||
 | 
						memcpy((a)->list + (a)->num, (b)->list, (b)->num * ARRAY_ITEMSIZE(a)) \
 | 
				
			||||||
 | 
						(a)->num += (b)->num;						\
 | 
				
			||||||
 | 
					} while (0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define ARRAY_FREE(a) do {						\
 | 
				
			||||||
 | 
						if ((a)->list != NULL)						\
 | 
				
			||||||
 | 
							xfree((a)->list);					\
 | 
				
			||||||
 | 
						ARRAY_INIT(a);							\
 | 
				
			||||||
 | 
					} while (0)
 | 
				
			||||||
 | 
					#define ARRAY_FREEALL(a) do {						\
 | 
				
			||||||
 | 
						ARRAY_FREE(a);							\
 | 
				
			||||||
 | 
						xfree(a);							\
 | 
				
			||||||
 | 
					} while (0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										92
									
								
								attributes.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								attributes.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,92 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2009 Joshua Elsasser <josh@elsasser.org>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const char *
 | 
				
			||||||
 | 
					attributes_tostring(u_char ch)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						static char	buf[128];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (ch == 0)
 | 
				
			||||||
 | 
							return ("default");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						buf[0] = '\0';
 | 
				
			||||||
 | 
						if (ch & GRID_ATTR_BRIGHT)
 | 
				
			||||||
 | 
							strlcat(buf, "bright,", sizeof (buf));
 | 
				
			||||||
 | 
						if (ch & GRID_ATTR_DIM)
 | 
				
			||||||
 | 
							strlcat(buf, "dim,", sizeof (buf));
 | 
				
			||||||
 | 
						if (ch & GRID_ATTR_UNDERSCORE)
 | 
				
			||||||
 | 
							strlcat(buf, "underscore,", sizeof (buf));
 | 
				
			||||||
 | 
						if (ch & GRID_ATTR_BLINK)
 | 
				
			||||||
 | 
							strlcat(buf, "blink,", sizeof (buf));
 | 
				
			||||||
 | 
						if (ch & GRID_ATTR_REVERSE)
 | 
				
			||||||
 | 
							strlcat(buf, "reverse,", sizeof (buf));
 | 
				
			||||||
 | 
						if (ch & GRID_ATTR_HIDDEN)
 | 
				
			||||||
 | 
							strlcat(buf, "hidden,", sizeof (buf));
 | 
				
			||||||
 | 
						if (ch & GRID_ATTR_ITALICS)
 | 
				
			||||||
 | 
							strlcat(buf, "italics,", sizeof (buf));
 | 
				
			||||||
 | 
						*(strrchr(buf, ',')) = '\0';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (buf);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					attributes_fromstring(const char *str)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const char	delimiters[] = " ,|";
 | 
				
			||||||
 | 
						u_char		ch;
 | 
				
			||||||
 | 
						size_t		end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (*str == '\0' || strcspn(str, delimiters) == 0)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						if (strchr(delimiters, str[strlen(str) - 1]) != NULL)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (strcasecmp(str, "default") == 0)
 | 
				
			||||||
 | 
							return (0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ch = 0;
 | 
				
			||||||
 | 
						do {
 | 
				
			||||||
 | 
							end = strcspn(str, delimiters);
 | 
				
			||||||
 | 
							if ((end == 6 && strncasecmp(str, "bright", end) == 0) ||
 | 
				
			||||||
 | 
							    (end == 4 && strncasecmp(str, "bold", end) == 0))
 | 
				
			||||||
 | 
								ch |= GRID_ATTR_BRIGHT;
 | 
				
			||||||
 | 
							else if (end == 3 && strncasecmp(str, "dim", end) == 0)
 | 
				
			||||||
 | 
								ch |= GRID_ATTR_DIM;
 | 
				
			||||||
 | 
							else if (end == 10 && strncasecmp(str, "underscore", end) == 0)
 | 
				
			||||||
 | 
								ch |= GRID_ATTR_UNDERSCORE;
 | 
				
			||||||
 | 
							else if (end == 5 && strncasecmp(str, "blink", end) == 0)
 | 
				
			||||||
 | 
								ch |= GRID_ATTR_BLINK;
 | 
				
			||||||
 | 
							else if (end == 7 && strncasecmp(str, "reverse", end) == 0)
 | 
				
			||||||
 | 
								ch |= GRID_ATTR_REVERSE;
 | 
				
			||||||
 | 
							else if (end == 6 && strncasecmp(str, "hidden", end) == 0)
 | 
				
			||||||
 | 
								ch |= GRID_ATTR_HIDDEN;
 | 
				
			||||||
 | 
							else if (end == 7 && strncasecmp(str, "italics", end) == 0)
 | 
				
			||||||
 | 
								ch |= GRID_ATTR_ITALICS;
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								return (-1);
 | 
				
			||||||
 | 
							str += end + strspn(str + end, delimiters);
 | 
				
			||||||
 | 
						} while (*str != '\0');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (ch);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										97
									
								
								buffer-poll.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								buffer-poll.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,97 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <errno.h>
 | 
				
			||||||
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Set up pollfd for buffers. */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					buffer_set(
 | 
				
			||||||
 | 
					    struct pollfd *pfd, int fd, unused struct buffer *in, struct buffer *out)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						pfd->fd = fd;
 | 
				
			||||||
 | 
						pfd->events = POLLIN;
 | 
				
			||||||
 | 
						if (BUFFER_USED(out) > 0)
 | 
				
			||||||
 | 
							pfd->events |= POLLOUT;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Fill buffers from socket based on poll results. */
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					buffer_poll(struct pollfd *pfd, struct buffer *in, struct buffer *out)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						ssize_t	n;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if 0
 | 
				
			||||||
 | 
						log_debug("buffer_poll (%ld): fd=%d, revents=%d; out=%zu in=%zu",
 | 
				
			||||||
 | 
						    (long) getpid(),
 | 
				
			||||||
 | 
						    pfd->fd, pfd->revents, BUFFER_USED(out), BUFFER_USED(in));
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (pfd->revents & (POLLERR|POLLNVAL|POLLHUP))
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						if (pfd->revents & POLLIN) {
 | 
				
			||||||
 | 
							buffer_ensure(in, BUFSIZ);
 | 
				
			||||||
 | 
							n = read(pfd->fd, BUFFER_IN(in), BUFFER_FREE(in));
 | 
				
			||||||
 | 
					#if 0
 | 
				
			||||||
 | 
							log_debug("buffer_poll: fd=%d, read=%zd", pfd->fd, n);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
							if (n == 0)
 | 
				
			||||||
 | 
								return (-1);
 | 
				
			||||||
 | 
							if (n == -1) {
 | 
				
			||||||
 | 
								if (errno != EINTR && errno != EAGAIN)
 | 
				
			||||||
 | 
									return (-1);
 | 
				
			||||||
 | 
							} else
 | 
				
			||||||
 | 
								buffer_add(in, n);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (BUFFER_USED(out) > 0 && pfd->revents & POLLOUT) {
 | 
				
			||||||
 | 
							n = write(pfd->fd, BUFFER_OUT(out), BUFFER_USED(out));
 | 
				
			||||||
 | 
					#if 0
 | 
				
			||||||
 | 
							log_debug("buffer_poll: fd=%d, write=%zd", pfd->fd, n);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
							if (n == -1) {
 | 
				
			||||||
 | 
								if (errno != EINTR && errno != EAGAIN)
 | 
				
			||||||
 | 
									return (-1);
 | 
				
			||||||
 | 
							} else
 | 
				
			||||||
 | 
								buffer_remove(out, n);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Flush buffer output to socket. */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					buffer_flush(int fd, struct buffer *in, struct buffer *out)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct pollfd	pfd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while (BUFFER_USED(out) > 0) {
 | 
				
			||||||
 | 
							buffer_set(&pfd, fd, in, out);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (poll(&pfd, 1, INFTIM) == -1) {
 | 
				
			||||||
 | 
								if (errno == EAGAIN || errno == EINTR)
 | 
				
			||||||
 | 
									continue;
 | 
				
			||||||
 | 
								fatal("poll failed");
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (buffer_poll(&pfd, in, out) != 0)
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										227
									
								
								buffer.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										227
									
								
								buffer.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,227 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Create a buffer. */
 | 
				
			||||||
 | 
					struct buffer *
 | 
				
			||||||
 | 
					buffer_create(size_t size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct buffer	*b;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (size == 0)
 | 
				
			||||||
 | 
							fatalx("zero size");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						b = xcalloc(1, sizeof *b);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						b->base = xmalloc(size);
 | 
				
			||||||
 | 
						b->space = size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (b);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Destroy a buffer. */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					buffer_destroy(struct buffer *b)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						xfree(b->base);
 | 
				
			||||||
 | 
						xfree(b);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Empty a buffer. */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					buffer_clear(struct buffer *b)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						b->size = 0;
 | 
				
			||||||
 | 
						b->off = 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Ensure free space for size in buffer. */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					buffer_ensure(struct buffer *b, size_t size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (size == 0)
 | 
				
			||||||
 | 
							fatalx("zero size");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (BUFFER_FREE(b) >= size)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (b->off > 0) {
 | 
				
			||||||
 | 
							if (b->size > 0)
 | 
				
			||||||
 | 
								memmove(b->base, b->base + b->off, b->size);
 | 
				
			||||||
 | 
							b->off = 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (SIZE_MAX - b->size < size)
 | 
				
			||||||
 | 
							fatalx("size too big");
 | 
				
			||||||
 | 
						while (b->space < b->size + size) {
 | 
				
			||||||
 | 
							b->base = xrealloc(b->base, 2, b->space);
 | 
				
			||||||
 | 
							b->space *= 2;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Adjust buffer after data appended. */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					buffer_add(struct buffer *b, size_t size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (size == 0)
 | 
				
			||||||
 | 
							fatalx("zero size");
 | 
				
			||||||
 | 
						if (size > b->space - b->size)
 | 
				
			||||||
 | 
							fatalx("overflow");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						b->size += size;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Reverse buffer add. */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					buffer_reverse_add(struct buffer *b, size_t size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (size == 0)
 | 
				
			||||||
 | 
							fatalx("zero size");
 | 
				
			||||||
 | 
						if (size > b->size)
 | 
				
			||||||
 | 
							fatalx("underflow");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						b->size -= size;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Adjust buffer after data removed. */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					buffer_remove(struct buffer *b, size_t size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (size == 0)
 | 
				
			||||||
 | 
							fatalx("zero size");
 | 
				
			||||||
 | 
						if (size > b->size)
 | 
				
			||||||
 | 
							fatalx("underflow");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						b->size -= size;
 | 
				
			||||||
 | 
						b->off += size;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Reverse buffer remove. */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					buffer_reverse_remove(struct buffer *b, size_t size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (size == 0)
 | 
				
			||||||
 | 
							fatalx("zero size");
 | 
				
			||||||
 | 
						if (size > b->off)
 | 
				
			||||||
 | 
							fatalx("overflow");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						b->size += size;
 | 
				
			||||||
 | 
						b->off -= size;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Insert a section into the buffer. */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					buffer_insert_range(struct buffer *b, size_t base, size_t size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (size == 0)
 | 
				
			||||||
 | 
							fatalx("zero size");
 | 
				
			||||||
 | 
						if (base > b->size)
 | 
				
			||||||
 | 
							fatalx("range outside buffer");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						buffer_ensure(b, size);
 | 
				
			||||||
 | 
						memmove(b->base + b->off + base + size,
 | 
				
			||||||
 | 
						    b->base + b->off + base, b->size - base);
 | 
				
			||||||
 | 
						b->size += size;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Delete a section from the buffer. */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					buffer_delete_range(struct buffer *b, size_t base, size_t size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (size == 0)
 | 
				
			||||||
 | 
							fatalx("zero size");
 | 
				
			||||||
 | 
						if (size > b->size)
 | 
				
			||||||
 | 
							fatalx("size too big");
 | 
				
			||||||
 | 
						if (base + size > b->size)
 | 
				
			||||||
 | 
							fatalx("range outside buffer");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						memmove(b->base + b->off + base,
 | 
				
			||||||
 | 
						    b->base + b->off + base + size, b->size - base - size);
 | 
				
			||||||
 | 
						b->size -= size;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Copy data into a buffer. */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					buffer_write(struct buffer *b, const void *data, size_t size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (size == 0)
 | 
				
			||||||
 | 
							fatalx("zero size");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						buffer_ensure(b, size);
 | 
				
			||||||
 | 
						memcpy(BUFFER_IN(b), data, size);
 | 
				
			||||||
 | 
						buffer_add(b, size);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Copy data out of a buffer. */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					buffer_read(struct buffer *b, void *data, size_t size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (size == 0)
 | 
				
			||||||
 | 
							fatalx("zero size");
 | 
				
			||||||
 | 
						if (size > b->size)
 | 
				
			||||||
 | 
							fatalx("underflow");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						memcpy(data, BUFFER_OUT(b), size);
 | 
				
			||||||
 | 
						buffer_remove(b, size);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Store an 8-bit value. */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					buffer_write8(struct buffer *b, uint8_t n)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						buffer_ensure(b, 1);
 | 
				
			||||||
 | 
						BUFFER_IN(b)[0] = n;
 | 
				
			||||||
 | 
						buffer_add(b, 1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Store a 16-bit value. */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					buffer_write16(struct buffer *b, uint16_t n)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						buffer_ensure(b, 2);
 | 
				
			||||||
 | 
						BUFFER_IN(b)[0] = n & 0xff;
 | 
				
			||||||
 | 
						BUFFER_IN(b)[1] = n >> 8;
 | 
				
			||||||
 | 
						buffer_add(b, 2);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Extract an 8-bit value. */
 | 
				
			||||||
 | 
					uint8_t
 | 
				
			||||||
 | 
					buffer_read8(struct buffer *b)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint8_t	n;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						n = BUFFER_OUT(b)[0];
 | 
				
			||||||
 | 
						buffer_remove(b, 1);
 | 
				
			||||||
 | 
						return (n);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Extract a 16-bit value. */
 | 
				
			||||||
 | 
					uint16_t
 | 
				
			||||||
 | 
					buffer_read16(struct buffer *b)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint16_t	n;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						n = BUFFER_OUT(b)[0] | (BUFFER_OUT(b)[1] << 8);
 | 
				
			||||||
 | 
						buffer_remove(b, 2);
 | 
				
			||||||
 | 
						return (n);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										132
									
								
								cfg.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										132
									
								
								cfg.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,132 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					#include <sys/stat.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <errno.h>
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Config file parser. Pretty quick and simple, each line is parsed into a
 | 
				
			||||||
 | 
					 * argv array and executed as a command.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					char	 *cfg_string(FILE *, char, int);
 | 
				
			||||||
 | 
					void printflike2 cfg_print(struct cmd_ctx *, const char *, ...);
 | 
				
			||||||
 | 
					void printflike2 cfg_error(struct cmd_ctx *, const char *, ...);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					char	 *cfg_cause;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void printflike2
 | 
				
			||||||
 | 
					cfg_print(unused struct cmd_ctx *ctx, unused const char *fmt, ...)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void printflike2
 | 
				
			||||||
 | 
					cfg_error(unused struct cmd_ctx *ctx, const char *fmt, ...)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						va_list	ap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						va_start(ap, fmt);
 | 
				
			||||||
 | 
						xvasprintf(&cfg_cause, fmt, ap);
 | 
				
			||||||
 | 
						va_end(ap);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					load_cfg(const char *path, char **cause)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						FILE   	        *f;
 | 
				
			||||||
 | 
						u_int		 n;
 | 
				
			||||||
 | 
						struct stat	 sb;
 | 
				
			||||||
 | 
						char	        *buf, *line, *ptr;
 | 
				
			||||||
 | 
						size_t		 len;
 | 
				
			||||||
 | 
						struct cmd_list	*cmdlist;
 | 
				
			||||||
 | 
						struct cmd_ctx	 ctx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (stat(path, &sb) != 0) {
 | 
				
			||||||
 | 
							xasprintf(cause, "%s: %s", path, strerror(errno));
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (!S_ISREG(sb.st_mode)) {
 | 
				
			||||||
 | 
							xasprintf(cause, "%s: not a regular file", path);
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((f = fopen(path, "rb")) == NULL) {
 | 
				
			||||||
 | 
							xasprintf(cause, "%s: %s", path, strerror(errno));
 | 
				
			||||||
 | 
							return (1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						n = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						line = NULL;
 | 
				
			||||||
 | 
						while ((buf = fgetln(f, &len))) {
 | 
				
			||||||
 | 
							if (buf[len - 1] == '\n')
 | 
				
			||||||
 | 
								buf[len - 1] = '\0';
 | 
				
			||||||
 | 
							else {
 | 
				
			||||||
 | 
								line = xrealloc(line, 1, len + 1);
 | 
				
			||||||
 | 
								memcpy(line, buf, len);
 | 
				
			||||||
 | 
								line[len] = '\0';
 | 
				
			||||||
 | 
								buf = line;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							n++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (cmd_string_parse(buf, &cmdlist, cause) != 0) {
 | 
				
			||||||
 | 
								if (*cause == NULL)
 | 
				
			||||||
 | 
									continue;
 | 
				
			||||||
 | 
								goto error;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (cmdlist == NULL)
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							cfg_cause = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							ctx.msgdata = NULL;
 | 
				
			||||||
 | 
							ctx.cursession = NULL;
 | 
				
			||||||
 | 
							ctx.curclient = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							ctx.error = cfg_error;
 | 
				
			||||||
 | 
							ctx.print = cfg_print;
 | 
				
			||||||
 | 
							ctx.info = cfg_print;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							ctx.cmdclient = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							cfg_cause = NULL;
 | 
				
			||||||
 | 
							cmd_list_exec(cmdlist, &ctx);
 | 
				
			||||||
 | 
							cmd_list_free(cmdlist);
 | 
				
			||||||
 | 
							if (cfg_cause != NULL) {
 | 
				
			||||||
 | 
								*cause = cfg_cause;
 | 
				
			||||||
 | 
								goto error;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (line != NULL)
 | 
				
			||||||
 | 
							xfree(line);
 | 
				
			||||||
 | 
						fclose(f);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					error:
 | 
				
			||||||
 | 
						fclose(f);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						xasprintf(&ptr, "%s: %s at line %u", path, *cause, n);
 | 
				
			||||||
 | 
						xfree(*cause);
 | 
				
			||||||
 | 
						*cause = ptr;
 | 
				
			||||||
 | 
						return (1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										92
									
								
								client-fn.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								client-fn.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,92 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					client_fill_session(struct msg_command_data *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char		*env, *ptr1, *ptr2, buf[256];
 | 
				
			||||||
 | 
						size_t		 len;
 | 
				
			||||||
 | 
						const char	*errstr;
 | 
				
			||||||
 | 
						long long	 ll;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						data->pid = -1;
 | 
				
			||||||
 | 
						if ((env = getenv("TMUX")) == NULL)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((ptr2 = strrchr(env, ',')) == NULL || ptr2 == env)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						for (ptr1 = ptr2 - 1; ptr1 > env && *ptr1 != ','; ptr1--)
 | 
				
			||||||
 | 
							;
 | 
				
			||||||
 | 
						if (*ptr1 != ',')
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						ptr1++;
 | 
				
			||||||
 | 
						ptr2++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						len = ptr2 - ptr1 - 1;
 | 
				
			||||||
 | 
						if (len > (sizeof buf) - 1)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						memcpy(buf, ptr1, len);
 | 
				
			||||||
 | 
						buf[len] = '\0';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ll = strtonum(buf, 0, LONG_MAX, &errstr);
 | 
				
			||||||
 | 
						if (errstr != NULL)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						data->pid = ll;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ll = strtonum(ptr2, 0, UINT_MAX, &errstr);
 | 
				
			||||||
 | 
						if (errstr != NULL)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						data->idx = ll;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					client_write_server(
 | 
				
			||||||
 | 
					    struct client_ctx *cctx, enum hdrtype type, void *buf, size_t len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct hdr	hdr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						hdr.type = type;
 | 
				
			||||||
 | 
						hdr.size = len;
 | 
				
			||||||
 | 
						buffer_write(cctx->srv_out, &hdr, sizeof hdr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (buf != NULL && len > 0)
 | 
				
			||||||
 | 
							buffer_write(cctx->srv_out, buf, len);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					client_write_server2(struct client_ctx *cctx,
 | 
				
			||||||
 | 
					    enum hdrtype type, void *buf1, size_t len1, void *buf2, size_t len2)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct hdr	hdr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						hdr.type = type;
 | 
				
			||||||
 | 
						hdr.size = len1 + len2;
 | 
				
			||||||
 | 
						buffer_write(cctx->srv_out, &hdr, sizeof hdr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (buf1 != NULL && len1 > 0)
 | 
				
			||||||
 | 
							buffer_write(cctx->srv_out, buf1, len1);
 | 
				
			||||||
 | 
						if (buf2 != NULL && len2 > 0)
 | 
				
			||||||
 | 
							buffer_write(cctx->srv_out, buf2, len2);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										159
									
								
								client-msg.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										159
									
								
								client-msg.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,159 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	client_msg_fn_detach(struct hdr *, struct client_ctx *, char **);
 | 
				
			||||||
 | 
					int	client_msg_fn_error(struct hdr *, struct client_ctx *, char **);
 | 
				
			||||||
 | 
					int	client_msg_fn_shutdown(struct hdr *, struct client_ctx *, char **);
 | 
				
			||||||
 | 
					int	client_msg_fn_exit(struct hdr *, struct client_ctx *, char **);
 | 
				
			||||||
 | 
					int	client_msg_fn_exited(struct hdr *, struct client_ctx *, char **);
 | 
				
			||||||
 | 
					int	client_msg_fn_suspend(struct hdr *, struct client_ctx *, char **);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct client_msg {
 | 
				
			||||||
 | 
						enum hdrtype   type;
 | 
				
			||||||
 | 
						int	       (*fn)(struct hdr *, struct client_ctx *, char **);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					struct client_msg client_msg_table[] = {
 | 
				
			||||||
 | 
						{ MSG_DETACH, client_msg_fn_detach },
 | 
				
			||||||
 | 
						{ MSG_ERROR, client_msg_fn_error },
 | 
				
			||||||
 | 
						{ MSG_EXIT, client_msg_fn_exit },
 | 
				
			||||||
 | 
						{ MSG_EXITED, client_msg_fn_exited },
 | 
				
			||||||
 | 
						{ MSG_SHUTDOWN, client_msg_fn_shutdown },
 | 
				
			||||||
 | 
						{ MSG_SUSPEND, client_msg_fn_suspend },
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					client_msg_dispatch(struct client_ctx *cctx, char **error)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct hdr		 hdr;
 | 
				
			||||||
 | 
						struct client_msg	*msg;
 | 
				
			||||||
 | 
						u_int		 	 i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (BUFFER_USED(cctx->srv_in) < sizeof hdr)
 | 
				
			||||||
 | 
							return (1);
 | 
				
			||||||
 | 
						memcpy(&hdr, BUFFER_OUT(cctx->srv_in), sizeof hdr);
 | 
				
			||||||
 | 
						if (BUFFER_USED(cctx->srv_in) < (sizeof hdr) + hdr.size)
 | 
				
			||||||
 | 
							return (1);
 | 
				
			||||||
 | 
						buffer_remove(cctx->srv_in, sizeof hdr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < nitems(client_msg_table); i++) {
 | 
				
			||||||
 | 
							msg = client_msg_table + i;
 | 
				
			||||||
 | 
							if (msg->type == hdr.type) {
 | 
				
			||||||
 | 
								if (msg->fn(&hdr, cctx, error) != 0)
 | 
				
			||||||
 | 
									return (-1);
 | 
				
			||||||
 | 
								return (0);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						fatalx("unexpected message");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					client_msg_fn_error(struct hdr *hdr, struct client_ctx *cctx, char **error)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (hdr->size > SIZE_MAX - 1)
 | 
				
			||||||
 | 
							fatalx("bad MSG_ERROR size");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						*error = xmalloc(hdr->size + 1);
 | 
				
			||||||
 | 
						buffer_read(cctx->srv_in, *error, hdr->size);
 | 
				
			||||||
 | 
						(*error)[hdr->size] = '\0';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (-1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					client_msg_fn_detach(
 | 
				
			||||||
 | 
					    struct hdr *hdr, unused struct client_ctx *cctx, unused char **error)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (hdr->size != 0)
 | 
				
			||||||
 | 
							fatalx("bad MSG_DETACH size");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						client_write_server(cctx, MSG_EXITING, NULL, 0);
 | 
				
			||||||
 | 
						cctx->flags |= CCTX_DETACH;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					client_msg_fn_shutdown(
 | 
				
			||||||
 | 
					    struct hdr *hdr, unused struct client_ctx *cctx, unused char **error)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (hdr->size != 0)
 | 
				
			||||||
 | 
							fatalx("bad MSG_SHUTDOWN size");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						client_write_server(cctx, MSG_EXITING, NULL, 0);
 | 
				
			||||||
 | 
						cctx->flags |= CCTX_SHUTDOWN;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					client_msg_fn_exit(
 | 
				
			||||||
 | 
					    struct hdr *hdr, unused struct client_ctx *cctx, unused char **error)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (hdr->size != 0)
 | 
				
			||||||
 | 
							fatalx("bad MSG_EXIT size");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						client_write_server(cctx, MSG_EXITING, NULL, 0);
 | 
				
			||||||
 | 
						cctx->flags |= CCTX_EXIT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					client_msg_fn_exited(
 | 
				
			||||||
 | 
					    struct hdr *hdr, unused struct client_ctx *cctx, unused char **error)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (hdr->size != 0)
 | 
				
			||||||
 | 
							fatalx("bad MSG_EXITED size");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (-1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					client_msg_fn_suspend(
 | 
				
			||||||
 | 
					    struct hdr *hdr, unused struct client_ctx *cctx, unused char **error)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct sigaction	 act;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (hdr->size != 0)
 | 
				
			||||||
 | 
							fatalx("bad MSG_SUSPEND size");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						memset(&act, 0, sizeof act);
 | 
				
			||||||
 | 
						sigemptyset(&act.sa_mask);
 | 
				
			||||||
 | 
						act.sa_flags = SA_RESTART;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						act.sa_handler = SIG_DFL;
 | 
				
			||||||
 | 
						if (sigaction(SIGTSTP, &act, NULL) != 0)
 | 
				
			||||||
 | 
							fatal("sigaction failed");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						act.sa_handler = sighandler;
 | 
				
			||||||
 | 
						if (sigaction(SIGCONT, &act, NULL) != 0)
 | 
				
			||||||
 | 
							fatal("sigaction failed");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						kill(getpid(), SIGTSTP);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										226
									
								
								client.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										226
									
								
								client.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,226 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					#include <sys/ioctl.h>
 | 
				
			||||||
 | 
					#include <sys/socket.h>
 | 
				
			||||||
 | 
					#include <sys/stat.h>
 | 
				
			||||||
 | 
					#include <sys/un.h>
 | 
				
			||||||
 | 
					#include <sys/wait.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <errno.h>
 | 
				
			||||||
 | 
					#include <fcntl.h>
 | 
				
			||||||
 | 
					#include <pwd.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <syslog.h>
 | 
				
			||||||
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void	client_handle_winch(struct client_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					client_init(char *path, struct client_ctx *cctx, int start_server, int flags)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct sockaddr_un		sa;
 | 
				
			||||||
 | 
						struct stat			sb;
 | 
				
			||||||
 | 
						struct msg_identify_data	data;
 | 
				
			||||||
 | 
						struct winsize			ws;
 | 
				
			||||||
 | 
						size_t				size;
 | 
				
			||||||
 | 
						int				mode;
 | 
				
			||||||
 | 
						struct buffer		       *b;
 | 
				
			||||||
 | 
						char			       *name;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (lstat(path, &sb) != 0) {
 | 
				
			||||||
 | 
							if (start_server && errno == ENOENT) {
 | 
				
			||||||
 | 
								if ((cctx->srv_fd = server_start(path)) == -1)
 | 
				
			||||||
 | 
									goto start_failed;
 | 
				
			||||||
 | 
								goto server_started;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							goto not_found;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (!S_ISSOCK(sb.st_mode)) {
 | 
				
			||||||
 | 
							errno = ENOTSOCK;
 | 
				
			||||||
 | 
							goto not_found;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						memset(&sa, 0, sizeof sa);
 | 
				
			||||||
 | 
						sa.sun_family = AF_UNIX;
 | 
				
			||||||
 | 
						size = strlcpy(sa.sun_path, path, sizeof sa.sun_path);
 | 
				
			||||||
 | 
						if (size >= sizeof sa.sun_path) {
 | 
				
			||||||
 | 
							errno = ENAMETOOLONG;
 | 
				
			||||||
 | 
							goto not_found;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((cctx->srv_fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
 | 
				
			||||||
 | 
							fatal("socket");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (connect(
 | 
				
			||||||
 | 
						    cctx->srv_fd, (struct sockaddr *) &sa, SUN_LEN(&sa)) == -1) {
 | 
				
			||||||
 | 
							if (errno == ECONNREFUSED) {
 | 
				
			||||||
 | 
								if (unlink(path) != 0 || !start_server)
 | 
				
			||||||
 | 
									goto not_found;
 | 
				
			||||||
 | 
								if ((cctx->srv_fd = server_start(path)) == -1)
 | 
				
			||||||
 | 
									goto start_failed;
 | 
				
			||||||
 | 
								goto server_started;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							goto not_found;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					server_started:
 | 
				
			||||||
 | 
						if ((mode = fcntl(cctx->srv_fd, F_GETFL)) == -1)
 | 
				
			||||||
 | 
							fatal("fcntl failed");
 | 
				
			||||||
 | 
						if (fcntl(cctx->srv_fd, F_SETFL, mode|O_NONBLOCK) == -1)
 | 
				
			||||||
 | 
							fatal("fcntl failed");
 | 
				
			||||||
 | 
						cctx->srv_in = buffer_create(BUFSIZ);
 | 
				
			||||||
 | 
						cctx->srv_out = buffer_create(BUFSIZ);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (isatty(STDIN_FILENO)) {
 | 
				
			||||||
 | 
							if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) == -1)
 | 
				
			||||||
 | 
								fatal("ioctl(TIOCGWINSZ)");
 | 
				
			||||||
 | 
							data.version = PROTOCOL_VERSION;
 | 
				
			||||||
 | 
							data.flags = flags;
 | 
				
			||||||
 | 
							data.sx = ws.ws_col;
 | 
				
			||||||
 | 
							data.sy = ws.ws_row;
 | 
				
			||||||
 | 
							*data.tty = '\0';
 | 
				
			||||||
 | 
							if (getcwd(data.cwd, sizeof data.cwd) == NULL)
 | 
				
			||||||
 | 
								*data.cwd = '\0';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if ((name = ttyname(STDIN_FILENO)) == NULL)
 | 
				
			||||||
 | 
								fatal("ttyname failed");
 | 
				
			||||||
 | 
							if (strlcpy(data.tty, name, sizeof data.tty) >= sizeof data.tty)
 | 
				
			||||||
 | 
								fatalx("ttyname failed");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							b = buffer_create(BUFSIZ);
 | 
				
			||||||
 | 
							cmd_send_string(b, getenv("TERM"));
 | 
				
			||||||
 | 
							client_write_server2(cctx, MSG_IDENTIFY,
 | 
				
			||||||
 | 
							    &data, sizeof data, BUFFER_OUT(b), BUFFER_USED(b));
 | 
				
			||||||
 | 
							buffer_destroy(b);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					start_failed:
 | 
				
			||||||
 | 
						log_warnx("server failed to start");
 | 
				
			||||||
 | 
						return (1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					not_found:
 | 
				
			||||||
 | 
						log_warn("server not found");
 | 
				
			||||||
 | 
						return (1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					client_main(struct client_ctx *cctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct pollfd	 pfd;
 | 
				
			||||||
 | 
						char		*error;
 | 
				
			||||||
 | 
						int		 xtimeout; /* Yay for ncurses namespace! */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						siginit();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						logfile("client");
 | 
				
			||||||
 | 
						setproctitle("client");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						error = NULL;
 | 
				
			||||||
 | 
						xtimeout = INFTIM;
 | 
				
			||||||
 | 
						while (!sigterm) {
 | 
				
			||||||
 | 
							if (sigchld) {
 | 
				
			||||||
 | 
								waitpid(WAIT_ANY, NULL, WNOHANG);
 | 
				
			||||||
 | 
								sigchld = 0;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (sigwinch)
 | 
				
			||||||
 | 
								client_handle_winch(cctx);
 | 
				
			||||||
 | 
							if (sigcont) {
 | 
				
			||||||
 | 
								siginit();
 | 
				
			||||||
 | 
								client_write_server(cctx, MSG_WAKEUP, NULL, 0);
 | 
				
			||||||
 | 
								sigcont = 0;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							switch (client_msg_dispatch(cctx, &error)) {
 | 
				
			||||||
 | 
							case -1:
 | 
				
			||||||
 | 
								goto out;
 | 
				
			||||||
 | 
							case 0:
 | 
				
			||||||
 | 
								/* May be more in buffer, don't let poll block. */
 | 
				
			||||||
 | 
								xtimeout = 0;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								/* Out of data, poll may block. */
 | 
				
			||||||
 | 
								xtimeout = INFTIM;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							pfd.fd = cctx->srv_fd;
 | 
				
			||||||
 | 
							pfd.events = POLLIN;
 | 
				
			||||||
 | 
							if (BUFFER_USED(cctx->srv_out) > 0)
 | 
				
			||||||
 | 
								pfd.events |= POLLOUT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (poll(&pfd, 1, xtimeout) == -1) {
 | 
				
			||||||
 | 
								if (errno == EAGAIN || errno == EINTR)
 | 
				
			||||||
 | 
									continue;
 | 
				
			||||||
 | 
								fatal("poll failed");
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (buffer_poll(&pfd, cctx->srv_in, cctx->srv_out) != 0)
 | 
				
			||||||
 | 
								goto server_dead;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					out:
 | 
				
			||||||
 | 
					 	if (sigterm) {
 | 
				
			||||||
 | 
					 		printf("[terminated]\n");
 | 
				
			||||||
 | 
					 		return (1);
 | 
				
			||||||
 | 
					 	}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (cctx->flags & CCTX_SHUTDOWN) {
 | 
				
			||||||
 | 
							printf("[server exited]\n");
 | 
				
			||||||
 | 
							return (0);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (cctx->flags & CCTX_EXIT) {
 | 
				
			||||||
 | 
							printf("[exited]\n");
 | 
				
			||||||
 | 
							return (0);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (cctx->flags & CCTX_DETACH) {
 | 
				
			||||||
 | 
							printf("[detached]\n");
 | 
				
			||||||
 | 
							return (0);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						printf("[error: %s]\n", error);
 | 
				
			||||||
 | 
						return (1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					server_dead:
 | 
				
			||||||
 | 
						printf("[lost server]\n");
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					client_handle_winch(struct client_ctx *cctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct msg_resize_data	data;
 | 
				
			||||||
 | 
						struct winsize		ws;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) == -1)
 | 
				
			||||||
 | 
							fatal("ioctl failed");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						data.sx = ws.ws_col;
 | 
				
			||||||
 | 
						data.sy = ws.ws_row;
 | 
				
			||||||
 | 
						client_write_server(cctx, MSG_RESIZE, &data, sizeof data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sigwinch = 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										161
									
								
								clock.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										161
									
								
								clock.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,161 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <time.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const char clock_table[14][5][5] = {
 | 
				
			||||||
 | 
						{ { 1,1,1,1,1 }, /* 0 */
 | 
				
			||||||
 | 
						  { 1,0,0,0,1 },
 | 
				
			||||||
 | 
						  { 1,0,0,0,1 },
 | 
				
			||||||
 | 
						  { 1,0,0,0,1 },
 | 
				
			||||||
 | 
						  { 1,1,1,1,1 } },
 | 
				
			||||||
 | 
						{ { 0,0,0,0,1 }, /* 1 */
 | 
				
			||||||
 | 
						  { 0,0,0,0,1 },
 | 
				
			||||||
 | 
						  { 0,0,0,0,1 },
 | 
				
			||||||
 | 
						  { 0,0,0,0,1 },
 | 
				
			||||||
 | 
						  { 0,0,0,0,1 } },
 | 
				
			||||||
 | 
						{ { 1,1,1,1,1 }, /* 2 */
 | 
				
			||||||
 | 
						  { 0,0,0,0,1 },
 | 
				
			||||||
 | 
						  { 1,1,1,1,1 },
 | 
				
			||||||
 | 
						  { 1,0,0,0,0 },
 | 
				
			||||||
 | 
						  { 1,1,1,1,1 } },
 | 
				
			||||||
 | 
						{ { 1,1,1,1,1 }, /* 3 */
 | 
				
			||||||
 | 
						  { 0,0,0,0,1 },
 | 
				
			||||||
 | 
						  { 1,1,1,1,1 },
 | 
				
			||||||
 | 
						  { 0,0,0,0,1 },
 | 
				
			||||||
 | 
						  { 1,1,1,1,1 } },
 | 
				
			||||||
 | 
						{ { 1,0,0,0,1 }, /* 4 */
 | 
				
			||||||
 | 
						  { 1,0,0,0,1 },
 | 
				
			||||||
 | 
						  { 1,1,1,1,1 },
 | 
				
			||||||
 | 
						  { 0,0,0,0,1 },
 | 
				
			||||||
 | 
						  { 0,0,0,0,1 } },
 | 
				
			||||||
 | 
						{ { 1,1,1,1,1 }, /* 5 */
 | 
				
			||||||
 | 
						  { 1,0,0,0,0 },
 | 
				
			||||||
 | 
						  { 1,1,1,1,1 },
 | 
				
			||||||
 | 
						  { 0,0,0,0,1 },
 | 
				
			||||||
 | 
						  { 1,1,1,1,1 } },
 | 
				
			||||||
 | 
						{ { 1,1,1,1,1 }, /* 6 */
 | 
				
			||||||
 | 
						  { 1,0,0,0,0 },
 | 
				
			||||||
 | 
						  { 1,1,1,1,1 },
 | 
				
			||||||
 | 
						  { 1,0,0,0,1 },
 | 
				
			||||||
 | 
						  { 1,1,1,1,1 } },
 | 
				
			||||||
 | 
						{ { 1,1,1,1,1 }, /* 7 */
 | 
				
			||||||
 | 
						  { 0,0,0,0,1 },
 | 
				
			||||||
 | 
						  { 0,0,0,0,1 },
 | 
				
			||||||
 | 
						  { 0,0,0,0,1 },
 | 
				
			||||||
 | 
						  { 0,0,0,0,1 } },
 | 
				
			||||||
 | 
						{ { 1,1,1,1,1 }, /* 8 */
 | 
				
			||||||
 | 
						  { 1,0,0,0,1 },
 | 
				
			||||||
 | 
						  { 1,1,1,1,1 },
 | 
				
			||||||
 | 
						  { 1,0,0,0,1 },
 | 
				
			||||||
 | 
						  { 1,1,1,1,1 } },
 | 
				
			||||||
 | 
						{ { 1,1,1,1,1 }, /* 9 */
 | 
				
			||||||
 | 
						  { 1,0,0,0,1 },
 | 
				
			||||||
 | 
						  { 1,1,1,1,1 },
 | 
				
			||||||
 | 
						  { 0,0,0,0,1 },
 | 
				
			||||||
 | 
						  { 1,1,1,1,1 } },
 | 
				
			||||||
 | 
						{ { 0,0,0,0,0 }, /* : */
 | 
				
			||||||
 | 
						  { 0,0,1,0,0 },
 | 
				
			||||||
 | 
						  { 0,0,0,0,0 },
 | 
				
			||||||
 | 
						  { 0,0,1,0,0 },
 | 
				
			||||||
 | 
						  { 0,0,0,0,0 } },
 | 
				
			||||||
 | 
						{ { 1,1,1,1,1 }, /* A */
 | 
				
			||||||
 | 
						  { 1,0,0,0,1 },
 | 
				
			||||||
 | 
						  { 1,1,1,1,1 },
 | 
				
			||||||
 | 
						  { 1,0,0,0,1 },
 | 
				
			||||||
 | 
						  { 1,0,0,0,1 } },
 | 
				
			||||||
 | 
						{ { 1,1,1,1,1 }, /* P */
 | 
				
			||||||
 | 
						  { 1,0,0,0,1 },
 | 
				
			||||||
 | 
						  { 1,1,1,1,1 },
 | 
				
			||||||
 | 
						  { 1,0,0,0,0 },
 | 
				
			||||||
 | 
						  { 1,0,0,0,0 } },
 | 
				
			||||||
 | 
						{ { 1,0,0,0,1 }, /* M */
 | 
				
			||||||
 | 
						  { 1,1,0,1,1 },
 | 
				
			||||||
 | 
						  { 1,0,1,0,1 },
 | 
				
			||||||
 | 
						  { 1,0,0,0,1 },
 | 
				
			||||||
 | 
						  { 1,0,0,0,1 } },
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					clock_draw(struct screen_write_ctx *ctx, u_int colour, int style)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct screen		*s = ctx->s;
 | 
				
			||||||
 | 
						struct grid_cell	 gc;
 | 
				
			||||||
 | 
						char			 tim[64], *ptr;
 | 
				
			||||||
 | 
						time_t			 t;
 | 
				
			||||||
 | 
						u_int			 i, j, x, y, idx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						t = time(NULL);
 | 
				
			||||||
 | 
						if (style == 0)
 | 
				
			||||||
 | 
							strftime(tim, sizeof tim, "%l:%M %p", localtime(&t));
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							strftime(tim, sizeof tim, "%H:%M", localtime(&t));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						screen_write_clearscreen(ctx);
 | 
				
			||||||
 | 
						memcpy(&gc, &grid_default_cell, sizeof gc);
 | 
				
			||||||
 | 
						gc.fg = colour;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (screen_size_x(s) < 6 * strlen(tim) || screen_size_y(s) < 6) {
 | 
				
			||||||
 | 
							if (screen_size_x(s) >= strlen(tim) && screen_size_y(s) != 0) {
 | 
				
			||||||
 | 
								x = (screen_size_x(s) / 2) - (strlen(tim) / 2);
 | 
				
			||||||
 | 
								y = screen_size_y(s) / 2;
 | 
				
			||||||
 | 
								screen_write_cursormove(ctx, x, y);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								gc.fg = colour;
 | 
				
			||||||
 | 
								screen_write_puts(ctx, &gc, "%s", tim);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						x = (screen_size_x(s) / 2) - 3 * strlen(tim);
 | 
				
			||||||
 | 
						y = (screen_size_y(s) / 2) - 3;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (ptr = tim; *ptr != '\0'; ptr++) {
 | 
				
			||||||
 | 
							if (*ptr >= '0' && *ptr <= '9')
 | 
				
			||||||
 | 
								idx = *ptr - '0';
 | 
				
			||||||
 | 
					 		else if (*ptr == ':')
 | 
				
			||||||
 | 
								idx = 10;
 | 
				
			||||||
 | 
					 		else if (*ptr == 'A')
 | 
				
			||||||
 | 
								idx = 11;
 | 
				
			||||||
 | 
					 		else if (*ptr == 'P')
 | 
				
			||||||
 | 
								idx = 12;
 | 
				
			||||||
 | 
					 		else if (*ptr == 'M')
 | 
				
			||||||
 | 
								idx = 13;
 | 
				
			||||||
 | 
							else {
 | 
				
			||||||
 | 
								x += 6;
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for (j = 0; j < 5; j++) {
 | 
				
			||||||
 | 
								screen_write_cursormove(ctx, x, y + j);
 | 
				
			||||||
 | 
								for (i = 0; i < 5; i++) {
 | 
				
			||||||
 | 
									if (clock_table[idx][j][i])
 | 
				
			||||||
 | 
										gc.attr |= GRID_ATTR_REVERSE;
 | 
				
			||||||
 | 
									else
 | 
				
			||||||
 | 
										gc.attr &= ~GRID_ATTR_REVERSE;
 | 
				
			||||||
 | 
									screen_write_putc(ctx, &gc, ' ');
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							x += 6;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										80
									
								
								cmd-attach-session.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								cmd-attach-session.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,80 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Attach existing session to the current terminal.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_attach_session_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_attach_session_entry = {
 | 
				
			||||||
 | 
						"attach-session", "attach",
 | 
				
			||||||
 | 
						"[-d] " CMD_TARGET_SESSION_USAGE,
 | 
				
			||||||
 | 
					       	CMD_DFLAG|CMD_CANTNEST|CMD_STARTSERVER,
 | 
				
			||||||
 | 
						cmd_target_init,
 | 
				
			||||||
 | 
						cmd_target_parse,
 | 
				
			||||||
 | 
						cmd_attach_session_exec,
 | 
				
			||||||
 | 
						cmd_target_send,
 | 
				
			||||||
 | 
						cmd_target_recv,
 | 
				
			||||||
 | 
						cmd_target_free,
 | 
				
			||||||
 | 
						cmd_target_print
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_attach_session_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_target_data	*data = self->data;
 | 
				
			||||||
 | 
						struct session		*s;
 | 
				
			||||||
 | 
						char			*cause;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (ctx->curclient != NULL)
 | 
				
			||||||
 | 
							return (0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (ARRAY_LENGTH(&sessions) == 0) {
 | 
				
			||||||
 | 
							ctx->error(ctx, "no sessions");
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if ((s = cmd_find_session(ctx, data->target)) == NULL)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!(ctx->cmdclient->flags & CLIENT_TERMINAL)) {
 | 
				
			||||||
 | 
							ctx->error(ctx, "not a terminal");
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (tty_open(&ctx->cmdclient->tty, &cause) != 0) {
 | 
				
			||||||
 | 
							ctx->error(ctx, "terminal open failed: %s", cause);
 | 
				
			||||||
 | 
							xfree(cause);
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (data->flags & CMD_DFLAG)
 | 
				
			||||||
 | 
							server_write_session(s, MSG_DETACH, NULL, 0);
 | 
				
			||||||
 | 
						ctx->cmdclient->session = s;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						server_write_client(ctx->cmdclient, MSG_READY, NULL, 0);
 | 
				
			||||||
 | 
						recalculate_sizes();
 | 
				
			||||||
 | 
						server_redraw_client(ctx->cmdclient);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										157
									
								
								cmd-bind-key.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										157
									
								
								cmd-bind-key.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,157 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Bind a key to a command, this recurses through cmd_*.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_bind_key_parse(struct cmd *, int, char **, char **);
 | 
				
			||||||
 | 
					int	cmd_bind_key_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					void	cmd_bind_key_send(struct cmd *, struct buffer *);
 | 
				
			||||||
 | 
					void	cmd_bind_key_recv(struct cmd *, struct buffer *);
 | 
				
			||||||
 | 
					void	cmd_bind_key_free(struct cmd *);
 | 
				
			||||||
 | 
					size_t	cmd_bind_key_print(struct cmd *, char *, size_t);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct cmd_bind_key_data {
 | 
				
			||||||
 | 
						int		 key;
 | 
				
			||||||
 | 
						int		 can_repeat;
 | 
				
			||||||
 | 
						struct cmd_list	*cmdlist;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_bind_key_entry = {
 | 
				
			||||||
 | 
						"bind-key", "bind",
 | 
				
			||||||
 | 
						"[-r] key command [arguments]",
 | 
				
			||||||
 | 
						0,
 | 
				
			||||||
 | 
						NULL,
 | 
				
			||||||
 | 
						cmd_bind_key_parse,
 | 
				
			||||||
 | 
						cmd_bind_key_exec,
 | 
				
			||||||
 | 
						cmd_bind_key_send,
 | 
				
			||||||
 | 
						cmd_bind_key_recv,
 | 
				
			||||||
 | 
						cmd_bind_key_free,
 | 
				
			||||||
 | 
						cmd_bind_key_print
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_bind_key_parse(struct cmd *self, int argc, char **argv, char **cause)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_bind_key_data	*data;
 | 
				
			||||||
 | 
						int				 opt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						self->data = data = xmalloc(sizeof *data);
 | 
				
			||||||
 | 
						data->can_repeat = 0;
 | 
				
			||||||
 | 
						data->cmdlist = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while ((opt = getopt(argc, argv, "r")) != -1) {
 | 
				
			||||||
 | 
							switch (opt) {
 | 
				
			||||||
 | 
							case 'r':
 | 
				
			||||||
 | 
								data->can_repeat = 1;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								goto usage;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						argc -= optind;
 | 
				
			||||||
 | 
						argv += optind;
 | 
				
			||||||
 | 
						if (argc < 1)
 | 
				
			||||||
 | 
							goto usage;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((data->key = key_string_lookup_string(argv[0])) == KEYC_NONE) {
 | 
				
			||||||
 | 
							xasprintf(cause, "unknown key: %s", argv[0]);
 | 
				
			||||||
 | 
							goto error;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						argc--;
 | 
				
			||||||
 | 
						argv++;
 | 
				
			||||||
 | 
						if ((data->cmdlist = cmd_list_parse(argc, argv, cause)) == NULL)
 | 
				
			||||||
 | 
							goto error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					usage:
 | 
				
			||||||
 | 
						xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					error:
 | 
				
			||||||
 | 
						self->entry->free(self);
 | 
				
			||||||
 | 
						return (-1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_bind_key_exec(struct cmd *self, unused struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_bind_key_data	*data = self->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (data == NULL)
 | 
				
			||||||
 | 
							return (0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						key_bindings_add(data->key, data->can_repeat, data->cmdlist);
 | 
				
			||||||
 | 
						data->cmdlist = NULL;	/* avoid free */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_bind_key_send(struct cmd *self, struct buffer *b)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_bind_key_data	*data = self->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						buffer_write(b, data, sizeof *data);
 | 
				
			||||||
 | 
						cmd_list_send(data->cmdlist, b);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_bind_key_recv(struct cmd *self, struct buffer *b)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_bind_key_data	*data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						self->data = data = xmalloc(sizeof *data);
 | 
				
			||||||
 | 
						buffer_read(b, data, sizeof *data);
 | 
				
			||||||
 | 
						data->cmdlist = cmd_list_recv(b);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_bind_key_free(struct cmd *self)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_bind_key_data	*data = self->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (data->cmdlist != NULL)
 | 
				
			||||||
 | 
							cmd_list_free(data->cmdlist);
 | 
				
			||||||
 | 
						xfree(data);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					size_t
 | 
				
			||||||
 | 
					cmd_bind_key_print(struct cmd *self, char *buf, size_t len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_bind_key_data	*data = self->data;
 | 
				
			||||||
 | 
						size_t				 off = 0;
 | 
				
			||||||
 | 
						const char			*skey;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						off += xsnprintf(buf, len, "%s", self->entry->name);
 | 
				
			||||||
 | 
						if (data == NULL)
 | 
				
			||||||
 | 
							return (off);
 | 
				
			||||||
 | 
						if (off < len) {
 | 
				
			||||||
 | 
							skey = key_string_lookup_key(data->key);
 | 
				
			||||||
 | 
							off += xsnprintf(buf + off, len - off, " %s ", skey);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (off < len)
 | 
				
			||||||
 | 
							off += cmd_list_print(data->cmdlist, buf + off, len - off);
 | 
				
			||||||
 | 
						return (off);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										92
									
								
								cmd-break-pane.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								cmd-break-pane.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,92 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Break pane off into a window.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_break_pane_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_break_pane_entry = {
 | 
				
			||||||
 | 
						"break-pane", "breakp",
 | 
				
			||||||
 | 
						CMD_PANE_WINDOW_USAGE " [-d]",
 | 
				
			||||||
 | 
						CMD_DFLAG,
 | 
				
			||||||
 | 
						cmd_pane_init,
 | 
				
			||||||
 | 
						cmd_pane_parse,
 | 
				
			||||||
 | 
						cmd_break_pane_exec,
 | 
				
			||||||
 | 
					       	cmd_pane_send,
 | 
				
			||||||
 | 
						cmd_pane_recv,
 | 
				
			||||||
 | 
						cmd_pane_free,
 | 
				
			||||||
 | 
						cmd_pane_print
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_break_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_pane_data	*data = self->data;
 | 
				
			||||||
 | 
						struct winlink		*wl;
 | 
				
			||||||
 | 
						struct session		*s;
 | 
				
			||||||
 | 
						struct window_pane	*wp;
 | 
				
			||||||
 | 
						struct window		*w;
 | 
				
			||||||
 | 
						char			*cause;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						if (data->pane == -1)
 | 
				
			||||||
 | 
							wp = wl->window->active;
 | 
				
			||||||
 | 
						else {
 | 
				
			||||||
 | 
							wp = window_pane_at_index(wl->window, data->pane);
 | 
				
			||||||
 | 
							if (wp == NULL) {
 | 
				
			||||||
 | 
								ctx->error(ctx, "no pane: %d", data->pane);
 | 
				
			||||||
 | 
								return (-1);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (window_count_panes(wl->window) == 1) {
 | 
				
			||||||
 | 
							ctx->error(ctx, "can't break pane: %d", data->pane);
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						TAILQ_REMOVE(&wl->window->panes, wp, entry);
 | 
				
			||||||
 | 
						if (wl->window->active == wp) {
 | 
				
			||||||
 | 
							wl->window->active = TAILQ_PREV(wp, window_panes, entry);
 | 
				
			||||||
 | 
							if (wl->window->active == NULL)
 | 
				
			||||||
 | 
								wl->window->active = TAILQ_NEXT(wp, entry);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					 	layout_refresh(wl->window, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 	w = wp->window = window_create1(s->sx, s->sy);
 | 
				
			||||||
 | 
					 	TAILQ_INSERT_HEAD(&w->panes, wp, entry);
 | 
				
			||||||
 | 
					 	w->active = wp;
 | 
				
			||||||
 | 
					 	w->name = default_window_name(w);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 	wl = session_attach(s, w, -1, &cause); /* can't fail */
 | 
				
			||||||
 | 
					 	if (!(data->flags & CMD_DFLAG))
 | 
				
			||||||
 | 
					 		session_select(s, wl->idx);
 | 
				
			||||||
 | 
					 	layout_refresh(w, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						server_redraw_session(s);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										107
									
								
								cmd-choose-session.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								cmd-choose-session.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,107 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Enter choice mode to choose a session.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_choose_session_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void	cmd_choose_session_callback(void *, int);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_choose_session_entry = {
 | 
				
			||||||
 | 
						"choose-session", NULL,
 | 
				
			||||||
 | 
						CMD_TARGET_WINDOW_USAGE,
 | 
				
			||||||
 | 
						0,
 | 
				
			||||||
 | 
						cmd_target_init,
 | 
				
			||||||
 | 
						cmd_target_parse,
 | 
				
			||||||
 | 
						cmd_choose_session_exec,
 | 
				
			||||||
 | 
						cmd_target_send,
 | 
				
			||||||
 | 
						cmd_target_recv,
 | 
				
			||||||
 | 
						cmd_target_free,
 | 
				
			||||||
 | 
						cmd_target_print
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct cmd_choose_session_data {
 | 
				
			||||||
 | 
						u_int	client;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_choose_session_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_target_data		*data = self->data;
 | 
				
			||||||
 | 
						struct cmd_choose_session_data	*cdata;
 | 
				
			||||||
 | 
						struct winlink			*wl;
 | 
				
			||||||
 | 
						struct session			*s;
 | 
				
			||||||
 | 
						u_int			 	 i, idx, cur;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (ctx->curclient == NULL) {
 | 
				
			||||||
 | 
							ctx->error(ctx, "must be run interactively");
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0)
 | 
				
			||||||
 | 
							return (0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cur = idx = 0;
 | 
				
			||||||
 | 
						for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
 | 
				
			||||||
 | 
							s = ARRAY_ITEM(&sessions, i);
 | 
				
			||||||
 | 
							if (s == NULL)
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							if (s == ctx->curclient->session)
 | 
				
			||||||
 | 
								cur = idx;
 | 
				
			||||||
 | 
							idx++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							window_choose_add(wl->window->active, i,
 | 
				
			||||||
 | 
							    "%s: %u windows [%ux%u]%s", s->name,
 | 
				
			||||||
 | 
							    winlink_count(&s->windows), s->sx, s->sy,
 | 
				
			||||||
 | 
							    s->flags & SESSION_UNATTACHED ? "" : " (attached)");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cdata = xmalloc(sizeof *cdata);
 | 
				
			||||||
 | 
						cdata->client = server_client_index(ctx->curclient);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						window_choose_ready(
 | 
				
			||||||
 | 
						    wl->window->active, cur, cmd_choose_session_callback, cdata);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_choose_session_callback(void *data, int idx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_choose_session_data	*cdata = data;
 | 
				
			||||||
 | 
						struct client  			*c;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (idx != -1 && cdata->client <= ARRAY_LENGTH(&clients) - 1) {
 | 
				
			||||||
 | 
							c = ARRAY_ITEM(&clients, cdata->client);
 | 
				
			||||||
 | 
							if (c != NULL && (u_int) idx <= ARRAY_LENGTH(&sessions) - 1) {
 | 
				
			||||||
 | 
								c->session = ARRAY_ITEM(&sessions, idx);
 | 
				
			||||||
 | 
								recalculate_sizes();
 | 
				
			||||||
 | 
								server_redraw_client(c);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						xfree(cdata);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										106
									
								
								cmd-choose-window.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								cmd-choose-window.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,106 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Enter choice mode to choose a window.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_choose_window_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void	cmd_choose_window_callback(void *, int);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_choose_window_entry = {
 | 
				
			||||||
 | 
						"choose-window", NULL,
 | 
				
			||||||
 | 
						CMD_TARGET_WINDOW_USAGE,
 | 
				
			||||||
 | 
						0,
 | 
				
			||||||
 | 
						cmd_target_init,
 | 
				
			||||||
 | 
						cmd_target_parse,
 | 
				
			||||||
 | 
						cmd_choose_window_exec,
 | 
				
			||||||
 | 
						cmd_target_send,
 | 
				
			||||||
 | 
						cmd_target_recv,
 | 
				
			||||||
 | 
						cmd_target_free,
 | 
				
			||||||
 | 
						cmd_target_print
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct cmd_choose_window_data {
 | 
				
			||||||
 | 
						u_int	session;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_choose_window_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_target_data		*data = self->data;
 | 
				
			||||||
 | 
						struct cmd_choose_window_data	*cdata;
 | 
				
			||||||
 | 
						struct session			*s;
 | 
				
			||||||
 | 
						struct winlink			*wl, *wm;
 | 
				
			||||||
 | 
						struct window			*w;
 | 
				
			||||||
 | 
						u_int			 	 idx, cur;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (ctx->curclient == NULL) {
 | 
				
			||||||
 | 
							ctx->error(ctx, "must be run interactively");
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						s = ctx->curclient->session;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0)
 | 
				
			||||||
 | 
							return (0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cur = idx = 0;
 | 
				
			||||||
 | 
						RB_FOREACH(wm, winlinks, &s->windows) {
 | 
				
			||||||
 | 
							w = wm->window;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (wm == s->curw)
 | 
				
			||||||
 | 
								cur = idx;
 | 
				
			||||||
 | 
							idx++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							window_choose_add(wl->window->active,
 | 
				
			||||||
 | 
							    wm->idx, "%3d: %s [%ux%u %s] (%u panes)", wm->idx, w->name,
 | 
				
			||||||
 | 
							    w->sx, w->sy, layout_name(w), window_count_panes(w));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cdata = xmalloc(sizeof *cdata);
 | 
				
			||||||
 | 
						if (session_index(s, &cdata->session) != 0)
 | 
				
			||||||
 | 
							fatalx("session not found");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						window_choose_ready(
 | 
				
			||||||
 | 
						    wl->window->active, cur, cmd_choose_window_callback, cdata);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 	return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_choose_window_callback(void *data, int idx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_choose_window_data	*cdata = data;
 | 
				
			||||||
 | 
						struct session			*s;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (idx != -1 && cdata->session <= ARRAY_LENGTH(&sessions) - 1) {
 | 
				
			||||||
 | 
							s = ARRAY_ITEM(&sessions, cdata->session);
 | 
				
			||||||
 | 
							if (s != NULL && session_select(s, idx) == 0)
 | 
				
			||||||
 | 
								server_redraw_session(s);
 | 
				
			||||||
 | 
							recalculate_sizes();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						xfree(cdata);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										68
									
								
								cmd-clear-history.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								cmd-clear-history.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,68 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Clear pane history.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void	cmd_clear_history_init(struct cmd *, int);
 | 
				
			||||||
 | 
					int	cmd_clear_history_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_clear_history_entry = {
 | 
				
			||||||
 | 
						"clear-history", "clearhist",
 | 
				
			||||||
 | 
						CMD_PANE_WINDOW_USAGE,
 | 
				
			||||||
 | 
						0,
 | 
				
			||||||
 | 
						cmd_pane_init,
 | 
				
			||||||
 | 
						cmd_pane_parse,
 | 
				
			||||||
 | 
						cmd_clear_history_exec,
 | 
				
			||||||
 | 
						cmd_pane_send,
 | 
				
			||||||
 | 
						cmd_pane_recv,
 | 
				
			||||||
 | 
						cmd_pane_free,
 | 
				
			||||||
 | 
						cmd_pane_print
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_clear_history_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_pane_data	*data = self->data;
 | 
				
			||||||
 | 
						struct winlink		*wl;
 | 
				
			||||||
 | 
						struct window_pane	*wp;
 | 
				
			||||||
 | 
						struct grid		*gd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						if (data->pane == -1)
 | 
				
			||||||
 | 
							wp = wl->window->active;
 | 
				
			||||||
 | 
						else {
 | 
				
			||||||
 | 
							wp = window_pane_at_index(wl->window, data->pane);
 | 
				
			||||||
 | 
							if (wp == NULL) {
 | 
				
			||||||
 | 
								ctx->error(ctx, "no pane: %d", data->pane);
 | 
				
			||||||
 | 
								return (-1);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						gd = wp->base.grid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						grid_move_lines(gd, 0, gd->hsize, gd->sy);
 | 
				
			||||||
 | 
						gd->hsize = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										54
									
								
								cmd-clock-mode.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								cmd-clock-mode.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,54 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Enter clock mode.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_clock_mode_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_clock_mode_entry = {
 | 
				
			||||||
 | 
						"clock-mode", NULL,
 | 
				
			||||||
 | 
						CMD_TARGET_WINDOW_USAGE,
 | 
				
			||||||
 | 
						0,
 | 
				
			||||||
 | 
						cmd_target_init,
 | 
				
			||||||
 | 
						cmd_target_parse,
 | 
				
			||||||
 | 
						cmd_clock_mode_exec,
 | 
				
			||||||
 | 
					       	cmd_target_send,
 | 
				
			||||||
 | 
						cmd_target_recv,
 | 
				
			||||||
 | 
						cmd_target_free,
 | 
				
			||||||
 | 
						cmd_target_print
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_clock_mode_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_target_data	*data = self->data;
 | 
				
			||||||
 | 
						struct winlink		*wl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						window_pane_set_mode(wl->window->active, &window_clock_mode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										178
									
								
								cmd-command-prompt.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										178
									
								
								cmd-command-prompt.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,178 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <ctype.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Prompt for command in client.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void	cmd_command_prompt_init(struct cmd *, int);
 | 
				
			||||||
 | 
					int	cmd_command_prompt_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_command_prompt_callback(void *, const char *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_command_prompt_entry = {
 | 
				
			||||||
 | 
						"command-prompt", NULL,
 | 
				
			||||||
 | 
						CMD_TARGET_CLIENT_USAGE " [template]",
 | 
				
			||||||
 | 
						CMD_ARG01,
 | 
				
			||||||
 | 
						cmd_command_prompt_init,
 | 
				
			||||||
 | 
						cmd_target_parse,
 | 
				
			||||||
 | 
						cmd_command_prompt_exec,
 | 
				
			||||||
 | 
						cmd_target_send,
 | 
				
			||||||
 | 
						cmd_target_recv,
 | 
				
			||||||
 | 
						cmd_target_free,
 | 
				
			||||||
 | 
						cmd_target_print
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct cmd_command_prompt_data {
 | 
				
			||||||
 | 
						struct client	*c;
 | 
				
			||||||
 | 
						char		*template;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_command_prompt_init(struct cmd *self, int key)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_target_data	*data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cmd_target_init(self, key);
 | 
				
			||||||
 | 
						data = self->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (key) {
 | 
				
			||||||
 | 
						case ',':
 | 
				
			||||||
 | 
							data->arg = xstrdup("rename-window '%%'");
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case '.':
 | 
				
			||||||
 | 
							data->arg = xstrdup("move-window -t '%%'");
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case 'f':
 | 
				
			||||||
 | 
							data->arg = xstrdup("find-window '%%'");
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_command_prompt_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_target_data		*data = self->data;
 | 
				
			||||||
 | 
						struct cmd_command_prompt_data	*cdata;
 | 
				
			||||||
 | 
						struct client			*c;
 | 
				
			||||||
 | 
						char				*hdr, *ptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((c = cmd_find_client(ctx, data->target)) == NULL)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (c->prompt_string != NULL)
 | 
				
			||||||
 | 
							return (0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cdata = xmalloc(sizeof *cdata);
 | 
				
			||||||
 | 
						cdata->c = c;
 | 
				
			||||||
 | 
						if (data->arg != NULL) {
 | 
				
			||||||
 | 
							cdata->template = xstrdup(data->arg);
 | 
				
			||||||
 | 
							if ((ptr = strchr(data->arg, ' ')) == NULL)
 | 
				
			||||||
 | 
								ptr = strchr(data->arg, '\0');
 | 
				
			||||||
 | 
							xasprintf(&hdr, "(%.*s) ", (int) (ptr - data->arg), data->arg);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							cdata->template = NULL;
 | 
				
			||||||
 | 
							hdr = xstrdup(":");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						status_prompt_set(c, hdr, cmd_command_prompt_callback, cdata, 0);
 | 
				
			||||||
 | 
						xfree(hdr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_command_prompt_callback(void *data, const char *s)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_command_prompt_data	*cdata = data;
 | 
				
			||||||
 | 
						struct client			*c = cdata->c;
 | 
				
			||||||
 | 
						struct cmd_list			*cmdlist;
 | 
				
			||||||
 | 
						struct cmd_ctx	 		 ctx;
 | 
				
			||||||
 | 
						char				*cause, *ptr, *buf, ch;
 | 
				
			||||||
 | 
						size_t				 len, slen;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (s == NULL) {
 | 
				
			||||||
 | 
							xfree(cdata);
 | 
				
			||||||
 | 
							return (0);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						slen = strlen(s);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						len = 0;
 | 
				
			||||||
 | 
						buf = NULL;
 | 
				
			||||||
 | 
						if (cdata->template != NULL) {
 | 
				
			||||||
 | 
							ptr = cdata->template;
 | 
				
			||||||
 | 
							while (*ptr != '\0') {
 | 
				
			||||||
 | 
								switch (ch = *ptr++) {
 | 
				
			||||||
 | 
								case '%':
 | 
				
			||||||
 | 
									if (*ptr != '%')
 | 
				
			||||||
 | 
										break;
 | 
				
			||||||
 | 
									ptr++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									buf = xrealloc(buf, 1, len + slen + 1);
 | 
				
			||||||
 | 
									memcpy(buf + len, s, slen);
 | 
				
			||||||
 | 
									len += slen;
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								default:
 | 
				
			||||||
 | 
									buf = xrealloc(buf, 1, len + 2);
 | 
				
			||||||
 | 
									buf[len++] = ch;
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							xfree(cdata->template);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							buf[len] = '\0';
 | 
				
			||||||
 | 
							s = buf;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						xfree(cdata);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (cmd_string_parse(s, &cmdlist, &cause) != 0) {
 | 
				
			||||||
 | 
							if (cause == NULL)
 | 
				
			||||||
 | 
								return (0);
 | 
				
			||||||
 | 
							*cause = toupper((u_char) *cause);
 | 
				
			||||||
 | 
							status_message_set(c, cause);
 | 
				
			||||||
 | 
							xfree(cause);
 | 
				
			||||||
 | 
							cmdlist = NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (buf != NULL)
 | 
				
			||||||
 | 
							xfree(buf);
 | 
				
			||||||
 | 
						if (cmdlist == NULL)
 | 
				
			||||||
 | 
							return (0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ctx.msgdata = NULL;
 | 
				
			||||||
 | 
						ctx.cursession = c->session;
 | 
				
			||||||
 | 
						ctx.curclient = c;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ctx.error = key_bindings_error;
 | 
				
			||||||
 | 
						ctx.print = key_bindings_print;
 | 
				
			||||||
 | 
						ctx.info = key_bindings_info;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ctx.cmdclient = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cmd_list_exec(cmdlist, &ctx);
 | 
				
			||||||
 | 
						cmd_list_free(cmdlist);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (c->prompt_callback != (void *) &cmd_command_prompt_callback)
 | 
				
			||||||
 | 
							return (1);
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										141
									
								
								cmd-confirm-before.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										141
									
								
								cmd-confirm-before.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,141 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <ctype.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Asks for confirmation before executing a command.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_confirm_before_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					void	cmd_confirm_before_init(struct cmd *, int);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_confirm_before_callback(void *, const char *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct cmd_confirm_before_data {
 | 
				
			||||||
 | 
						struct client	*c;
 | 
				
			||||||
 | 
						char		*cmd;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_confirm_before_entry = {
 | 
				
			||||||
 | 
						"confirm-before", "confirm",
 | 
				
			||||||
 | 
						CMD_TARGET_CLIENT_USAGE " command",
 | 
				
			||||||
 | 
						CMD_ARG1,
 | 
				
			||||||
 | 
						cmd_confirm_before_init,
 | 
				
			||||||
 | 
						cmd_target_parse,
 | 
				
			||||||
 | 
						cmd_confirm_before_exec,
 | 
				
			||||||
 | 
						cmd_target_send,
 | 
				
			||||||
 | 
						cmd_target_recv,
 | 
				
			||||||
 | 
						cmd_target_free,
 | 
				
			||||||
 | 
						cmd_target_print
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_confirm_before_init(struct cmd *self, int key)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_target_data	*data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cmd_target_init(self, key);
 | 
				
			||||||
 | 
						data = self->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (key) {
 | 
				
			||||||
 | 
						case '&':
 | 
				
			||||||
 | 
							data->arg = xstrdup("kill-window");
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case 'x':
 | 
				
			||||||
 | 
							data->arg = xstrdup("kill-pane");
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_confirm_before_exec(unused struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_target_data		*data = self->data;
 | 
				
			||||||
 | 
						struct cmd_confirm_before_data	*cdata;
 | 
				
			||||||
 | 
						struct client			*c;
 | 
				
			||||||
 | 
						char				*buf, *cmd, *ptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (ctx->curclient == NULL) {
 | 
				
			||||||
 | 
							ctx->error(ctx, "must be run interactively");
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((c = cmd_find_client(ctx, data->target)) == NULL)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ptr = xstrdup(data->arg);
 | 
				
			||||||
 | 
						if ((cmd = strtok(ptr, " \t")) == NULL)
 | 
				
			||||||
 | 
							cmd = ptr;
 | 
				
			||||||
 | 
						xasprintf(&buf, "Confirm '%s'? (y/n) ", cmd);
 | 
				
			||||||
 | 
						xfree(ptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cdata = xmalloc(sizeof *cdata);
 | 
				
			||||||
 | 
						cdata->cmd = xstrdup(data->arg);
 | 
				
			||||||
 | 
						cdata->c = c;
 | 
				
			||||||
 | 
						status_prompt_set(
 | 
				
			||||||
 | 
						    cdata->c, buf, cmd_confirm_before_callback, cdata, PROMPT_SINGLE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						xfree(buf);
 | 
				
			||||||
 | 
						return (1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_confirm_before_callback(void *data, const char *s)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_confirm_before_data	*cdata = data;
 | 
				
			||||||
 | 
						struct client			*c = cdata->c;
 | 
				
			||||||
 | 
						struct cmd_list			*cmdlist;
 | 
				
			||||||
 | 
						struct cmd_ctx	 	 	 ctx;
 | 
				
			||||||
 | 
						char				*cause;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (s == NULL || tolower((u_char) s[0]) != 'y' || s[1] != '\0')
 | 
				
			||||||
 | 
							goto out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (cmd_string_parse(cdata->cmd, &cmdlist, &cause) != 0) {
 | 
				
			||||||
 | 
							if (cause != NULL) {
 | 
				
			||||||
 | 
								*cause = toupper((u_char) *cause);
 | 
				
			||||||
 | 
								status_message_set(c, cause);
 | 
				
			||||||
 | 
								xfree(cause);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							goto out;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ctx.msgdata = NULL;
 | 
				
			||||||
 | 
						ctx.cursession = c->session;
 | 
				
			||||||
 | 
						ctx.curclient = c;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ctx.error = key_bindings_error;
 | 
				
			||||||
 | 
						ctx.print = key_bindings_print;
 | 
				
			||||||
 | 
						ctx.info = key_bindings_info;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ctx.cmdclient = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cmd_list_exec(cmdlist, &ctx);
 | 
				
			||||||
 | 
						cmd_list_free(cmdlist);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					out:
 | 
				
			||||||
 | 
						if (cdata->cmd != NULL)
 | 
				
			||||||
 | 
							xfree(cdata->cmd);
 | 
				
			||||||
 | 
						xfree(cdata);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										222
									
								
								cmd-copy-buffer.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										222
									
								
								cmd-copy-buffer.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,222 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copies a session paste buffer to another session.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_copy_buffer_parse(struct cmd *, int, char **, char **);
 | 
				
			||||||
 | 
					int	cmd_copy_buffer_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					void	cmd_copy_buffer_send(struct cmd *, struct buffer *);
 | 
				
			||||||
 | 
					void	cmd_copy_buffer_recv(struct cmd *, struct buffer *);
 | 
				
			||||||
 | 
					void	cmd_copy_buffer_free(struct cmd *);
 | 
				
			||||||
 | 
					void	cmd_copy_buffer_init(struct cmd *, int);
 | 
				
			||||||
 | 
					size_t	cmd_copy_buffer_print(struct cmd *, char *, size_t);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct cmd_copy_buffer_data {
 | 
				
			||||||
 | 
						char	*dst_session;
 | 
				
			||||||
 | 
						char	*src_session;
 | 
				
			||||||
 | 
						int	 dst_idx;
 | 
				
			||||||
 | 
						int	 src_idx;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_copy_buffer_entry = {
 | 
				
			||||||
 | 
						"copy-buffer", "copyb",
 | 
				
			||||||
 | 
						"[-a src-index] [-b dst-index] [-s src-session] [-t dst-session]",
 | 
				
			||||||
 | 
						0,
 | 
				
			||||||
 | 
						cmd_copy_buffer_init,
 | 
				
			||||||
 | 
						cmd_copy_buffer_parse,
 | 
				
			||||||
 | 
						cmd_copy_buffer_exec,
 | 
				
			||||||
 | 
						cmd_copy_buffer_send,
 | 
				
			||||||
 | 
						cmd_copy_buffer_recv,
 | 
				
			||||||
 | 
						cmd_copy_buffer_free,
 | 
				
			||||||
 | 
						cmd_copy_buffer_print
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_copy_buffer_init(struct cmd *self, unused int arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_copy_buffer_data	*data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						self->data = data = xmalloc(sizeof *data);
 | 
				
			||||||
 | 
						data->dst_session = NULL;
 | 
				
			||||||
 | 
						data->src_session = NULL;
 | 
				
			||||||
 | 
						data->dst_idx = -1;
 | 
				
			||||||
 | 
						data->src_idx = -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_copy_buffer_parse(struct cmd *self, int argc, char **argv, char **cause)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_copy_buffer_data	*data;
 | 
				
			||||||
 | 
						const char			*errstr;
 | 
				
			||||||
 | 
						int				 n, opt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						self->entry->init(self, 0);
 | 
				
			||||||
 | 
						data = self->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while ((opt = getopt(argc, argv, "a:b:s:t:")) != -1) {
 | 
				
			||||||
 | 
							switch (opt) {
 | 
				
			||||||
 | 
							case 'a':
 | 
				
			||||||
 | 
								if (data->src_idx == -1) {
 | 
				
			||||||
 | 
									n = strtonum(optarg, 0, INT_MAX, &errstr);
 | 
				
			||||||
 | 
									if (errstr != NULL) {
 | 
				
			||||||
 | 
										xasprintf(cause, "buffer %s", errstr);
 | 
				
			||||||
 | 
										goto error;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									data->src_idx = n;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case 'b':
 | 
				
			||||||
 | 
								if (data->dst_idx == -1) {
 | 
				
			||||||
 | 
									n = strtonum(optarg, 0, INT_MAX, &errstr);
 | 
				
			||||||
 | 
									if (errstr != NULL) {
 | 
				
			||||||
 | 
										xasprintf(cause, "buffer %s", errstr);
 | 
				
			||||||
 | 
										goto error;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									data->dst_idx = n;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case 's':
 | 
				
			||||||
 | 
								if (data->src_session == NULL)
 | 
				
			||||||
 | 
									data->src_session = xstrdup(optarg);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case 't':
 | 
				
			||||||
 | 
								if (data->dst_session == NULL)
 | 
				
			||||||
 | 
									data->dst_session = xstrdup(optarg);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								goto usage;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						argc -= optind;
 | 
				
			||||||
 | 
						argv += optind;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					usage:
 | 
				
			||||||
 | 
						xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					error:
 | 
				
			||||||
 | 
						self->entry->free(self);
 | 
				
			||||||
 | 
						return (-1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_copy_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_copy_buffer_data	*data = self->data;
 | 
				
			||||||
 | 
						struct paste_buffer		*pb;
 | 
				
			||||||
 | 
						struct session			*dst_session, *src_session;
 | 
				
			||||||
 | 
						u_int				 limit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((dst_session = cmd_find_session(ctx, data->dst_session)) == NULL ||
 | 
				
			||||||
 | 
						    (src_session = cmd_find_session(ctx, data->src_session)) == NULL)
 | 
				
			||||||
 | 
						    	return (-1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (data->src_idx == -1) {
 | 
				
			||||||
 | 
							if ((pb = paste_get_top(&src_session->buffers)) == NULL) {
 | 
				
			||||||
 | 
								ctx->error(ctx, "no buffers");
 | 
				
			||||||
 | 
								return (-1);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							if ((pb = paste_get_index(&src_session->buffers,
 | 
				
			||||||
 | 
							    data->src_idx)) == NULL) {
 | 
				
			||||||
 | 
							    	ctx->error(ctx, "no buffer %d", data->src_idx);
 | 
				
			||||||
 | 
							    	return (-1);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						limit = options_get_number(&dst_session->options, "buffer-limit");
 | 
				
			||||||
 | 
						if (data->dst_idx == -1) {
 | 
				
			||||||
 | 
							paste_add(&dst_session->buffers, xstrdup(pb->data), limit);
 | 
				
			||||||
 | 
							return (0);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (paste_replace(&dst_session->buffers, data->dst_idx,
 | 
				
			||||||
 | 
						    xstrdup(pb->data)) != 0) {
 | 
				
			||||||
 | 
							ctx->error(ctx, "no buffer %d", data->dst_idx);
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_copy_buffer_send(struct cmd *self, struct buffer *b)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_copy_buffer_data	*data = self->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						buffer_write(b, data, sizeof *data);
 | 
				
			||||||
 | 
						cmd_send_string(b, data->dst_session);
 | 
				
			||||||
 | 
						cmd_send_string(b, data->src_session);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_copy_buffer_recv(struct cmd *self, struct buffer *b)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_copy_buffer_data	*data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						self->data = data = xmalloc(sizeof *data);
 | 
				
			||||||
 | 
						buffer_read(b, data, sizeof *data);
 | 
				
			||||||
 | 
						data->dst_session = cmd_recv_string(b);
 | 
				
			||||||
 | 
						data->src_session = cmd_recv_string(b);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_copy_buffer_free(struct cmd *self)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_copy_buffer_data	*data = self->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (data->dst_session != NULL)
 | 
				
			||||||
 | 
							xfree(data->dst_session);
 | 
				
			||||||
 | 
						if (data->src_session != NULL)
 | 
				
			||||||
 | 
							xfree(data->src_session);
 | 
				
			||||||
 | 
						xfree(data);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					size_t
 | 
				
			||||||
 | 
					cmd_copy_buffer_print(struct cmd *self, char *buf, size_t len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_copy_buffer_data	*data = self->data;
 | 
				
			||||||
 | 
						size_t				off = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						off += xsnprintf(buf, len, "%s", self->entry->name);
 | 
				
			||||||
 | 
						if (data == NULL)
 | 
				
			||||||
 | 
							return (off);
 | 
				
			||||||
 | 
						if (off < len && data->src_idx != -1) {
 | 
				
			||||||
 | 
							off += xsnprintf(buf + off, len - off, " -a %d",
 | 
				
			||||||
 | 
									 data->src_idx);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (off < len && data->dst_idx != -1) {
 | 
				
			||||||
 | 
							off += xsnprintf(buf + off, len - off, " -b %d",
 | 
				
			||||||
 | 
									 data->dst_idx);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (off < len && data->src_session != NULL) {
 | 
				
			||||||
 | 
							off += cmd_prarg(buf + off, len - off, " -s ",
 | 
				
			||||||
 | 
									 data->src_session);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (off < len && data->dst_session != NULL) {
 | 
				
			||||||
 | 
							off += cmd_prarg(buf + off, len - off, " -t ",
 | 
				
			||||||
 | 
									 data->dst_session);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return (off);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										56
									
								
								cmd-copy-mode.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								cmd-copy-mode.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,56 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Enter copy mode.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_copy_mode_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_copy_mode_entry = {
 | 
				
			||||||
 | 
						"copy-mode", NULL,
 | 
				
			||||||
 | 
						CMD_TARGET_WINDOW_USAGE,
 | 
				
			||||||
 | 
						CMD_UFLAG,
 | 
				
			||||||
 | 
						cmd_target_init,
 | 
				
			||||||
 | 
						cmd_target_parse,
 | 
				
			||||||
 | 
						cmd_copy_mode_exec,
 | 
				
			||||||
 | 
						cmd_target_send,
 | 
				
			||||||
 | 
						cmd_target_recv,
 | 
				
			||||||
 | 
						cmd_target_free,
 | 
				
			||||||
 | 
						NULL
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_copy_mode_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_target_data	*data = self->data;
 | 
				
			||||||
 | 
						struct winlink		*wl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						window_pane_set_mode(wl->window->active, &window_copy_mode);
 | 
				
			||||||
 | 
						if (data->flags & CMD_UFLAG)
 | 
				
			||||||
 | 
							window_copy_pageup(wl->window->active);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										61
									
								
								cmd-delete-buffer.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								cmd-delete-buffer.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,61 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Delete a paste buffer.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_delete_buffer_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_delete_buffer_entry = {
 | 
				
			||||||
 | 
						"delete-buffer", "deleteb",
 | 
				
			||||||
 | 
						CMD_BUFFER_SESSION_USAGE,
 | 
				
			||||||
 | 
						0,
 | 
				
			||||||
 | 
						cmd_buffer_init,
 | 
				
			||||||
 | 
						cmd_buffer_parse,
 | 
				
			||||||
 | 
						cmd_delete_buffer_exec,
 | 
				
			||||||
 | 
						cmd_buffer_send,
 | 
				
			||||||
 | 
						cmd_buffer_recv,
 | 
				
			||||||
 | 
						cmd_buffer_free,
 | 
				
			||||||
 | 
						cmd_buffer_print
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_delete_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_buffer_data	*data = self->data;
 | 
				
			||||||
 | 
						struct session		*s;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((s = cmd_find_session(ctx, data->target)) == NULL)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (data->buffer == -1)
 | 
				
			||||||
 | 
							paste_free_top(&s->buffers);
 | 
				
			||||||
 | 
						else if (paste_free_index(&s->buffers, data->buffer) != 0) {
 | 
				
			||||||
 | 
							ctx->error(ctx, "no buffer %d", data->buffer);
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										54
									
								
								cmd-detach-client.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								cmd-detach-client.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,54 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Detach a client.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_detach_client_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_detach_client_entry = {
 | 
				
			||||||
 | 
						"detach-client", "detach",
 | 
				
			||||||
 | 
						CMD_TARGET_CLIENT_USAGE,
 | 
				
			||||||
 | 
						0,
 | 
				
			||||||
 | 
						cmd_target_init,
 | 
				
			||||||
 | 
						cmd_target_parse,
 | 
				
			||||||
 | 
						cmd_detach_client_exec,
 | 
				
			||||||
 | 
						cmd_target_send,
 | 
				
			||||||
 | 
						cmd_target_recv,
 | 
				
			||||||
 | 
						cmd_target_free,
 | 
				
			||||||
 | 
						cmd_target_print
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_detach_client_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_target_data	*data = self->data;
 | 
				
			||||||
 | 
						struct client		*c;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((c = cmd_find_client(ctx, data->target)) == NULL)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						server_write_client(c, MSG_DETACH, NULL, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										61
									
								
								cmd-down-pane.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								cmd-down-pane.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,61 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Move down a pane.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_down_pane_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_down_pane_entry = {
 | 
				
			||||||
 | 
						"down-pane", "downp",
 | 
				
			||||||
 | 
						CMD_TARGET_WINDOW_USAGE,
 | 
				
			||||||
 | 
						0,
 | 
				
			||||||
 | 
						cmd_target_init,
 | 
				
			||||||
 | 
						cmd_target_parse,
 | 
				
			||||||
 | 
						cmd_down_pane_exec,
 | 
				
			||||||
 | 
						cmd_target_send,
 | 
				
			||||||
 | 
						cmd_target_recv,
 | 
				
			||||||
 | 
						cmd_target_free,
 | 
				
			||||||
 | 
						cmd_target_print
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_down_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_target_data	*data = self->data;
 | 
				
			||||||
 | 
						struct winlink		*wl;
 | 
				
			||||||
 | 
						struct window		*w;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						w = wl->window;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						do {
 | 
				
			||||||
 | 
							w->active = TAILQ_NEXT(w->active, entry);
 | 
				
			||||||
 | 
							if (w->active == NULL)
 | 
				
			||||||
 | 
								w->active = TAILQ_FIRST(&w->panes);
 | 
				
			||||||
 | 
							layout_refresh(w, 1);
 | 
				
			||||||
 | 
						} while (w->active->flags & PANE_HIDDEN);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										160
									
								
								cmd-find-window.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										160
									
								
								cmd-find-window.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,160 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Find window containing text.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_find_window_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void	cmd_find_window_callback(void *, int);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_find_window_entry = {
 | 
				
			||||||
 | 
						"find-window", "findw",
 | 
				
			||||||
 | 
						CMD_TARGET_WINDOW_USAGE " match-string",
 | 
				
			||||||
 | 
						CMD_ARG1,
 | 
				
			||||||
 | 
						cmd_target_init,
 | 
				
			||||||
 | 
						cmd_target_parse,
 | 
				
			||||||
 | 
						cmd_find_window_exec,
 | 
				
			||||||
 | 
						cmd_target_send,
 | 
				
			||||||
 | 
						cmd_target_recv,
 | 
				
			||||||
 | 
						cmd_target_free,
 | 
				
			||||||
 | 
						cmd_target_print
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct cmd_find_window_data {
 | 
				
			||||||
 | 
						u_int	session;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_find_window_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_target_data		*data = self->data;
 | 
				
			||||||
 | 
						struct cmd_find_window_data	*cdata;
 | 
				
			||||||
 | 
						struct session			*s;
 | 
				
			||||||
 | 
						struct winlink			*wl, *wm;
 | 
				
			||||||
 | 
						struct window			*w;
 | 
				
			||||||
 | 
						struct window_pane		*wp;
 | 
				
			||||||
 | 
						ARRAY_DECL(, u_int)	 	 list_idx;
 | 
				
			||||||
 | 
						ARRAY_DECL(, char *)	 	 list_ctx;
 | 
				
			||||||
 | 
						char				*sres, *sctx;
 | 
				
			||||||
 | 
						u_int				 i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (ctx->curclient == NULL) {
 | 
				
			||||||
 | 
							ctx->error(ctx, "must be run interactively");
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						s = ctx->curclient->session;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ARRAY_INIT(&list_idx);
 | 
				
			||||||
 | 
						ARRAY_INIT(&list_ctx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						RB_FOREACH(wm, winlinks, &s->windows) {
 | 
				
			||||||
 | 
							i = 0;
 | 
				
			||||||
 | 
							TAILQ_FOREACH(wp, &wm->window->panes, entry) {
 | 
				
			||||||
 | 
								i++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (strstr(wm->window->name, data->arg) != NULL)
 | 
				
			||||||
 | 
									sctx = xstrdup("");
 | 
				
			||||||
 | 
								else {
 | 
				
			||||||
 | 
									sres = window_pane_search(wp, data->arg);
 | 
				
			||||||
 | 
									if (sres == NULL &&
 | 
				
			||||||
 | 
									    strstr(wp->base.title, data->arg) == NULL)
 | 
				
			||||||
 | 
										continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									if (sres == NULL) {
 | 
				
			||||||
 | 
										xasprintf(&sctx,
 | 
				
			||||||
 | 
										    "pane %u title: \"%s\"", i - 1,
 | 
				
			||||||
 | 
										    wp->base.title);
 | 
				
			||||||
 | 
									} else {
 | 
				
			||||||
 | 
										xasprintf(&sctx, "\"%s\"", sres);
 | 
				
			||||||
 | 
										xfree(sres);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								ARRAY_ADD(&list_idx, wm->idx);
 | 
				
			||||||
 | 
								ARRAY_ADD(&list_ctx, sctx);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (ARRAY_LENGTH(&list_idx) == 0) {
 | 
				
			||||||
 | 
							ctx->error(ctx, "no windows matching: %s", data->arg);
 | 
				
			||||||
 | 
							ARRAY_FREE(&list_idx);
 | 
				
			||||||
 | 
							ARRAY_FREE(&list_ctx);
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (ARRAY_LENGTH(&list_idx) == 1) {
 | 
				
			||||||
 | 
							if (session_select(s, ARRAY_FIRST(&list_idx)) == 0)
 | 
				
			||||||
 | 
								server_redraw_session(s);
 | 
				
			||||||
 | 
							recalculate_sizes();
 | 
				
			||||||
 | 
							goto out;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0)
 | 
				
			||||||
 | 
							goto out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < ARRAY_LENGTH(&list_idx); i++) {
 | 
				
			||||||
 | 
							wm = winlink_find_by_index(
 | 
				
			||||||
 | 
							    &s->windows, ARRAY_ITEM(&list_idx, i));
 | 
				
			||||||
 | 
							w = wm->window;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							sctx = ARRAY_ITEM(&list_ctx, i);
 | 
				
			||||||
 | 
							window_choose_add(wl->window->active,
 | 
				
			||||||
 | 
							    wm->idx, "%3d: %s [%ux%u] (%u panes) %s", wm->idx, w->name,
 | 
				
			||||||
 | 
							    w->sx, w->sy, window_count_panes(w), sctx);
 | 
				
			||||||
 | 
							xfree(sctx);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cdata = xmalloc(sizeof *cdata);
 | 
				
			||||||
 | 
						if (session_index(s, &cdata->session) != 0)
 | 
				
			||||||
 | 
							fatalx("session not found");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						window_choose_ready(
 | 
				
			||||||
 | 
						    wl->window->active, 0, cmd_find_window_callback, cdata);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					out:
 | 
				
			||||||
 | 
						ARRAY_FREE(&list_idx);
 | 
				
			||||||
 | 
						ARRAY_FREE(&list_ctx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_find_window_callback(void *data, int idx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_find_window_data	*cdata = data;
 | 
				
			||||||
 | 
						struct session			*s;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (idx != -1 && cdata->session <= ARRAY_LENGTH(&sessions) - 1) {
 | 
				
			||||||
 | 
							s = ARRAY_ITEM(&sessions, cdata->session);
 | 
				
			||||||
 | 
							if (s != NULL && session_select(s, idx) == 0)
 | 
				
			||||||
 | 
								server_redraw_session(s);
 | 
				
			||||||
 | 
							recalculate_sizes();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						xfree(cdata);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										694
									
								
								cmd-generic.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										694
									
								
								cmd-generic.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,694 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define CMD_FLAGS "adDgkuU"
 | 
				
			||||||
 | 
					#define CMD_FLAGMASK (CMD_AFLAG|CMD_DFLAG|CMD_BIGDFLAG|CMD_GFLAG|CMD_KFLAG| \
 | 
				
			||||||
 | 
					    CMD_UFLAG|CMD_BIGUFLAG)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_do_flags(int, int, int *);
 | 
				
			||||||
 | 
					size_t	cmd_print_flags(char *, size_t, size_t, int);
 | 
				
			||||||
 | 
					int	cmd_fill_argument(int, char **, int, char **);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					size_t
 | 
				
			||||||
 | 
					cmd_prarg(char *buf, size_t len, const char *prefix, char *arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (strchr(arg, ' ') != NULL)
 | 
				
			||||||
 | 
							return (xsnprintf(buf, len, "%s\"%s\"", prefix, arg));
 | 
				
			||||||
 | 
						return (xsnprintf(buf, len, "%s%s", prefix, arg));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_do_flags(int opt, int iflags, int *oflags)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						switch (opt) {
 | 
				
			||||||
 | 
						case 'a':
 | 
				
			||||||
 | 
							if (iflags & CMD_AFLAG) {
 | 
				
			||||||
 | 
								(*oflags) |= CMD_AFLAG;
 | 
				
			||||||
 | 
								return (0);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						case 'd':
 | 
				
			||||||
 | 
							if (iflags & CMD_DFLAG) {
 | 
				
			||||||
 | 
								(*oflags) |= CMD_DFLAG;
 | 
				
			||||||
 | 
								return (0);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						case 'D':
 | 
				
			||||||
 | 
							if (iflags & CMD_BIGDFLAG) {
 | 
				
			||||||
 | 
								(*oflags) |= CMD_BIGDFLAG;
 | 
				
			||||||
 | 
								return (0);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						case 'g':
 | 
				
			||||||
 | 
							if (iflags & CMD_GFLAG) {
 | 
				
			||||||
 | 
								(*oflags) |= CMD_GFLAG;
 | 
				
			||||||
 | 
								return (0);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						case 'k':
 | 
				
			||||||
 | 
							if (iflags & CMD_KFLAG) {
 | 
				
			||||||
 | 
								(*oflags) |= CMD_KFLAG;
 | 
				
			||||||
 | 
								return (0);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						case 'u':
 | 
				
			||||||
 | 
							if (iflags & CMD_UFLAG) {
 | 
				
			||||||
 | 
								(*oflags) |= CMD_UFLAG;
 | 
				
			||||||
 | 
								return (0);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						case 'U':
 | 
				
			||||||
 | 
							if (iflags & CMD_BIGUFLAG) {
 | 
				
			||||||
 | 
								(*oflags) |= CMD_BIGUFLAG;
 | 
				
			||||||
 | 
								return (0);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return (1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					size_t
 | 
				
			||||||
 | 
					cmd_print_flags(char *buf, size_t len, size_t off, int flags)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						size_t	boff = off;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((flags & CMD_FLAGMASK) == 0)
 | 
				
			||||||
 | 
							return (0);
 | 
				
			||||||
 | 
						off += xsnprintf(buf + off, len - off, " -");
 | 
				
			||||||
 | 
						if (off < len && flags & CMD_AFLAG)
 | 
				
			||||||
 | 
							off += xsnprintf(buf + off, len - off, "a");
 | 
				
			||||||
 | 
						if (off < len && flags & CMD_BIGDFLAG)
 | 
				
			||||||
 | 
							off += xsnprintf(buf + off, len - off, "D");
 | 
				
			||||||
 | 
						if (off < len && flags & CMD_DFLAG)
 | 
				
			||||||
 | 
							off += xsnprintf(buf + off, len - off, "d");
 | 
				
			||||||
 | 
						if (off < len && flags & CMD_GFLAG)
 | 
				
			||||||
 | 
							off += xsnprintf(buf + off, len - off, "g");
 | 
				
			||||||
 | 
						if (off < len && flags & CMD_KFLAG)
 | 
				
			||||||
 | 
							off += xsnprintf(buf + off, len - off, "k");
 | 
				
			||||||
 | 
						if (off < len && flags & CMD_UFLAG)
 | 
				
			||||||
 | 
							off += xsnprintf(buf + off, len - off, "u");
 | 
				
			||||||
 | 
						if (off < len && flags & CMD_BIGUFLAG)
 | 
				
			||||||
 | 
							off += xsnprintf(buf + off, len - off, "U");
 | 
				
			||||||
 | 
						return (off - boff);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_fill_argument(int flags, char **arg, int argc, char **argv)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						*arg = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (flags & CMD_ARG1) {
 | 
				
			||||||
 | 
							if (argc != 1)
 | 
				
			||||||
 | 
								return (-1);
 | 
				
			||||||
 | 
							*arg = xstrdup(argv[0]);
 | 
				
			||||||
 | 
							return (0);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (flags & CMD_ARG01) {
 | 
				
			||||||
 | 
							if (argc != 0 && argc != 1)
 | 
				
			||||||
 | 
								return (-1);
 | 
				
			||||||
 | 
							if (argc == 1)
 | 
				
			||||||
 | 
								*arg = xstrdup(argv[0]);
 | 
				
			||||||
 | 
							return (0);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (argc != 0)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_target_init(struct cmd *self, unused int key)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_target_data	*data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						self->data = data = xmalloc(sizeof *data);
 | 
				
			||||||
 | 
						data->flags = 0;
 | 
				
			||||||
 | 
						data->target = NULL;
 | 
				
			||||||
 | 
						data->arg = NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_target_parse(struct cmd *self, int argc, char **argv, char **cause)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_target_data	*data;
 | 
				
			||||||
 | 
						int			 opt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Don't use the entry version since it may be dependent on key. */
 | 
				
			||||||
 | 
						cmd_target_init(self, 0);
 | 
				
			||||||
 | 
						data = self->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while ((opt = getopt(argc, argv, CMD_FLAGS "t:")) != -1) {
 | 
				
			||||||
 | 
							switch (cmd_do_flags(opt, self->entry->flags, &data->flags)) {
 | 
				
			||||||
 | 
							case -1:
 | 
				
			||||||
 | 
								goto usage;
 | 
				
			||||||
 | 
							case 0:
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							switch (opt) {
 | 
				
			||||||
 | 
							case 't':
 | 
				
			||||||
 | 
								if (data->target == NULL)
 | 
				
			||||||
 | 
									data->target = xstrdup(optarg);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								goto usage;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						argc -= optind;
 | 
				
			||||||
 | 
						argv += optind;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (cmd_fill_argument(self->entry->flags, &data->arg, argc, argv) != 0)
 | 
				
			||||||
 | 
							goto usage;
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					usage:
 | 
				
			||||||
 | 
						xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						self->entry->free(self);
 | 
				
			||||||
 | 
						return (-1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_target_send(struct cmd *self, struct buffer *b)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_target_data	*data = self->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						buffer_write(b, data, sizeof *data);
 | 
				
			||||||
 | 
						cmd_send_string(b, data->target);
 | 
				
			||||||
 | 
						cmd_send_string(b, data->arg);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_target_recv(struct cmd *self, struct buffer *b)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_target_data	*data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						self->data = data = xmalloc(sizeof *data);
 | 
				
			||||||
 | 
						buffer_read(b, data, sizeof *data);
 | 
				
			||||||
 | 
						data->target = cmd_recv_string(b);
 | 
				
			||||||
 | 
						data->arg = cmd_recv_string(b);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_target_free(struct cmd *self)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_target_data	*data = self->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (data->target != NULL)
 | 
				
			||||||
 | 
							xfree(data->target);
 | 
				
			||||||
 | 
						if (data->arg != NULL)
 | 
				
			||||||
 | 
							xfree(data->arg);
 | 
				
			||||||
 | 
						xfree(data);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					size_t
 | 
				
			||||||
 | 
					cmd_target_print(struct cmd *self, char *buf, size_t len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_target_data	*data = self->data;
 | 
				
			||||||
 | 
						size_t			 off = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						off += xsnprintf(buf, len, "%s", self->entry->name);
 | 
				
			||||||
 | 
						if (data == NULL)
 | 
				
			||||||
 | 
							return (off);
 | 
				
			||||||
 | 
						off += cmd_print_flags(buf, len, off, data->flags);
 | 
				
			||||||
 | 
						if (off < len && data->target != NULL)
 | 
				
			||||||
 | 
							off += cmd_prarg(buf + off, len - off, " -t ", data->target);
 | 
				
			||||||
 | 
					 	if (off < len && data->arg != NULL)
 | 
				
			||||||
 | 
							off += cmd_prarg(buf + off, len - off, " ", data->arg);
 | 
				
			||||||
 | 
						return (off);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_srcdst_init(struct cmd *self, unused int key)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_srcdst_data	*data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						self->data = data = xmalloc(sizeof *data);
 | 
				
			||||||
 | 
						data->flags = 0;
 | 
				
			||||||
 | 
						data->src = NULL;
 | 
				
			||||||
 | 
						data->dst = NULL;
 | 
				
			||||||
 | 
						data->arg = NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_srcdst_parse(struct cmd *self, int argc, char **argv, char **cause)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_srcdst_data	*data;
 | 
				
			||||||
 | 
						int			 opt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cmd_srcdst_init(self, 0);
 | 
				
			||||||
 | 
						data = self->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while ((opt = getopt(argc, argv, CMD_FLAGS "s:t:")) != -1) {
 | 
				
			||||||
 | 
							switch (cmd_do_flags(opt, self->entry->flags, &data->flags)) {
 | 
				
			||||||
 | 
							case -1:
 | 
				
			||||||
 | 
								goto usage;
 | 
				
			||||||
 | 
							case 0:
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							switch (opt) {
 | 
				
			||||||
 | 
							case 's':
 | 
				
			||||||
 | 
								if (data->src == NULL)
 | 
				
			||||||
 | 
									data->src = xstrdup(optarg);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case 't':
 | 
				
			||||||
 | 
								if (data->dst == NULL)
 | 
				
			||||||
 | 
									data->dst = xstrdup(optarg);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								goto usage;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						argc -= optind;
 | 
				
			||||||
 | 
						argv += optind;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (cmd_fill_argument(self->entry->flags, &data->arg, argc, argv) != 0)
 | 
				
			||||||
 | 
							goto usage;
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					usage:
 | 
				
			||||||
 | 
						xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						self->entry->free(self);
 | 
				
			||||||
 | 
						return (-1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_srcdst_send(struct cmd *self, struct buffer *b)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_srcdst_data	*data = self->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						buffer_write(b, data, sizeof *data);
 | 
				
			||||||
 | 
						cmd_send_string(b, data->src);
 | 
				
			||||||
 | 
						cmd_send_string(b, data->dst);
 | 
				
			||||||
 | 
						cmd_send_string(b, data->arg);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_srcdst_recv(struct cmd *self, struct buffer *b)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_srcdst_data	*data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						self->data = data = xmalloc(sizeof *data);
 | 
				
			||||||
 | 
						buffer_read(b, data, sizeof *data);
 | 
				
			||||||
 | 
						data->src = cmd_recv_string(b);
 | 
				
			||||||
 | 
						data->dst = cmd_recv_string(b);
 | 
				
			||||||
 | 
						data->arg = cmd_recv_string(b);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_srcdst_free(struct cmd *self)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_srcdst_data	*data = self->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (data->src != NULL)
 | 
				
			||||||
 | 
							xfree(data->src);
 | 
				
			||||||
 | 
						if (data->dst != NULL)
 | 
				
			||||||
 | 
							xfree(data->dst);
 | 
				
			||||||
 | 
						if (data->arg != NULL)
 | 
				
			||||||
 | 
							xfree(data->arg);
 | 
				
			||||||
 | 
						xfree(data);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					size_t
 | 
				
			||||||
 | 
					cmd_srcdst_print(struct cmd *self, char *buf, size_t len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_srcdst_data	*data = self->data;
 | 
				
			||||||
 | 
						size_t			 off = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						off += xsnprintf(buf, len, "%s", self->entry->name);
 | 
				
			||||||
 | 
						if (data == NULL)
 | 
				
			||||||
 | 
							return (off);
 | 
				
			||||||
 | 
						off += cmd_print_flags(buf, len, off, data->flags);
 | 
				
			||||||
 | 
						if (off < len && data->src != NULL)
 | 
				
			||||||
 | 
							off += xsnprintf(buf + off, len - off, " -s %s", data->src);
 | 
				
			||||||
 | 
						if (off < len && data->dst != NULL)
 | 
				
			||||||
 | 
							off += xsnprintf(buf + off, len - off, " -t %s", data->dst);
 | 
				
			||||||
 | 
					 	if (off < len && data->arg != NULL)
 | 
				
			||||||
 | 
							off += cmd_prarg(buf + off, len - off, " ", data->arg);
 | 
				
			||||||
 | 
						return (off);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_buffer_init(struct cmd *self, unused int key)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_buffer_data	*data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						self->data = data = xmalloc(sizeof *data);
 | 
				
			||||||
 | 
						data->flags = 0;
 | 
				
			||||||
 | 
						data->target = NULL;
 | 
				
			||||||
 | 
						data->buffer = -1;
 | 
				
			||||||
 | 
						data->arg = NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_buffer_parse(struct cmd *self, int argc, char **argv, char **cause)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_buffer_data	*data;
 | 
				
			||||||
 | 
						int			 opt, n;
 | 
				
			||||||
 | 
						const char		*errstr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cmd_buffer_init(self, 0);
 | 
				
			||||||
 | 
						data = self->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while ((opt = getopt(argc, argv, CMD_FLAGS "b:t:")) != -1) {
 | 
				
			||||||
 | 
							switch (cmd_do_flags(opt, self->entry->flags, &data->flags)) {
 | 
				
			||||||
 | 
							case -1:
 | 
				
			||||||
 | 
								goto usage;
 | 
				
			||||||
 | 
							case 0:
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							switch (opt) {
 | 
				
			||||||
 | 
							case 'b':
 | 
				
			||||||
 | 
								if (data->buffer == -1) {
 | 
				
			||||||
 | 
									n = strtonum(optarg, 0, INT_MAX, &errstr);
 | 
				
			||||||
 | 
									if (errstr != NULL) {
 | 
				
			||||||
 | 
										xasprintf(cause, "buffer %s", errstr);
 | 
				
			||||||
 | 
										goto error;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									data->buffer = n;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case 't':
 | 
				
			||||||
 | 
								if (data->target == NULL)
 | 
				
			||||||
 | 
									data->target = xstrdup(optarg);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								goto usage;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						argc -= optind;
 | 
				
			||||||
 | 
						argv += optind;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (cmd_fill_argument(self->entry->flags, &data->arg, argc, argv) != 0)
 | 
				
			||||||
 | 
							goto usage;
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					usage:
 | 
				
			||||||
 | 
						xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					error:
 | 
				
			||||||
 | 
						self->entry->free(self);
 | 
				
			||||||
 | 
						return (-1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_buffer_send(struct cmd *self, struct buffer *b)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_buffer_data	*data = self->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						buffer_write(b, data, sizeof *data);
 | 
				
			||||||
 | 
						cmd_send_string(b, data->target);
 | 
				
			||||||
 | 
						cmd_send_string(b, data->arg);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_buffer_recv(struct cmd *self, struct buffer *b)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_buffer_data	*data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						self->data = data = xmalloc(sizeof *data);
 | 
				
			||||||
 | 
						buffer_read(b, data, sizeof *data);
 | 
				
			||||||
 | 
						data->target = cmd_recv_string(b);
 | 
				
			||||||
 | 
						data->arg = cmd_recv_string(b);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_buffer_free(struct cmd *self)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_buffer_data	*data = self->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (data->target != NULL)
 | 
				
			||||||
 | 
							xfree(data->target);
 | 
				
			||||||
 | 
						if (data->arg != NULL)
 | 
				
			||||||
 | 
							xfree(data->arg);
 | 
				
			||||||
 | 
						xfree(data);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					size_t
 | 
				
			||||||
 | 
					cmd_buffer_print(struct cmd *self, char *buf, size_t len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_buffer_data	*data = self->data;
 | 
				
			||||||
 | 
						size_t			 off = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						off += xsnprintf(buf, len, "%s", self->entry->name);
 | 
				
			||||||
 | 
						if (data == NULL)
 | 
				
			||||||
 | 
							return (off);
 | 
				
			||||||
 | 
						off += cmd_print_flags(buf, len, off, data->flags);
 | 
				
			||||||
 | 
						if (off < len && data->buffer != -1)
 | 
				
			||||||
 | 
							off += xsnprintf(buf + off, len - off, " -b %d", data->buffer);
 | 
				
			||||||
 | 
						if (off < len && data->target != NULL)
 | 
				
			||||||
 | 
							off += cmd_prarg(buf + off, len - off, " -t ", data->target);
 | 
				
			||||||
 | 
					 	if (off < len && data->arg != NULL)
 | 
				
			||||||
 | 
							off += cmd_prarg(buf + off, len - off, " ", data->arg);
 | 
				
			||||||
 | 
						return (off);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_option_init(struct cmd *self, unused int key)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_option_data	*data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						self->data = data = xmalloc(sizeof *data);
 | 
				
			||||||
 | 
						data->flags = 0;
 | 
				
			||||||
 | 
						data->target = NULL;
 | 
				
			||||||
 | 
						data->option = NULL;
 | 
				
			||||||
 | 
						data->value = NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_option_parse(struct cmd *self, int argc, char **argv, char **cause)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_option_data	*data;
 | 
				
			||||||
 | 
						int			 opt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Don't use the entry version since it may be dependent on key. */
 | 
				
			||||||
 | 
						cmd_option_init(self, 0);
 | 
				
			||||||
 | 
						data = self->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while ((opt = getopt(argc, argv, CMD_FLAGS "t:")) != -1) {
 | 
				
			||||||
 | 
							switch (cmd_do_flags(opt, self->entry->flags, &data->flags)) {
 | 
				
			||||||
 | 
							case -1:
 | 
				
			||||||
 | 
								goto usage;
 | 
				
			||||||
 | 
							case 0:
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							switch (opt) {
 | 
				
			||||||
 | 
							case 't':
 | 
				
			||||||
 | 
								if (data->target == NULL)
 | 
				
			||||||
 | 
									data->target = xstrdup(optarg);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								goto usage;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						argc -= optind;
 | 
				
			||||||
 | 
						argv += optind;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (argc == 2) {
 | 
				
			||||||
 | 
							data->option = xstrdup(argv[0]);
 | 
				
			||||||
 | 
							data->value = xstrdup(argv[1]);
 | 
				
			||||||
 | 
						} else if (argc == 1)
 | 
				
			||||||
 | 
							data->option = xstrdup(argv[0]);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							goto usage;
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					usage:
 | 
				
			||||||
 | 
						xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						self->entry->free(self);
 | 
				
			||||||
 | 
						return (-1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_option_send(struct cmd *self, struct buffer *b)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_option_data	*data = self->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						buffer_write(b, data, sizeof *data);
 | 
				
			||||||
 | 
						cmd_send_string(b, data->target);
 | 
				
			||||||
 | 
						cmd_send_string(b, data->option);
 | 
				
			||||||
 | 
						cmd_send_string(b, data->value);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_option_recv(struct cmd *self, struct buffer *b)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_option_data	*data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						self->data = data = xmalloc(sizeof *data);
 | 
				
			||||||
 | 
						buffer_read(b, data, sizeof *data);
 | 
				
			||||||
 | 
						data->target = cmd_recv_string(b);
 | 
				
			||||||
 | 
						data->option = cmd_recv_string(b);
 | 
				
			||||||
 | 
						data->value = cmd_recv_string(b);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_option_free(struct cmd *self)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_option_data	*data = self->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (data->target != NULL)
 | 
				
			||||||
 | 
							xfree(data->target);
 | 
				
			||||||
 | 
						if (data->option != NULL)
 | 
				
			||||||
 | 
							xfree(data->option);
 | 
				
			||||||
 | 
						if (data->value != NULL)
 | 
				
			||||||
 | 
							xfree(data->value);
 | 
				
			||||||
 | 
						xfree(data);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					size_t
 | 
				
			||||||
 | 
					cmd_option_print(struct cmd *self, char *buf, size_t len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_option_data	*data = self->data;
 | 
				
			||||||
 | 
						size_t			 off = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						off += xsnprintf(buf, len, "%s", self->entry->name);
 | 
				
			||||||
 | 
						if (data == NULL)
 | 
				
			||||||
 | 
							return (off);
 | 
				
			||||||
 | 
						off += cmd_print_flags(buf, len, off, data->flags);
 | 
				
			||||||
 | 
						if (off < len && data->target != NULL)
 | 
				
			||||||
 | 
							off += cmd_prarg(buf + off, len - off, " -t ", data->target);
 | 
				
			||||||
 | 
					 	if (off < len && data->option != NULL)
 | 
				
			||||||
 | 
							off += xsnprintf(buf + off, len - off, " %s", data->option);
 | 
				
			||||||
 | 
					 	if (off < len && data->value != NULL)
 | 
				
			||||||
 | 
							off += xsnprintf(buf + off, len - off, " %s", data->value);
 | 
				
			||||||
 | 
						return (off);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_pane_init(struct cmd *self, unused int key)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_pane_data	*data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						self->data = data = xmalloc(sizeof *data);
 | 
				
			||||||
 | 
						data->flags = 0;
 | 
				
			||||||
 | 
						data->target = NULL;
 | 
				
			||||||
 | 
						data->arg = NULL;
 | 
				
			||||||
 | 
						data->pane = -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_pane_parse(struct cmd *self, int argc, char **argv, char **cause)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_pane_data	*data;
 | 
				
			||||||
 | 
						int			 opt, n;
 | 
				
			||||||
 | 
						const char		*errstr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Don't use the entry version since it may be dependent on key. */
 | 
				
			||||||
 | 
						cmd_pane_init(self, 0);
 | 
				
			||||||
 | 
						data = self->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while ((opt = getopt(argc, argv, CMD_FLAGS "p:t:")) != -1) {
 | 
				
			||||||
 | 
							switch (cmd_do_flags(opt, self->entry->flags, &data->flags)) {
 | 
				
			||||||
 | 
							case -1:
 | 
				
			||||||
 | 
								goto usage;
 | 
				
			||||||
 | 
							case 0:
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							switch (opt) {
 | 
				
			||||||
 | 
							case 'p':
 | 
				
			||||||
 | 
								if (data->pane == -1) {
 | 
				
			||||||
 | 
									n = strtonum(optarg, 0, INT_MAX, &errstr);
 | 
				
			||||||
 | 
									if (errstr != NULL) {
 | 
				
			||||||
 | 
										xasprintf(cause, "pane %s", errstr);
 | 
				
			||||||
 | 
										goto error;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									data->pane = n;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case 't':
 | 
				
			||||||
 | 
								if (data->target == NULL)
 | 
				
			||||||
 | 
									data->target = xstrdup(optarg);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								goto usage;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						argc -= optind;
 | 
				
			||||||
 | 
						argv += optind;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (cmd_fill_argument(self->entry->flags, &data->arg, argc, argv) != 0)
 | 
				
			||||||
 | 
							goto usage;
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					usage:
 | 
				
			||||||
 | 
						xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					error:
 | 
				
			||||||
 | 
						self->entry->free(self);
 | 
				
			||||||
 | 
						return (-1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_pane_send(struct cmd *self, struct buffer *b)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_pane_data	*data = self->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						buffer_write(b, data, sizeof *data);
 | 
				
			||||||
 | 
						cmd_send_string(b, data->target);
 | 
				
			||||||
 | 
						cmd_send_string(b, data->arg);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_pane_recv(struct cmd *self, struct buffer *b)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_pane_data	*data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						self->data = data = xmalloc(sizeof *data);
 | 
				
			||||||
 | 
						buffer_read(b, data, sizeof *data);
 | 
				
			||||||
 | 
						data->target = cmd_recv_string(b);
 | 
				
			||||||
 | 
						data->arg = cmd_recv_string(b);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_pane_free(struct cmd *self)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_pane_data	*data = self->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (data->target != NULL)
 | 
				
			||||||
 | 
							xfree(data->target);
 | 
				
			||||||
 | 
						if (data->arg != NULL)
 | 
				
			||||||
 | 
							xfree(data->arg);
 | 
				
			||||||
 | 
						xfree(data);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					size_t
 | 
				
			||||||
 | 
					cmd_pane_print(struct cmd *self, char *buf, size_t len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_pane_data	*data = self->data;
 | 
				
			||||||
 | 
						size_t			 off = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						off += xsnprintf(buf, len, "%s", self->entry->name);
 | 
				
			||||||
 | 
						if (data == NULL)
 | 
				
			||||||
 | 
							return (off);
 | 
				
			||||||
 | 
						off += cmd_print_flags(buf, len, off, data->flags);
 | 
				
			||||||
 | 
						if (off < len && data->target != NULL)
 | 
				
			||||||
 | 
							off += cmd_prarg(buf + off, len - off, " -t ", data->target);
 | 
				
			||||||
 | 
					 	if (off < len && data->arg != NULL)
 | 
				
			||||||
 | 
							off += cmd_prarg(buf + off, len - off, " ", data->arg);
 | 
				
			||||||
 | 
						return (off);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										51
									
								
								cmd-has-session.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								cmd-has-session.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,51 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Cause client to report an error and exit with 1 if session doesn't exist.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_has_session_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_has_session_entry = {
 | 
				
			||||||
 | 
						"has-session", "has",
 | 
				
			||||||
 | 
						CMD_TARGET_SESSION_USAGE,
 | 
				
			||||||
 | 
						0,
 | 
				
			||||||
 | 
						cmd_target_init,
 | 
				
			||||||
 | 
						cmd_target_parse,
 | 
				
			||||||
 | 
						cmd_has_session_exec,
 | 
				
			||||||
 | 
						cmd_target_send,
 | 
				
			||||||
 | 
						cmd_target_recv,
 | 
				
			||||||
 | 
						cmd_target_free,
 | 
				
			||||||
 | 
						cmd_target_print
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_has_session_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_target_data	*data = self->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (cmd_find_session(ctx, data->target) == NULL)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										72
									
								
								cmd-kill-pane.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								cmd-kill-pane.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,72 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Kill pane.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_kill_pane_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_kill_pane_entry = {
 | 
				
			||||||
 | 
						"kill-pane", "killp",
 | 
				
			||||||
 | 
						CMD_PANE_WINDOW_USAGE,
 | 
				
			||||||
 | 
						0,
 | 
				
			||||||
 | 
						cmd_pane_init,
 | 
				
			||||||
 | 
						cmd_pane_parse,
 | 
				
			||||||
 | 
						cmd_kill_pane_exec,
 | 
				
			||||||
 | 
					       	cmd_pane_send,
 | 
				
			||||||
 | 
						cmd_pane_recv,
 | 
				
			||||||
 | 
						cmd_pane_free,
 | 
				
			||||||
 | 
						cmd_pane_print
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_kill_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_pane_data	*data = self->data;
 | 
				
			||||||
 | 
						struct winlink		*wl;
 | 
				
			||||||
 | 
						struct window_pane	*wp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						if (data->pane == -1)
 | 
				
			||||||
 | 
							wp = wl->window->active;
 | 
				
			||||||
 | 
						else {
 | 
				
			||||||
 | 
							wp = window_pane_at_index(wl->window, data->pane);
 | 
				
			||||||
 | 
							if (wp == NULL) {
 | 
				
			||||||
 | 
								ctx->error(ctx, "no pane: %d", data->pane);
 | 
				
			||||||
 | 
								return (-1);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (window_count_panes(wl->window) == 1) {
 | 
				
			||||||
 | 
							ctx->error(ctx, "can't kill pane: %d", data->pane);
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						window_remove_pane(wl->window, wp);
 | 
				
			||||||
 | 
						server_redraw_window(wl->window);
 | 
				
			||||||
 | 
						layout_refresh(wl->window, 0);
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										51
									
								
								cmd-kill-server.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								cmd-kill-server.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,51 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <signal.h>
 | 
				
			||||||
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Kill the server and do nothing else.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_kill_server_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_kill_server_entry = {
 | 
				
			||||||
 | 
						"kill-server", NULL,
 | 
				
			||||||
 | 
						"",
 | 
				
			||||||
 | 
						0,
 | 
				
			||||||
 | 
						NULL,
 | 
				
			||||||
 | 
						NULL,
 | 
				
			||||||
 | 
						cmd_kill_server_exec,
 | 
				
			||||||
 | 
						NULL,
 | 
				
			||||||
 | 
						NULL,
 | 
				
			||||||
 | 
						NULL,
 | 
				
			||||||
 | 
						NULL
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_kill_server_exec(unused struct cmd *self, unused struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						sigterm = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										68
									
								
								cmd-kill-session.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								cmd-kill-session.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,68 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Destroy session, detaching all clients attached to it and destroying any
 | 
				
			||||||
 | 
					 * windows linked only to this session.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Note this deliberately has no alias to make it hard to hit by accident.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_kill_session_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_kill_session_entry = {
 | 
				
			||||||
 | 
						"kill-session", NULL,
 | 
				
			||||||
 | 
						CMD_TARGET_SESSION_USAGE,
 | 
				
			||||||
 | 
						0,
 | 
				
			||||||
 | 
						cmd_target_init,
 | 
				
			||||||
 | 
						cmd_target_parse,
 | 
				
			||||||
 | 
						cmd_kill_session_exec,
 | 
				
			||||||
 | 
						cmd_target_send,
 | 
				
			||||||
 | 
						cmd_target_recv,
 | 
				
			||||||
 | 
						cmd_target_free,
 | 
				
			||||||
 | 
						cmd_target_print
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_kill_session_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_target_data	*data = self->data;
 | 
				
			||||||
 | 
						struct session		*s;
 | 
				
			||||||
 | 
					 	struct client		*c;
 | 
				
			||||||
 | 
						u_int			 i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((s = cmd_find_session(ctx, data->target)) == NULL)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
 | 
				
			||||||
 | 
							c = ARRAY_ITEM(&clients, i);
 | 
				
			||||||
 | 
							if (c->session == s) {
 | 
				
			||||||
 | 
								c->session = NULL;
 | 
				
			||||||
 | 
								server_write_client(c, MSG_EXIT, NULL, 0);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						recalculate_sizes();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						session_destroy(s);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										69
									
								
								cmd-kill-window.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								cmd-kill-window.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,69 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Destroy window.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_kill_window_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_kill_window_entry = {
 | 
				
			||||||
 | 
						"kill-window", "killw",
 | 
				
			||||||
 | 
						CMD_TARGET_WINDOW_USAGE,
 | 
				
			||||||
 | 
						0,
 | 
				
			||||||
 | 
						cmd_target_init,
 | 
				
			||||||
 | 
						cmd_target_parse,
 | 
				
			||||||
 | 
						cmd_kill_window_exec,
 | 
				
			||||||
 | 
						cmd_target_send,
 | 
				
			||||||
 | 
						cmd_target_recv,
 | 
				
			||||||
 | 
						cmd_target_free,
 | 
				
			||||||
 | 
						cmd_target_print
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_kill_window_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_target_data	*data = self->data;
 | 
				
			||||||
 | 
						struct winlink		*wl;
 | 
				
			||||||
 | 
						struct session		*s;
 | 
				
			||||||
 | 
						struct client		*c;
 | 
				
			||||||
 | 
						u_int		 	 i;
 | 
				
			||||||
 | 
						int		 	 destroyed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 	destroyed = session_detach(s, wl);
 | 
				
			||||||
 | 
						for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
 | 
				
			||||||
 | 
							c = ARRAY_ITEM(&clients, i);
 | 
				
			||||||
 | 
							if (c == NULL || c->session != s)
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							if (destroyed) {
 | 
				
			||||||
 | 
								c->session = NULL;
 | 
				
			||||||
 | 
								server_write_client(c, MSG_EXIT, NULL, 0);
 | 
				
			||||||
 | 
							} else
 | 
				
			||||||
 | 
								server_redraw_client(c);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						recalculate_sizes();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										60
									
								
								cmd-last-window.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								cmd-last-window.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,60 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Move to last window.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_last_window_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_last_window_entry = {
 | 
				
			||||||
 | 
						"last-window", "last",
 | 
				
			||||||
 | 
						CMD_TARGET_SESSION_USAGE,
 | 
				
			||||||
 | 
						0,
 | 
				
			||||||
 | 
						cmd_target_init,
 | 
				
			||||||
 | 
						cmd_target_parse,
 | 
				
			||||||
 | 
						cmd_last_window_exec,
 | 
				
			||||||
 | 
						cmd_target_send,
 | 
				
			||||||
 | 
						cmd_target_recv,
 | 
				
			||||||
 | 
						cmd_target_free,
 | 
				
			||||||
 | 
						cmd_target_print
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_last_window_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_target_data	*data = self->data;
 | 
				
			||||||
 | 
						struct session		*s;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((s = cmd_find_session(ctx, data->target)) == NULL)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (session_last(s) == 0)
 | 
				
			||||||
 | 
							server_redraw_session(s);
 | 
				
			||||||
 | 
						else {
 | 
				
			||||||
 | 
							ctx->error(ctx, "no last window");
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						recalculate_sizes();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										109
									
								
								cmd-link-window.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								cmd-link-window.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,109 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Link a window into another session.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_link_window_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_link_window_entry = {
 | 
				
			||||||
 | 
						"link-window", "linkw",
 | 
				
			||||||
 | 
						"[-dk] " CMD_SRCDST_WINDOW_USAGE,
 | 
				
			||||||
 | 
						CMD_DFLAG|CMD_KFLAG,
 | 
				
			||||||
 | 
						cmd_srcdst_init,
 | 
				
			||||||
 | 
						cmd_srcdst_parse,
 | 
				
			||||||
 | 
						cmd_link_window_exec,
 | 
				
			||||||
 | 
						cmd_srcdst_send,
 | 
				
			||||||
 | 
						cmd_srcdst_recv,
 | 
				
			||||||
 | 
						cmd_srcdst_free,
 | 
				
			||||||
 | 
						cmd_srcdst_print
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_link_window_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_srcdst_data	*data = self->data;
 | 
				
			||||||
 | 
						struct session		*dst;
 | 
				
			||||||
 | 
						struct winlink		*wl_src, *wl_dst;
 | 
				
			||||||
 | 
						char			*cause;
 | 
				
			||||||
 | 
						int			 idx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((wl_src = cmd_find_window(ctx, data->src, NULL)) == NULL)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (arg_parse_window(data->dst, &dst, &idx) != 0) {
 | 
				
			||||||
 | 
							ctx->error(ctx, "bad window: %s", data->dst);
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (dst == NULL)
 | 
				
			||||||
 | 
							dst = ctx->cursession;
 | 
				
			||||||
 | 
						if (dst == NULL)
 | 
				
			||||||
 | 
							dst = cmd_current_session(ctx);
 | 
				
			||||||
 | 
						if (dst == NULL) {
 | 
				
			||||||
 | 
							ctx->error(ctx, "session not found: %s", data->dst);
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wl_dst = NULL;
 | 
				
			||||||
 | 
						if (idx != -1)
 | 
				
			||||||
 | 
							wl_dst = winlink_find_by_index(&dst->windows, idx);
 | 
				
			||||||
 | 
						if (wl_dst != NULL) {
 | 
				
			||||||
 | 
							if (wl_dst->window == wl_src->window)
 | 
				
			||||||
 | 
								return (0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (data->flags & CMD_KFLAG) {
 | 
				
			||||||
 | 
								/*
 | 
				
			||||||
 | 
								 * Can't use session_detach as it will destroy session
 | 
				
			||||||
 | 
								 * if this makes it empty.
 | 
				
			||||||
 | 
								 */
 | 
				
			||||||
 | 
								session_alert_cancel(dst, wl_dst);
 | 
				
			||||||
 | 
								winlink_stack_remove(&dst->lastw, wl_dst);
 | 
				
			||||||
 | 
								winlink_remove(&dst->windows, wl_dst);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								/* Force select/redraw if current. */
 | 
				
			||||||
 | 
								if (wl_dst == dst->curw) {
 | 
				
			||||||
 | 
									data->flags &= ~CMD_DFLAG;
 | 
				
			||||||
 | 
									dst->curw = NULL;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wl_dst = session_attach(dst, wl_src->window, idx, &cause);
 | 
				
			||||||
 | 
						if (wl_dst == NULL) {
 | 
				
			||||||
 | 
							ctx->error(ctx, "create session failed: %s", cause);
 | 
				
			||||||
 | 
							xfree(cause);
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (data->flags & CMD_DFLAG)
 | 
				
			||||||
 | 
							server_status_session(dst);
 | 
				
			||||||
 | 
						else {
 | 
				
			||||||
 | 
							session_select(dst, wl_dst->idx);
 | 
				
			||||||
 | 
							server_redraw_session(dst);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						recalculate_sizes();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										91
									
								
								cmd-list-buffers.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								cmd-list-buffers.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,91 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * List paste buffers.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_list_buffers_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_list_buffers_entry = {
 | 
				
			||||||
 | 
						"list-buffers", "lsb",
 | 
				
			||||||
 | 
						CMD_TARGET_SESSION_USAGE,
 | 
				
			||||||
 | 
						0,
 | 
				
			||||||
 | 
						cmd_target_init,
 | 
				
			||||||
 | 
						cmd_target_parse,
 | 
				
			||||||
 | 
						cmd_list_buffers_exec,
 | 
				
			||||||
 | 
						cmd_target_send,
 | 
				
			||||||
 | 
						cmd_target_recv,
 | 
				
			||||||
 | 
						cmd_target_free,
 | 
				
			||||||
 | 
						cmd_target_print
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_list_buffers_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_target_data	*data = self->data;
 | 
				
			||||||
 | 
						struct session		*s;
 | 
				
			||||||
 | 
						struct paste_buffer	*pb;
 | 
				
			||||||
 | 
						u_int			 idx;
 | 
				
			||||||
 | 
						char			*tmp;
 | 
				
			||||||
 | 
						size_t			 size, in, out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((s = cmd_find_session(ctx, data->target)) == NULL)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (s->sx > 35) {	/* leave three for ... */
 | 
				
			||||||
 | 
							size = s->sx - 32;
 | 
				
			||||||
 | 
							tmp = xmalloc(size + 1);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							size = 0;
 | 
				
			||||||
 | 
							tmp = NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						idx = 0;
 | 
				
			||||||
 | 
						while ((pb = paste_walk_stack(&s->buffers, &idx)) != NULL) {
 | 
				
			||||||
 | 
							if (tmp != NULL) {
 | 
				
			||||||
 | 
								in = out = 0;
 | 
				
			||||||
 | 
								while (out < size && pb->data[in] != '\0') {
 | 
				
			||||||
 | 
									if (pb->data[in] > 31 && pb->data[in] != 127)
 | 
				
			||||||
 | 
										tmp[out++] = pb->data[in];
 | 
				
			||||||
 | 
									in++;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								tmp[out] = '\0';
 | 
				
			||||||
 | 
								if (out == size) {
 | 
				
			||||||
 | 
									tmp[out - 1] = '.';
 | 
				
			||||||
 | 
									tmp[out - 2] = '.';
 | 
				
			||||||
 | 
									tmp[out - 3] = '.';
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								ctx->print(ctx, "%d: %zu bytes: \"%s\"",
 | 
				
			||||||
 | 
								    idx - 1, strlen(pb->data), tmp);
 | 
				
			||||||
 | 
							} else
 | 
				
			||||||
 | 
								ctx->print(ctx, "%d: %zu bytes", idx, strlen(pb->data));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (tmp != NULL)
 | 
				
			||||||
 | 
							xfree(tmp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										67
									
								
								cmd-list-clients.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								cmd-list-clients.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,67 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <time.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * List all clients.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_list_clients_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_list_clients_entry = {
 | 
				
			||||||
 | 
						"list-clients", "lsc",
 | 
				
			||||||
 | 
						"",
 | 
				
			||||||
 | 
						0,
 | 
				
			||||||
 | 
						NULL,
 | 
				
			||||||
 | 
						NULL,
 | 
				
			||||||
 | 
						cmd_list_clients_exec,
 | 
				
			||||||
 | 
						NULL,
 | 
				
			||||||
 | 
						NULL,
 | 
				
			||||||
 | 
						NULL,
 | 
				
			||||||
 | 
						NULL
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_list_clients_exec(unused struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct client	*c;
 | 
				
			||||||
 | 
						u_int		 i;
 | 
				
			||||||
 | 
						const char	*s_utf8;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
 | 
				
			||||||
 | 
							c = ARRAY_ITEM(&clients, i);
 | 
				
			||||||
 | 
							if (c == NULL || c->session == NULL)
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (c->tty.flags & TTY_UTF8)
 | 
				
			||||||
 | 
								s_utf8 = " (utf8)";
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								s_utf8 = "";
 | 
				
			||||||
 | 
							ctx->print(ctx, "%s: %s [%ux%u %s]%s", c->tty.path,
 | 
				
			||||||
 | 
							    c->session->name, c->tty.sx, c->tty.sy,
 | 
				
			||||||
 | 
							    c->tty.termname, s_utf8);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										51
									
								
								cmd-list-commands.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								cmd-list-commands.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,51 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * List all commands with usages.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_list_commands_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_list_commands_entry = {
 | 
				
			||||||
 | 
						"list-commands", "lscm",
 | 
				
			||||||
 | 
						"",
 | 
				
			||||||
 | 
						0,
 | 
				
			||||||
 | 
						NULL,
 | 
				
			||||||
 | 
						NULL,
 | 
				
			||||||
 | 
						cmd_list_commands_exec,
 | 
				
			||||||
 | 
						NULL,
 | 
				
			||||||
 | 
						NULL,
 | 
				
			||||||
 | 
						NULL,
 | 
				
			||||||
 | 
						NULL
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_list_commands_exec(unused struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const struct cmd_entry 	      **entryp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (entryp = cmd_table; *entryp != NULL; entryp++)
 | 
				
			||||||
 | 
							ctx->print(ctx, "%s %s", (*entryp)->name, (*entryp)->usage);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										59
									
								
								cmd-list-keys.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								cmd-list-keys.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,59 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * List key bindings.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_list_keys_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_list_keys_entry = {
 | 
				
			||||||
 | 
						"list-keys", "lsk",
 | 
				
			||||||
 | 
						"",
 | 
				
			||||||
 | 
						0,
 | 
				
			||||||
 | 
						NULL,
 | 
				
			||||||
 | 
						NULL,
 | 
				
			||||||
 | 
						cmd_list_keys_exec,
 | 
				
			||||||
 | 
						NULL,
 | 
				
			||||||
 | 
						NULL,
 | 
				
			||||||
 | 
						NULL,
 | 
				
			||||||
 | 
						NULL
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_list_keys_exec(unused struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct key_binding	*bd;
 | 
				
			||||||
 | 
						const char		*key;
 | 
				
			||||||
 | 
						char			 tmp[BUFSIZ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						SPLAY_FOREACH(bd, key_bindings, &key_bindings) {
 | 
				
			||||||
 | 
							if ((key = key_string_lookup_key(bd->key)) == NULL)
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							*tmp = '\0';
 | 
				
			||||||
 | 
							cmd_list_print(bd->cmdlist, tmp, sizeof tmp);
 | 
				
			||||||
 | 
							ctx->print(ctx, "%11s: %s", key, tmp);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										67
									
								
								cmd-list-sessions.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								cmd-list-sessions.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,67 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <time.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * List all sessions.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_list_sessions_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_list_sessions_entry = {
 | 
				
			||||||
 | 
						"list-sessions", "ls", "",
 | 
				
			||||||
 | 
						0,
 | 
				
			||||||
 | 
						NULL,
 | 
				
			||||||
 | 
						NULL,
 | 
				
			||||||
 | 
						cmd_list_sessions_exec,
 | 
				
			||||||
 | 
						NULL,
 | 
				
			||||||
 | 
						NULL,
 | 
				
			||||||
 | 
						NULL,
 | 
				
			||||||
 | 
						NULL
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_list_sessions_exec(unused struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct session	*s;
 | 
				
			||||||
 | 
						char		*tim;
 | 
				
			||||||
 | 
						u_int		 i;
 | 
				
			||||||
 | 
						time_t		 t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
 | 
				
			||||||
 | 
							s = ARRAY_ITEM(&sessions, i);
 | 
				
			||||||
 | 
							if (s == NULL)
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							t = s->tv.tv_sec;
 | 
				
			||||||
 | 
							tim = ctime(&t);
 | 
				
			||||||
 | 
							*strchr(tim, '\n') = '\0';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							ctx->print(ctx, "%s: %u windows (created %s) [%ux%u]%s",
 | 
				
			||||||
 | 
							    s->name, winlink_count(&s->windows), tim, s->sx, s->sy,
 | 
				
			||||||
 | 
							    s->flags & SESSION_UNATTACHED ? "" : " (attached)");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										88
									
								
								cmd-list-windows.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								cmd-list-windows.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,88 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * List windows on given session.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_list_windows_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_list_windows_entry = {
 | 
				
			||||||
 | 
						"list-windows", "lsw",
 | 
				
			||||||
 | 
						CMD_TARGET_SESSION_USAGE,
 | 
				
			||||||
 | 
						0,
 | 
				
			||||||
 | 
						cmd_target_init,
 | 
				
			||||||
 | 
						cmd_target_parse,
 | 
				
			||||||
 | 
						cmd_list_windows_exec,
 | 
				
			||||||
 | 
						cmd_target_send,
 | 
				
			||||||
 | 
						cmd_target_recv,
 | 
				
			||||||
 | 
						cmd_target_free,
 | 
				
			||||||
 | 
						cmd_target_print
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_list_windows_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_target_data	*data = self->data;
 | 
				
			||||||
 | 
						struct session		*s;
 | 
				
			||||||
 | 
						struct winlink		*wl;
 | 
				
			||||||
 | 
						struct window		*w;
 | 
				
			||||||
 | 
						struct window_pane	*wp;
 | 
				
			||||||
 | 
						struct grid		*gd;
 | 
				
			||||||
 | 
						u_int			 i;
 | 
				
			||||||
 | 
						unsigned long long	 size;
 | 
				
			||||||
 | 
						const char		*name;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((s = cmd_find_session(ctx, data->target)) == NULL)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						RB_FOREACH(wl, winlinks, &s->windows) {
 | 
				
			||||||
 | 
							w = wl->window;
 | 
				
			||||||
 | 
							ctx->print(ctx,
 | 
				
			||||||
 | 
							    "%3d: %s [%ux%u]", wl->idx, w->name, w->sx, w->sy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							TAILQ_FOREACH(wp, &w->panes, entry) {
 | 
				
			||||||
 | 
								gd = wp->base.grid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								size = 0;
 | 
				
			||||||
 | 
								for (i = 0; i < gd->hsize; i++) {
 | 
				
			||||||
 | 
									size += gd->size[i] * sizeof **gd->data;
 | 
				
			||||||
 | 
									size += gd->usize[i] * sizeof **gd->udata;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								size += gd->hsize * (sizeof *gd->data);
 | 
				
			||||||
 | 
								size += gd->hsize * (sizeof *gd->size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (wp->fd != -1)
 | 
				
			||||||
 | 
									name = ttyname(wp->fd);
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
									name = "unknown";
 | 
				
			||||||
 | 
								ctx->print(ctx,
 | 
				
			||||||
 | 
								    "     %s [%ux%u %s] [history %u/%u, %llu bytes]",
 | 
				
			||||||
 | 
								    name, wp->sx, wp->sy, layout_name(w), gd->hsize,
 | 
				
			||||||
 | 
								    gd->hlimit, size);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										154
									
								
								cmd-list.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										154
									
								
								cmd-list.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,154 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct cmd_list *
 | 
				
			||||||
 | 
					cmd_list_parse(int argc, char **argv, char **cause)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_list	*cmdlist;
 | 
				
			||||||
 | 
						struct cmd	*cmd;
 | 
				
			||||||
 | 
						int		 i, lastsplit;
 | 
				
			||||||
 | 
						size_t		 arglen, new_argc;
 | 
				
			||||||
 | 
						char	       **new_argv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cmdlist = xmalloc(sizeof *cmdlist);
 | 
				
			||||||
 | 
						TAILQ_INIT(cmdlist);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						lastsplit = 0;
 | 
				
			||||||
 | 
						for (i = 0; i < argc; i++) {
 | 
				
			||||||
 | 
							arglen = strlen(argv[i]);
 | 
				
			||||||
 | 
							if (arglen == 0 || argv[i][arglen - 1] != ';')
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							argv[i][arglen - 1] = '\0';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (arglen > 1 && argv[i][arglen - 2] == '\\') {
 | 
				
			||||||
 | 
								argv[i][arglen - 2] = ';';
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							new_argc = i - lastsplit;
 | 
				
			||||||
 | 
							new_argv = argv + lastsplit;
 | 
				
			||||||
 | 
							if (arglen != 1)
 | 
				
			||||||
 | 
								new_argc++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							cmd = cmd_parse(new_argc, new_argv, cause);
 | 
				
			||||||
 | 
							if (cmd == NULL)
 | 
				
			||||||
 | 
								goto bad;
 | 
				
			||||||
 | 
							TAILQ_INSERT_TAIL(cmdlist, cmd, qentry);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							lastsplit = i + 1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (lastsplit != argc) {
 | 
				
			||||||
 | 
							cmd = cmd_parse(argc - lastsplit, argv + lastsplit, cause);
 | 
				
			||||||
 | 
							if (cmd == NULL)
 | 
				
			||||||
 | 
								goto bad;
 | 
				
			||||||
 | 
							TAILQ_INSERT_TAIL(cmdlist, cmd, qentry);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (cmdlist);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bad:
 | 
				
			||||||
 | 
						cmd_list_free(cmdlist);
 | 
				
			||||||
 | 
						return (NULL);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_list_exec(struct cmd_list *cmdlist, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd	*cmd;
 | 
				
			||||||
 | 
						int		 n;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						TAILQ_FOREACH(cmd, cmdlist, qentry) {
 | 
				
			||||||
 | 
							if ((n = cmd_exec(cmd, ctx)) != 0)
 | 
				
			||||||
 | 
								return (n);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_list_send(struct cmd_list *cmdlist, struct buffer *b)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd	*cmd;
 | 
				
			||||||
 | 
						u_int		 n;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						n = 0;
 | 
				
			||||||
 | 
						TAILQ_FOREACH(cmd, cmdlist, qentry)
 | 
				
			||||||
 | 
						    	n++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						buffer_write(b, &n, sizeof n);
 | 
				
			||||||
 | 
						TAILQ_FOREACH(cmd, cmdlist, qentry)
 | 
				
			||||||
 | 
						    	cmd_send(cmd, b);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct cmd_list *
 | 
				
			||||||
 | 
					cmd_list_recv(struct buffer *b)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_list	*cmdlist;
 | 
				
			||||||
 | 
						struct cmd	*cmd;
 | 
				
			||||||
 | 
						u_int		 n;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						buffer_read(b, &n, sizeof n);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cmdlist = xmalloc(sizeof *cmdlist);
 | 
				
			||||||
 | 
						TAILQ_INIT(cmdlist);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while (n-- > 0) {
 | 
				
			||||||
 | 
							cmd = cmd_recv(b);
 | 
				
			||||||
 | 
							TAILQ_INSERT_TAIL(cmdlist, cmd, qentry);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (cmdlist);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_list_free(struct cmd_list *cmdlist)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd	*cmd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while (!TAILQ_EMPTY(cmdlist)) {
 | 
				
			||||||
 | 
							cmd = TAILQ_FIRST(cmdlist);
 | 
				
			||||||
 | 
							TAILQ_REMOVE(cmdlist, cmd, qentry);
 | 
				
			||||||
 | 
							cmd_free(cmd);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						xfree(cmdlist);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					size_t
 | 
				
			||||||
 | 
					cmd_list_print(struct cmd_list *cmdlist, char *buf, size_t len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd	*cmd;
 | 
				
			||||||
 | 
						size_t		 off;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						off = 0;
 | 
				
			||||||
 | 
						TAILQ_FOREACH(cmd, cmdlist, qentry) {
 | 
				
			||||||
 | 
							if (off >= len)
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							off += cmd_print(cmd, buf + off, len - off);
 | 
				
			||||||
 | 
							if (off >= len)
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							if (TAILQ_NEXT(cmd, qentry) != NULL)
 | 
				
			||||||
 | 
								off += xsnprintf(buf + off, len - off, " ; ");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return (off);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										106
									
								
								cmd-load-buffer.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								cmd-load-buffer.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,106 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					#include <sys/stat.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <errno.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Loads a session paste buffer from a file.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_load_buffer_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_load_buffer_entry = {
 | 
				
			||||||
 | 
						"load-buffer", "loadb",
 | 
				
			||||||
 | 
						CMD_BUFFER_SESSION_USAGE " path",
 | 
				
			||||||
 | 
						CMD_ARG1,
 | 
				
			||||||
 | 
						cmd_buffer_init,
 | 
				
			||||||
 | 
						cmd_buffer_parse,
 | 
				
			||||||
 | 
						cmd_load_buffer_exec,
 | 
				
			||||||
 | 
						cmd_buffer_send,
 | 
				
			||||||
 | 
						cmd_buffer_recv,
 | 
				
			||||||
 | 
						cmd_buffer_free,
 | 
				
			||||||
 | 
						cmd_buffer_print
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_load_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_buffer_data	*data = self->data;
 | 
				
			||||||
 | 
						struct session		*s;
 | 
				
			||||||
 | 
						struct stat		statbuf;
 | 
				
			||||||
 | 
						FILE			*f;
 | 
				
			||||||
 | 
						char			*buf;
 | 
				
			||||||
 | 
						u_int			limit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((s = cmd_find_session(ctx, data->target)) == NULL)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (stat(data->arg, &statbuf) < 0) {
 | 
				
			||||||
 | 
							ctx->error(ctx, "%s: %s", data->arg, strerror(errno));
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (!S_ISREG(statbuf.st_mode)) {
 | 
				
			||||||
 | 
							ctx->error(ctx, "%s: not a regular file", data->arg);
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((f = fopen(data->arg, "rb")) == NULL) {
 | 
				
			||||||
 | 
							ctx->error(ctx, "%s: %s", data->arg, strerror(errno));
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * We don't want to die due to memory exhaustion, hence xmalloc can't
 | 
				
			||||||
 | 
						 * be used here.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						if ((buf = malloc(statbuf.st_size + 1)) == NULL) {
 | 
				
			||||||
 | 
							ctx->error(ctx, "malloc error: %s", strerror(errno));
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (fread(buf, 1, statbuf.st_size, f) != (size_t) statbuf.st_size) {
 | 
				
			||||||
 | 
							ctx->error(ctx, "%s: fread error", data->arg);
 | 
				
			||||||
 | 
							xfree(buf);
 | 
				
			||||||
 | 
							fclose(f);
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						buf[statbuf.st_size] = '\0';
 | 
				
			||||||
 | 
						fclose(f);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						limit = options_get_number(&s->options, "buffer-limit");
 | 
				
			||||||
 | 
						if (data->buffer == -1) {
 | 
				
			||||||
 | 
							paste_add(&s->buffers, buf, limit);
 | 
				
			||||||
 | 
							return (0);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (paste_replace(&s->buffers, data->buffer, buf) != 0) {
 | 
				
			||||||
 | 
							ctx->error(ctx, "no buffer %d", data->buffer);
 | 
				
			||||||
 | 
							xfree(buf);
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										54
									
								
								cmd-lock-server.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								cmd-lock-server.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,54 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <pwd.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Lock server.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_lock_server_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_lock_server_callback(void *, const char *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_lock_server_entry = {
 | 
				
			||||||
 | 
						"lock-server", "lock",
 | 
				
			||||||
 | 
						"",
 | 
				
			||||||
 | 
						0,
 | 
				
			||||||
 | 
						NULL,
 | 
				
			||||||
 | 
						NULL,
 | 
				
			||||||
 | 
						cmd_lock_server_exec,
 | 
				
			||||||
 | 
						NULL,
 | 
				
			||||||
 | 
						NULL,
 | 
				
			||||||
 | 
						NULL,
 | 
				
			||||||
 | 
						NULL,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_lock_server_exec(unused struct cmd *self, unused struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						server_lock();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										123
									
								
								cmd-move-window.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								cmd-move-window.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,123 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Move a window.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_move_window_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_move_window_entry = {
 | 
				
			||||||
 | 
						"move-window", "movew",
 | 
				
			||||||
 | 
						"[-dk] " CMD_SRCDST_WINDOW_USAGE,
 | 
				
			||||||
 | 
						CMD_DFLAG|CMD_KFLAG,
 | 
				
			||||||
 | 
						cmd_srcdst_init,
 | 
				
			||||||
 | 
						cmd_srcdst_parse,
 | 
				
			||||||
 | 
						cmd_move_window_exec,
 | 
				
			||||||
 | 
						cmd_srcdst_send,
 | 
				
			||||||
 | 
						cmd_srcdst_recv,
 | 
				
			||||||
 | 
						cmd_srcdst_free,
 | 
				
			||||||
 | 
						cmd_srcdst_print
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_move_window_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_srcdst_data	*data = self->data;
 | 
				
			||||||
 | 
						struct session		*src, *dst;
 | 
				
			||||||
 | 
						struct winlink		*wl_src, *wl_dst;
 | 
				
			||||||
 | 
						struct client		*c;
 | 
				
			||||||
 | 
						u_int		 	 i;
 | 
				
			||||||
 | 
						int		 	 destroyed, idx;
 | 
				
			||||||
 | 
						char			*cause;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((wl_src = cmd_find_window(ctx, data->src, &src)) == NULL)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (arg_parse_window(data->dst, &dst, &idx) != 0) {
 | 
				
			||||||
 | 
							ctx->error(ctx, "bad window: %s", data->dst);
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (dst == NULL)
 | 
				
			||||||
 | 
							dst = ctx->cursession;
 | 
				
			||||||
 | 
						if (dst == NULL)
 | 
				
			||||||
 | 
							dst = cmd_current_session(ctx);
 | 
				
			||||||
 | 
						if (dst == NULL) {
 | 
				
			||||||
 | 
							ctx->error(ctx, "session not found: %s", data->dst);
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wl_dst = NULL;
 | 
				
			||||||
 | 
						if (idx != -1)
 | 
				
			||||||
 | 
							wl_dst = winlink_find_by_index(&dst->windows, idx);
 | 
				
			||||||
 | 
						if (wl_dst != NULL) {
 | 
				
			||||||
 | 
							if (wl_dst->window == wl_src->window)
 | 
				
			||||||
 | 
								return (0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (data->flags & CMD_KFLAG) {
 | 
				
			||||||
 | 
								/*
 | 
				
			||||||
 | 
								 * Can't use session_detach as it will destroy session
 | 
				
			||||||
 | 
								 * if this makes it empty.
 | 
				
			||||||
 | 
								 */
 | 
				
			||||||
 | 
								session_alert_cancel(dst, wl_dst);
 | 
				
			||||||
 | 
								winlink_stack_remove(&dst->lastw, wl_dst);
 | 
				
			||||||
 | 
								winlink_remove(&dst->windows, wl_dst);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								/* Force select/redraw if current. */
 | 
				
			||||||
 | 
								if (wl_dst == dst->curw) {
 | 
				
			||||||
 | 
									data->flags &= ~CMD_DFLAG;
 | 
				
			||||||
 | 
									dst->curw = NULL;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wl_dst = session_attach(dst, wl_src->window, idx, &cause);
 | 
				
			||||||
 | 
						if (wl_dst == NULL) {
 | 
				
			||||||
 | 
							ctx->error(ctx, "attach window failed: %s", cause);
 | 
				
			||||||
 | 
							xfree(cause);
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						destroyed = session_detach(src, wl_src);
 | 
				
			||||||
 | 
						for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
 | 
				
			||||||
 | 
							c = ARRAY_ITEM(&clients, i);
 | 
				
			||||||
 | 
							if (c == NULL || c->session != src)
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							if (destroyed) {
 | 
				
			||||||
 | 
								c->session = NULL;
 | 
				
			||||||
 | 
								server_write_client(c, MSG_EXIT, NULL, 0);
 | 
				
			||||||
 | 
							} else
 | 
				
			||||||
 | 
								server_redraw_client(c);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (data->flags & CMD_DFLAG)
 | 
				
			||||||
 | 
							server_status_session(dst);
 | 
				
			||||||
 | 
						else {
 | 
				
			||||||
 | 
							session_select(dst, wl_dst->idx);
 | 
				
			||||||
 | 
							server_redraw_session(dst);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						recalculate_sizes();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										248
									
								
								cmd-new-session.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										248
									
								
								cmd-new-session.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,248 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Create a new session and attach to the current terminal unless -d is given.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_new_session_parse(struct cmd *, int, char **, char **);
 | 
				
			||||||
 | 
					int	cmd_new_session_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					void	cmd_new_session_send(struct cmd *, struct buffer *);
 | 
				
			||||||
 | 
					void	cmd_new_session_recv(struct cmd *, struct buffer *);
 | 
				
			||||||
 | 
					void	cmd_new_session_free(struct cmd *);
 | 
				
			||||||
 | 
					void	cmd_new_session_init(struct cmd *, int);
 | 
				
			||||||
 | 
					size_t	cmd_new_session_print(struct cmd *, char *, size_t);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct cmd_new_session_data {
 | 
				
			||||||
 | 
						char	*newname;
 | 
				
			||||||
 | 
						char	*winname;
 | 
				
			||||||
 | 
						char	*cmd;
 | 
				
			||||||
 | 
						int	 flag_detached;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_new_session_entry = {
 | 
				
			||||||
 | 
						"new-session", "new",
 | 
				
			||||||
 | 
						"[-d] [-n window-name] [-s session-name] [command]",
 | 
				
			||||||
 | 
						CMD_STARTSERVER|CMD_CANTNEST,
 | 
				
			||||||
 | 
						cmd_new_session_init,
 | 
				
			||||||
 | 
						cmd_new_session_parse,
 | 
				
			||||||
 | 
						cmd_new_session_exec,
 | 
				
			||||||
 | 
						cmd_new_session_send,
 | 
				
			||||||
 | 
						cmd_new_session_recv,
 | 
				
			||||||
 | 
						cmd_new_session_free,
 | 
				
			||||||
 | 
						cmd_new_session_print
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_new_session_init(struct cmd *self, unused int arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_new_session_data	 *data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						self->data = data = xmalloc(sizeof *data);
 | 
				
			||||||
 | 
						data->flag_detached = 0;
 | 
				
			||||||
 | 
						data->newname = NULL;
 | 
				
			||||||
 | 
						data->winname = NULL;
 | 
				
			||||||
 | 
						data->cmd = NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_new_session_parse(struct cmd *self, int argc, char **argv, char **cause)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_new_session_data	*data;
 | 
				
			||||||
 | 
						int				 opt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						self->entry->init(self, 0);
 | 
				
			||||||
 | 
						data = self->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while ((opt = getopt(argc, argv, "ds:n:")) != -1) {
 | 
				
			||||||
 | 
							switch (opt) {
 | 
				
			||||||
 | 
							case 'd':
 | 
				
			||||||
 | 
								data->flag_detached = 1;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case 's':
 | 
				
			||||||
 | 
								if (data->newname == NULL)
 | 
				
			||||||
 | 
									data->newname = xstrdup(optarg);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case 'n':
 | 
				
			||||||
 | 
								if (data->winname == NULL)
 | 
				
			||||||
 | 
									data->winname = xstrdup(optarg);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								goto usage;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						argc -= optind;
 | 
				
			||||||
 | 
						argv += optind;
 | 
				
			||||||
 | 
						if (argc != 0 && argc != 1)
 | 
				
			||||||
 | 
							goto usage;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (argc == 1)
 | 
				
			||||||
 | 
							data->cmd = xstrdup(argv[0]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					usage:
 | 
				
			||||||
 | 
						xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						self->entry->free(self);
 | 
				
			||||||
 | 
						return (-1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_new_session_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_new_session_data	*data = self->data;
 | 
				
			||||||
 | 
						struct client			*c = ctx->cmdclient;
 | 
				
			||||||
 | 
						struct session			*s;
 | 
				
			||||||
 | 
						char				*cmd, *cwd, *cause;
 | 
				
			||||||
 | 
						u_int				 sx, sy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (ctx->curclient != NULL)
 | 
				
			||||||
 | 
							return (0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!data->flag_detached) {
 | 
				
			||||||
 | 
							if (c == NULL) {
 | 
				
			||||||
 | 
								ctx->error(ctx, "no client to attach to");
 | 
				
			||||||
 | 
								return (-1);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (!(c->flags & CLIENT_TERMINAL)) {
 | 
				
			||||||
 | 
								ctx->error(ctx, "not a terminal");
 | 
				
			||||||
 | 
								return (-1);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (data->newname != NULL && session_find(data->newname) != NULL) {
 | 
				
			||||||
 | 
							ctx->error(ctx, "duplicate session: %s", data->newname);
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cmd = data->cmd;
 | 
				
			||||||
 | 
						if (cmd == NULL)
 | 
				
			||||||
 | 
							cmd = options_get_string(&global_options, "default-command");
 | 
				
			||||||
 | 
						if (c == NULL || c->cwd == NULL)
 | 
				
			||||||
 | 
							cwd = options_get_string(&global_options, "default-path");
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							cwd = c->cwd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sx = 80;
 | 
				
			||||||
 | 
						sy = 25;
 | 
				
			||||||
 | 
						if (!data->flag_detached) {
 | 
				
			||||||
 | 
							sx = c->tty.sx;
 | 
				
			||||||
 | 
							sy = c->tty.sy;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (options_get_number(&global_options, "status")) {
 | 
				
			||||||
 | 
							if (sy == 0)
 | 
				
			||||||
 | 
								sy = 1;
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								sy--;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!data->flag_detached && tty_open(&c->tty, &cause) != 0) {
 | 
				
			||||||
 | 
							ctx->error(ctx, "open terminal failed: %s", cause);
 | 
				
			||||||
 | 
							xfree(cause);
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						s = session_create(data->newname, cmd, cwd, sx, sy, &cause);
 | 
				
			||||||
 | 
						if (s == NULL) {
 | 
				
			||||||
 | 
							ctx->error(ctx, "create session failed: %s", cause);
 | 
				
			||||||
 | 
							xfree(cause);
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (data->winname != NULL) {
 | 
				
			||||||
 | 
							xfree(s->curw->window->name);
 | 
				
			||||||
 | 
							s->curw->window->name = xstrdup(data->winname);
 | 
				
			||||||
 | 
							options_set_number(
 | 
				
			||||||
 | 
							    &s->curw->window->options, "automatic-rename", 0);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (data->flag_detached) {
 | 
				
			||||||
 | 
							if (c != NULL)
 | 
				
			||||||
 | 
								server_write_client(c, MSG_EXIT, NULL, 0);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							c->session = s;
 | 
				
			||||||
 | 
							server_write_client(c, MSG_READY, NULL, 0);
 | 
				
			||||||
 | 
							server_redraw_client(c);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						recalculate_sizes();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_new_session_send(struct cmd *self, struct buffer *b)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_new_session_data	*data = self->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						buffer_write(b, data, sizeof *data);
 | 
				
			||||||
 | 
						cmd_send_string(b, data->newname);
 | 
				
			||||||
 | 
						cmd_send_string(b, data->winname);
 | 
				
			||||||
 | 
						cmd_send_string(b, data->cmd);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_new_session_recv(struct cmd *self, struct buffer *b)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_new_session_data	*data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						self->data = data = xmalloc(sizeof *data);
 | 
				
			||||||
 | 
						buffer_read(b, data, sizeof *data);
 | 
				
			||||||
 | 
						data->newname = cmd_recv_string(b);
 | 
				
			||||||
 | 
						data->winname = cmd_recv_string(b);
 | 
				
			||||||
 | 
						data->cmd = cmd_recv_string(b);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_new_session_free(struct cmd *self)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_new_session_data	*data = self->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (data->newname != NULL)
 | 
				
			||||||
 | 
							xfree(data->newname);
 | 
				
			||||||
 | 
						if (data->winname != NULL)
 | 
				
			||||||
 | 
							xfree(data->winname);
 | 
				
			||||||
 | 
						if (data->cmd != NULL)
 | 
				
			||||||
 | 
							xfree(data->cmd);
 | 
				
			||||||
 | 
						xfree(data);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					size_t
 | 
				
			||||||
 | 
					cmd_new_session_print(struct cmd *self, char *buf, size_t len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_new_session_data	*data = self->data;
 | 
				
			||||||
 | 
						size_t				 off = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						off += xsnprintf(buf, len, "%s", self->entry->name);
 | 
				
			||||||
 | 
						if (data == NULL)
 | 
				
			||||||
 | 
							return (off);
 | 
				
			||||||
 | 
						if (off < len && data->flag_detached)
 | 
				
			||||||
 | 
							off += xsnprintf(buf + off, len - off, " -d");
 | 
				
			||||||
 | 
						if (off < len && data->newname != NULL)
 | 
				
			||||||
 | 
							off += cmd_prarg(buf + off, len - off, " -s ", data->newname);
 | 
				
			||||||
 | 
						if (off < len && data->winname != NULL)
 | 
				
			||||||
 | 
							off += cmd_prarg(buf + off, len - off, " -n ", data->winname);
 | 
				
			||||||
 | 
						if (off < len && data->cmd != NULL)
 | 
				
			||||||
 | 
							off += cmd_prarg(buf + off, len - off, " ", data->cmd);
 | 
				
			||||||
 | 
						return (off);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										241
									
								
								cmd-new-window.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										241
									
								
								cmd-new-window.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,241 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Create a new window.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_new_window_parse(struct cmd *, int, char **, char **);
 | 
				
			||||||
 | 
					int	cmd_new_window_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					void	cmd_new_window_send(struct cmd *, struct buffer *);
 | 
				
			||||||
 | 
					void	cmd_new_window_recv(struct cmd *, struct buffer *);
 | 
				
			||||||
 | 
					void	cmd_new_window_free(struct cmd *);
 | 
				
			||||||
 | 
					void	cmd_new_window_init(struct cmd *, int);
 | 
				
			||||||
 | 
					size_t	cmd_new_window_print(struct cmd *, char *, size_t);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct cmd_new_window_data {
 | 
				
			||||||
 | 
						char	*target;
 | 
				
			||||||
 | 
						char	*name;
 | 
				
			||||||
 | 
						char	*cmd;
 | 
				
			||||||
 | 
						int	 flag_detached;
 | 
				
			||||||
 | 
						int	 flag_kill;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_new_window_entry = {
 | 
				
			||||||
 | 
						"new-window", "neww",
 | 
				
			||||||
 | 
						"[-dk] [-n window-name] [-t target-window] [command]",
 | 
				
			||||||
 | 
						0,
 | 
				
			||||||
 | 
						cmd_new_window_init,
 | 
				
			||||||
 | 
						cmd_new_window_parse,
 | 
				
			||||||
 | 
						cmd_new_window_exec,
 | 
				
			||||||
 | 
						cmd_new_window_send,
 | 
				
			||||||
 | 
						cmd_new_window_recv,
 | 
				
			||||||
 | 
						cmd_new_window_free,
 | 
				
			||||||
 | 
						cmd_new_window_print
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_new_window_init(struct cmd *self, unused int arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_new_window_data	 *data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						self->data = data = xmalloc(sizeof *data);
 | 
				
			||||||
 | 
						data->target = NULL;
 | 
				
			||||||
 | 
						data->name = NULL;
 | 
				
			||||||
 | 
						data->cmd = NULL;
 | 
				
			||||||
 | 
						data->flag_detached = 0;
 | 
				
			||||||
 | 
						data->flag_kill = 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_new_window_parse(struct cmd *self, int argc, char **argv, char **cause)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_new_window_data	*data;
 | 
				
			||||||
 | 
						int				 opt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						self->entry->init(self, 0);
 | 
				
			||||||
 | 
						data = self->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while ((opt = getopt(argc, argv, "dkt:n:")) != -1) {
 | 
				
			||||||
 | 
							switch (opt) {
 | 
				
			||||||
 | 
							case 'd':
 | 
				
			||||||
 | 
								data->flag_detached = 1;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case 'k':
 | 
				
			||||||
 | 
								data->flag_kill = 1;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case 't':
 | 
				
			||||||
 | 
								if (data->target == NULL)
 | 
				
			||||||
 | 
									data->target = xstrdup(optarg);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case 'n':
 | 
				
			||||||
 | 
								if (data->name == NULL)
 | 
				
			||||||
 | 
									data->name = xstrdup(optarg);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								goto usage;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						argc -= optind;
 | 
				
			||||||
 | 
						argv += optind;
 | 
				
			||||||
 | 
						if (argc != 0 && argc != 1)
 | 
				
			||||||
 | 
							goto usage;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (argc == 1)
 | 
				
			||||||
 | 
							data->cmd = xstrdup(argv[0]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					usage:
 | 
				
			||||||
 | 
						xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						self->entry->free(self);
 | 
				
			||||||
 | 
						return (-1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_new_window_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_new_window_data	*data = self->data;
 | 
				
			||||||
 | 
						struct session			*s;
 | 
				
			||||||
 | 
						struct winlink			*wl;
 | 
				
			||||||
 | 
						char				*cmd, *cwd, *cause;
 | 
				
			||||||
 | 
						int				 idx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (data == NULL)
 | 
				
			||||||
 | 
							return (0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (arg_parse_window(data->target, &s, &idx) != 0) {
 | 
				
			||||||
 | 
							ctx->error(ctx, "bad window: %s", data->target);
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (s == NULL)
 | 
				
			||||||
 | 
							s = ctx->cursession;
 | 
				
			||||||
 | 
						if (s == NULL)
 | 
				
			||||||
 | 
							s = cmd_current_session(ctx);
 | 
				
			||||||
 | 
						if (s == NULL) {
 | 
				
			||||||
 | 
							ctx->error(ctx, "session not found: %s", data->target);
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wl = NULL;
 | 
				
			||||||
 | 
						if (idx != -1)
 | 
				
			||||||
 | 
							wl = winlink_find_by_index(&s->windows, idx);
 | 
				
			||||||
 | 
						if (wl != NULL) {
 | 
				
			||||||
 | 
							if (data->flag_kill) {
 | 
				
			||||||
 | 
								/*
 | 
				
			||||||
 | 
								 * Can't use session_detach as it will destroy session
 | 
				
			||||||
 | 
								 * if this makes it empty.
 | 
				
			||||||
 | 
								 */
 | 
				
			||||||
 | 
								session_alert_cancel(s, wl);
 | 
				
			||||||
 | 
								winlink_stack_remove(&s->lastw, wl);
 | 
				
			||||||
 | 
								winlink_remove(&s->windows, wl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								/* Force select/redraw if current. */
 | 
				
			||||||
 | 
								if (wl == s->curw) {
 | 
				
			||||||
 | 
									data->flag_detached = 0;
 | 
				
			||||||
 | 
									s->curw = NULL;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cmd = data->cmd;
 | 
				
			||||||
 | 
						if (cmd == NULL)
 | 
				
			||||||
 | 
							cmd = options_get_string(&s->options, "default-command");
 | 
				
			||||||
 | 
						if (ctx->cmdclient == NULL || ctx->cmdclient->cwd == NULL)
 | 
				
			||||||
 | 
							cwd = options_get_string(&global_options, "default-path");
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							cwd = ctx->cmdclient->cwd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wl = session_new(s, data->name, cmd, cwd, idx, &cause);
 | 
				
			||||||
 | 
						if (wl == NULL) {
 | 
				
			||||||
 | 
							ctx->error(ctx, "create window failed: %s", cause);
 | 
				
			||||||
 | 
							xfree(cause);
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (!data->flag_detached) {
 | 
				
			||||||
 | 
							session_select(s, wl->idx);
 | 
				
			||||||
 | 
							server_redraw_session(s);
 | 
				
			||||||
 | 
						} else
 | 
				
			||||||
 | 
							server_status_session(s);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_new_window_send(struct cmd *self, struct buffer *b)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_new_window_data	*data = self->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						buffer_write(b, data, sizeof *data);
 | 
				
			||||||
 | 
						cmd_send_string(b, data->target);
 | 
				
			||||||
 | 
						cmd_send_string(b, data->name);
 | 
				
			||||||
 | 
						cmd_send_string(b, data->cmd);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_new_window_recv(struct cmd *self, struct buffer *b)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_new_window_data	*data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						self->data = data = xmalloc(sizeof *data);
 | 
				
			||||||
 | 
						buffer_read(b, data, sizeof *data);
 | 
				
			||||||
 | 
						data->target = cmd_recv_string(b);
 | 
				
			||||||
 | 
						data->name = cmd_recv_string(b);
 | 
				
			||||||
 | 
						data->cmd = cmd_recv_string(b);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_new_window_free(struct cmd *self)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_new_window_data	*data = self->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (data->target != NULL)
 | 
				
			||||||
 | 
							xfree(data->target);
 | 
				
			||||||
 | 
						if (data->name != NULL)
 | 
				
			||||||
 | 
							xfree(data->name);
 | 
				
			||||||
 | 
						if (data->cmd != NULL)
 | 
				
			||||||
 | 
							xfree(data->cmd);
 | 
				
			||||||
 | 
						xfree(data);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					size_t
 | 
				
			||||||
 | 
					cmd_new_window_print(struct cmd *self, char *buf, size_t len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_new_window_data	*data = self->data;
 | 
				
			||||||
 | 
						size_t				 off = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						off += xsnprintf(buf, len, "%s", self->entry->name);
 | 
				
			||||||
 | 
						if (data == NULL)
 | 
				
			||||||
 | 
							return (off);
 | 
				
			||||||
 | 
						if (off < len && data->flag_detached)
 | 
				
			||||||
 | 
							off += xsnprintf(buf + off, len - off, " -d");
 | 
				
			||||||
 | 
						if (off < len && data->target != NULL)
 | 
				
			||||||
 | 
							off += cmd_prarg(buf + off, len - off, " -t ", data->target);
 | 
				
			||||||
 | 
						if (off < len && data->name != NULL)
 | 
				
			||||||
 | 
							off += cmd_prarg(buf + off, len - off, " -n ", data->name);
 | 
				
			||||||
 | 
						if (off < len && data->cmd != NULL)
 | 
				
			||||||
 | 
							off += cmd_prarg(buf + off, len - off, " ", data->cmd);
 | 
				
			||||||
 | 
						return (off);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										55
									
								
								cmd-next-layout.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								cmd-next-layout.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,55 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Switch window to next layout.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_next_layout_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_next_layout_entry = {
 | 
				
			||||||
 | 
						"next-layout", "nextl",
 | 
				
			||||||
 | 
						CMD_TARGET_WINDOW_USAGE,
 | 
				
			||||||
 | 
						0,
 | 
				
			||||||
 | 
						cmd_target_init,
 | 
				
			||||||
 | 
						cmd_target_parse,
 | 
				
			||||||
 | 
						cmd_next_layout_exec,
 | 
				
			||||||
 | 
						cmd_target_send,
 | 
				
			||||||
 | 
						cmd_target_recv,
 | 
				
			||||||
 | 
						cmd_target_free,
 | 
				
			||||||
 | 
						cmd_target_print
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_next_layout_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_target_data	*data = self->data;
 | 
				
			||||||
 | 
						struct winlink		*wl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						layout_next(wl->window);
 | 
				
			||||||
 | 
						ctx->info(ctx, "layout now: %s", layout_name(wl->window));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										78
									
								
								cmd-next-window.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								cmd-next-window.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,78 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Move to next window.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void	cmd_next_window_init(struct cmd *, int);
 | 
				
			||||||
 | 
					int	cmd_next_window_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_next_window_entry = {
 | 
				
			||||||
 | 
						"next-window", "next",
 | 
				
			||||||
 | 
						CMD_TARGET_SESSION_USAGE,
 | 
				
			||||||
 | 
						CMD_AFLAG,
 | 
				
			||||||
 | 
						cmd_next_window_init,
 | 
				
			||||||
 | 
						cmd_target_parse,
 | 
				
			||||||
 | 
						cmd_next_window_exec,
 | 
				
			||||||
 | 
						cmd_target_send,
 | 
				
			||||||
 | 
						cmd_target_recv,
 | 
				
			||||||
 | 
						cmd_target_free,
 | 
				
			||||||
 | 
						cmd_target_print
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_next_window_init(struct cmd *self, int key)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_target_data	*data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cmd_target_init(self, key);
 | 
				
			||||||
 | 
						data = self->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (key == KEYC_ADDESC('n'))
 | 
				
			||||||
 | 
							data->flags |= CMD_AFLAG;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_next_window_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_target_data	*data = self->data;
 | 
				
			||||||
 | 
						struct session		*s;
 | 
				
			||||||
 | 
						int			 activity;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((s = cmd_find_session(ctx, data->target)) == NULL)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						activity = 0;
 | 
				
			||||||
 | 
						if (data->flags & CMD_AFLAG)
 | 
				
			||||||
 | 
							activity = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (session_next(s, activity) == 0)
 | 
				
			||||||
 | 
							server_redraw_session(s);
 | 
				
			||||||
 | 
						else {
 | 
				
			||||||
 | 
							ctx->error(ctx, "no next window");
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						recalculate_sizes();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										78
									
								
								cmd-paste-buffer.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								cmd-paste-buffer.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,78 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Paste paste buffer if present.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_paste_buffer_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_paste_buffer_entry = {
 | 
				
			||||||
 | 
						"paste-buffer", "pasteb",
 | 
				
			||||||
 | 
						"[-d] " CMD_BUFFER_WINDOW_USAGE,
 | 
				
			||||||
 | 
						CMD_DFLAG,
 | 
				
			||||||
 | 
						cmd_buffer_init,
 | 
				
			||||||
 | 
						cmd_buffer_parse,
 | 
				
			||||||
 | 
						cmd_paste_buffer_exec,
 | 
				
			||||||
 | 
						cmd_buffer_send,
 | 
				
			||||||
 | 
						cmd_buffer_recv,
 | 
				
			||||||
 | 
						cmd_buffer_free,
 | 
				
			||||||
 | 
						cmd_buffer_print
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_paste_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_buffer_data	*data = self->data;
 | 
				
			||||||
 | 
						struct winlink		*wl;
 | 
				
			||||||
 | 
						struct window		*w;
 | 
				
			||||||
 | 
						struct session		*s;
 | 
				
			||||||
 | 
						struct paste_buffer	*pb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						w = wl->window;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (data->buffer == -1)
 | 
				
			||||||
 | 
							pb = paste_get_top(&s->buffers);
 | 
				
			||||||
 | 
						else {
 | 
				
			||||||
 | 
							if ((pb = paste_get_index(&s->buffers, data->buffer)) == NULL) {
 | 
				
			||||||
 | 
								ctx->error(ctx, "no buffer %d", data->buffer);
 | 
				
			||||||
 | 
								return (-1);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (pb != NULL)
 | 
				
			||||||
 | 
							buffer_write(w->active->out, pb->data, strlen(pb->data));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Delete the buffer if -d. */
 | 
				
			||||||
 | 
						if (data->flags & CMD_DFLAG) {
 | 
				
			||||||
 | 
							if (data->buffer == -1)
 | 
				
			||||||
 | 
								paste_free_top(&s->buffers);
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								paste_free_index(&s->buffers, data->buffer);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 	return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										55
									
								
								cmd-previous-layout.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								cmd-previous-layout.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,55 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Switch window to previous layout.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_previous_layout_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_previous_layout_entry = {
 | 
				
			||||||
 | 
						"previous-layout", "prevl",
 | 
				
			||||||
 | 
						CMD_TARGET_WINDOW_USAGE,
 | 
				
			||||||
 | 
						0,
 | 
				
			||||||
 | 
						cmd_target_init,
 | 
				
			||||||
 | 
						cmd_target_parse,
 | 
				
			||||||
 | 
						cmd_previous_layout_exec,
 | 
				
			||||||
 | 
						cmd_target_send,
 | 
				
			||||||
 | 
						cmd_target_recv,
 | 
				
			||||||
 | 
						cmd_target_free,
 | 
				
			||||||
 | 
						cmd_target_print
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_previous_layout_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_target_data	*data = self->data;
 | 
				
			||||||
 | 
						struct winlink		*wl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						layout_previous(wl->window);
 | 
				
			||||||
 | 
						ctx->info(ctx, "layout now: %s", layout_name(wl->window));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										78
									
								
								cmd-previous-window.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								cmd-previous-window.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,78 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Move to previous window.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void	cmd_previous_window_init(struct cmd *, int);
 | 
				
			||||||
 | 
					int	cmd_previous_window_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_previous_window_entry = {
 | 
				
			||||||
 | 
						"previous-window", "prev",
 | 
				
			||||||
 | 
						CMD_TARGET_SESSION_USAGE,
 | 
				
			||||||
 | 
						CMD_AFLAG,
 | 
				
			||||||
 | 
						cmd_previous_window_init,
 | 
				
			||||||
 | 
						cmd_target_parse,
 | 
				
			||||||
 | 
						cmd_previous_window_exec,
 | 
				
			||||||
 | 
						cmd_target_send,
 | 
				
			||||||
 | 
						cmd_target_recv,
 | 
				
			||||||
 | 
						cmd_target_free,
 | 
				
			||||||
 | 
						cmd_target_print
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_previous_window_init(struct cmd *self, int key)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_target_data	*data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cmd_target_init(self, key);
 | 
				
			||||||
 | 
						data = self->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (key == KEYC_ADDESC('p'))
 | 
				
			||||||
 | 
							data->flags |= CMD_AFLAG;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_previous_window_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_target_data	*data = self->data;
 | 
				
			||||||
 | 
						struct session		*s;
 | 
				
			||||||
 | 
						int			 activity;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((s = cmd_find_session(ctx, data->target)) == NULL)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						activity = 0;
 | 
				
			||||||
 | 
						if (data->flags & CMD_AFLAG)
 | 
				
			||||||
 | 
							activity = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (session_previous(s, activity) == 0)
 | 
				
			||||||
 | 
							server_redraw_session(s);
 | 
				
			||||||
 | 
						else {
 | 
				
			||||||
 | 
							ctx->error(ctx, "no previous window");
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						recalculate_sizes();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										54
									
								
								cmd-refresh-client.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								cmd-refresh-client.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,54 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Refresh client.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_refresh_client_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_refresh_client_entry = {
 | 
				
			||||||
 | 
						"refresh-client", "refresh",
 | 
				
			||||||
 | 
						CMD_TARGET_CLIENT_USAGE,
 | 
				
			||||||
 | 
						0,
 | 
				
			||||||
 | 
						cmd_target_init,
 | 
				
			||||||
 | 
						cmd_target_parse,
 | 
				
			||||||
 | 
						cmd_refresh_client_exec,
 | 
				
			||||||
 | 
						cmd_target_send,
 | 
				
			||||||
 | 
						cmd_target_recv,
 | 
				
			||||||
 | 
						cmd_target_free,
 | 
				
			||||||
 | 
						cmd_target_print
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_refresh_client_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_target_data	*data = self->data;
 | 
				
			||||||
 | 
						struct client		*c;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((c = cmd_find_client(ctx, data->target)) == NULL)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						server_redraw_client(c);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										57
									
								
								cmd-rename-session.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								cmd-rename-session.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,57 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Change session name.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_rename_session_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_rename_session_entry = {
 | 
				
			||||||
 | 
						"rename-session", "rename",
 | 
				
			||||||
 | 
						CMD_TARGET_SESSION_USAGE " new-name",
 | 
				
			||||||
 | 
						CMD_ARG1,
 | 
				
			||||||
 | 
						cmd_target_init,
 | 
				
			||||||
 | 
						cmd_target_parse,
 | 
				
			||||||
 | 
						cmd_rename_session_exec,
 | 
				
			||||||
 | 
						cmd_target_send,
 | 
				
			||||||
 | 
						cmd_target_recv,
 | 
				
			||||||
 | 
						cmd_target_free,
 | 
				
			||||||
 | 
						cmd_target_print
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_rename_session_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_target_data	*data = self->data;
 | 
				
			||||||
 | 
						struct session		*s;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((s = cmd_find_session(ctx, data->target)) == NULL)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						xfree(s->name);
 | 
				
			||||||
 | 
						s->name = xstrdup(data->arg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										61
									
								
								cmd-rename-window.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								cmd-rename-window.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,61 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Rename a window.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_rename_window_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_rename_window_entry = {
 | 
				
			||||||
 | 
						"rename-window", "renamew",
 | 
				
			||||||
 | 
						CMD_TARGET_WINDOW_USAGE " new-name",
 | 
				
			||||||
 | 
						CMD_ARG1,
 | 
				
			||||||
 | 
						cmd_target_init,
 | 
				
			||||||
 | 
						cmd_target_parse,
 | 
				
			||||||
 | 
						cmd_rename_window_exec,
 | 
				
			||||||
 | 
						cmd_target_send,
 | 
				
			||||||
 | 
						cmd_target_recv,
 | 
				
			||||||
 | 
						cmd_target_free,
 | 
				
			||||||
 | 
						cmd_target_print
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_rename_window_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_target_data	*data = self->data;
 | 
				
			||||||
 | 
						struct session		*s;
 | 
				
			||||||
 | 
						struct winlink		*wl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						xfree(wl->window->name);
 | 
				
			||||||
 | 
						wl->window->name = xstrdup(data->arg);
 | 
				
			||||||
 | 
						options_set_number(&wl->window->options, "automatic-rename", 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						server_status_session(s);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										105
									
								
								cmd-resize-pane.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								cmd-resize-pane.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,105 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Increase or decrease pane size.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void	cmd_resize_pane_init(struct cmd *, int);
 | 
				
			||||||
 | 
					int	cmd_resize_pane_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_resize_pane_entry = {
 | 
				
			||||||
 | 
						"resize-pane", "resizep",
 | 
				
			||||||
 | 
						CMD_PANE_WINDOW_USAGE "[-DU] [adjustment]",
 | 
				
			||||||
 | 
						CMD_ARG01|CMD_BIGUFLAG|CMD_BIGDFLAG,
 | 
				
			||||||
 | 
						cmd_resize_pane_init,
 | 
				
			||||||
 | 
						cmd_pane_parse,
 | 
				
			||||||
 | 
						cmd_resize_pane_exec,
 | 
				
			||||||
 | 
					       	cmd_pane_send,
 | 
				
			||||||
 | 
						cmd_pane_recv,
 | 
				
			||||||
 | 
						cmd_pane_free,
 | 
				
			||||||
 | 
						cmd_pane_print
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_resize_pane_init(struct cmd *self, int key)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_pane_data	*data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cmd_pane_init(self, key);
 | 
				
			||||||
 | 
						data = self->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (key == KEYC_ADDCTL(KEYC_DOWN))
 | 
				
			||||||
 | 
							data->flags |= CMD_BIGDFLAG;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (key == KEYC_ADDESC(KEYC_UP))
 | 
				
			||||||
 | 
							data->arg = xstrdup("5");
 | 
				
			||||||
 | 
						if (key == KEYC_ADDESC(KEYC_DOWN)) {
 | 
				
			||||||
 | 
							data->flags |= CMD_BIGDFLAG;
 | 
				
			||||||
 | 
							data->arg = xstrdup("5");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_resize_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_pane_data	*data = self->data;
 | 
				
			||||||
 | 
						struct winlink		*wl;
 | 
				
			||||||
 | 
						const char	       	*errstr;
 | 
				
			||||||
 | 
						struct window_pane	*wp;
 | 
				
			||||||
 | 
						u_int			 adjust;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						if (data->pane == -1)
 | 
				
			||||||
 | 
							wp = wl->window->active;
 | 
				
			||||||
 | 
						else {
 | 
				
			||||||
 | 
							wp = window_pane_at_index(wl->window, data->pane);
 | 
				
			||||||
 | 
							if (wp == NULL) {
 | 
				
			||||||
 | 
								ctx->error(ctx, "no pane: %d", data->pane);
 | 
				
			||||||
 | 
								return (-1);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (data->arg == NULL)
 | 
				
			||||||
 | 
							adjust = 1;
 | 
				
			||||||
 | 
						else {
 | 
				
			||||||
 | 
							adjust = strtonum(data->arg, 1, INT_MAX, &errstr);
 | 
				
			||||||
 | 
							if (errstr != NULL) {
 | 
				
			||||||
 | 
								ctx->error(ctx, "adjustment %s: %s", errstr, data->arg);
 | 
				
			||||||
 | 
								return (-1);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!(data->flags & CMD_BIGDFLAG))
 | 
				
			||||||
 | 
							adjust = -adjust;
 | 
				
			||||||
 | 
						if (layout_resize(wp, adjust) != 0) {
 | 
				
			||||||
 | 
							ctx->error(ctx, "layout %s "
 | 
				
			||||||
 | 
							    "does not support resizing", layout_name(wp->window));
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						server_redraw_window(wl->window);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										87
									
								
								cmd-respawn-window.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								cmd-respawn-window.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,87 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Respawn a window (restart the command). Kill existing if -k given.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_respawn_window_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_respawn_window_entry = {
 | 
				
			||||||
 | 
						"respawn-window", "respawnw",
 | 
				
			||||||
 | 
						"[-k] " CMD_TARGET_WINDOW_USAGE " [command]",
 | 
				
			||||||
 | 
						CMD_ARG01|CMD_KFLAG,
 | 
				
			||||||
 | 
						cmd_target_init,
 | 
				
			||||||
 | 
						cmd_target_parse,
 | 
				
			||||||
 | 
						cmd_respawn_window_exec,
 | 
				
			||||||
 | 
						cmd_target_send,
 | 
				
			||||||
 | 
						cmd_target_recv,
 | 
				
			||||||
 | 
						cmd_target_free,
 | 
				
			||||||
 | 
						cmd_target_print
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_respawn_window_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_target_data	*data = self->data;
 | 
				
			||||||
 | 
						struct winlink		*wl;
 | 
				
			||||||
 | 
						struct window		*w;
 | 
				
			||||||
 | 
						struct window_pane	*wp;
 | 
				
			||||||
 | 
						struct session		*s;
 | 
				
			||||||
 | 
						const char	       **env;
 | 
				
			||||||
 | 
						char		 	*cause;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						w = wl->window;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!(data->flags & CMD_KFLAG)) {
 | 
				
			||||||
 | 
							TAILQ_FOREACH(wp, &w->panes, entry) {
 | 
				
			||||||
 | 
								if (wp->fd == -1)
 | 
				
			||||||
 | 
									continue;
 | 
				
			||||||
 | 
								ctx->error(ctx,
 | 
				
			||||||
 | 
								    "window still active: %s:%d", s->name, wl->idx);
 | 
				
			||||||
 | 
								return (-1);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						env = server_fill_environ(s);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wp = TAILQ_FIRST(&w->panes);
 | 
				
			||||||
 | 
						TAILQ_REMOVE(&w->panes, wp, entry);
 | 
				
			||||||
 | 
					 	window_destroy_panes(w);
 | 
				
			||||||
 | 
						TAILQ_INSERT_HEAD(&w->panes, wp, entry);
 | 
				
			||||||
 | 
						window_pane_resize(wp, w->sx, w->sy);
 | 
				
			||||||
 | 
						if (window_pane_spawn(wp, data->arg, NULL, env, &cause) != 0) {
 | 
				
			||||||
 | 
							ctx->error(ctx, "respawn window failed: %s", cause);
 | 
				
			||||||
 | 
							xfree(cause);
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						screen_reinit(&wp->base);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						recalculate_sizes();
 | 
				
			||||||
 | 
						server_redraw_window(w);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										111
									
								
								cmd-rotate-window.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								cmd-rotate-window.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,111 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Rotate the panes in a window.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void	cmd_rotate_window_init(struct cmd *, int);
 | 
				
			||||||
 | 
					int	cmd_rotate_window_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_rotate_window_entry = {
 | 
				
			||||||
 | 
						"rotate-window", "rotatew",
 | 
				
			||||||
 | 
						"[-DU] " CMD_TARGET_WINDOW_USAGE,
 | 
				
			||||||
 | 
						CMD_BIGUFLAG|CMD_BIGDFLAG,
 | 
				
			||||||
 | 
						cmd_rotate_window_init,
 | 
				
			||||||
 | 
						cmd_target_parse,
 | 
				
			||||||
 | 
						cmd_rotate_window_exec,
 | 
				
			||||||
 | 
						cmd_target_send,
 | 
				
			||||||
 | 
						cmd_target_recv,
 | 
				
			||||||
 | 
						cmd_target_free,
 | 
				
			||||||
 | 
						cmd_target_print
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_rotate_window_init(struct cmd *self, int key)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_target_data	*data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cmd_target_init(self, key);
 | 
				
			||||||
 | 
						data = self->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (key == KEYC_ADDESC('o'))
 | 
				
			||||||
 | 
							data->flags |= CMD_BIGDFLAG;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_rotate_window_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_target_data	*data = self->data;
 | 
				
			||||||
 | 
						struct winlink		*wl;
 | 
				
			||||||
 | 
						struct window		*w;
 | 
				
			||||||
 | 
						struct window_pane	*wp, *wp2;
 | 
				
			||||||
 | 
						u_int			 sx, sy, xoff, yoff;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						w = wl->window;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (data->flags & CMD_BIGDFLAG) {
 | 
				
			||||||
 | 
							wp = TAILQ_LAST(&w->panes, window_panes);
 | 
				
			||||||
 | 
							TAILQ_REMOVE(&w->panes, wp, entry);
 | 
				
			||||||
 | 
							TAILQ_INSERT_HEAD(&w->panes, wp, entry);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							xoff = wp->xoff; yoff = wp->yoff;
 | 
				
			||||||
 | 
							sx = wp->sx; sy = wp->sy;
 | 
				
			||||||
 | 
							TAILQ_FOREACH(wp, &w->panes, entry) {
 | 
				
			||||||
 | 
								if ((wp2 = TAILQ_NEXT(wp, entry)) == NULL)
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								wp->xoff = wp2->xoff; wp->yoff = wp2->yoff;
 | 
				
			||||||
 | 
								window_pane_resize(wp, wp2->sx, wp2->sy);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							wp->xoff = xoff; wp->yoff = yoff;
 | 
				
			||||||
 | 
							window_pane_resize(wp, sx, sy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if ((wp = TAILQ_PREV(w->active, window_panes, entry)) == NULL)
 | 
				
			||||||
 | 
								wp = TAILQ_LAST(&w->panes, window_panes);
 | 
				
			||||||
 | 
							window_set_active_pane(w, wp);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							wp = TAILQ_FIRST(&w->panes);
 | 
				
			||||||
 | 
							TAILQ_REMOVE(&w->panes, wp, entry);
 | 
				
			||||||
 | 
							TAILQ_INSERT_TAIL(&w->panes, wp, entry);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							xoff = wp->xoff; yoff = wp->yoff;
 | 
				
			||||||
 | 
							sx = wp->sx; sy = wp->sy;
 | 
				
			||||||
 | 
							TAILQ_FOREACH_REVERSE(wp, &w->panes, window_panes, entry) {
 | 
				
			||||||
 | 
								if ((wp2 = TAILQ_PREV(wp, window_panes, entry)) == NULL)
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								wp->xoff = wp2->xoff; wp->yoff = wp2->yoff;
 | 
				
			||||||
 | 
								window_pane_resize(wp, wp2->sx, wp2->sy);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							wp->xoff = xoff; wp->yoff = yoff;
 | 
				
			||||||
 | 
							window_pane_resize(wp, sx, sy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if ((wp = TAILQ_NEXT(w->active, entry)) == NULL)
 | 
				
			||||||
 | 
								wp = TAILQ_FIRST(&w->panes);
 | 
				
			||||||
 | 
							window_set_active_pane(w, wp);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						layout_refresh(w, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										90
									
								
								cmd-save-buffer.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								cmd-save-buffer.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,90 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					#include <sys/stat.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <errno.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Saves a session paste buffer to a file.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_save_buffer_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_save_buffer_entry = {
 | 
				
			||||||
 | 
						"save-buffer", "saveb",
 | 
				
			||||||
 | 
						"[-a] " CMD_BUFFER_SESSION_USAGE " path",
 | 
				
			||||||
 | 
						CMD_AFLAG|CMD_ARG1,
 | 
				
			||||||
 | 
						cmd_buffer_init,
 | 
				
			||||||
 | 
						cmd_buffer_parse,
 | 
				
			||||||
 | 
						cmd_save_buffer_exec,
 | 
				
			||||||
 | 
						cmd_buffer_send,
 | 
				
			||||||
 | 
						cmd_buffer_recv,
 | 
				
			||||||
 | 
						cmd_buffer_free,
 | 
				
			||||||
 | 
						cmd_buffer_print
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_save_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_buffer_data	*data = self->data;
 | 
				
			||||||
 | 
						struct session		*s;
 | 
				
			||||||
 | 
						struct paste_buffer	*pb;
 | 
				
			||||||
 | 
						mode_t			mask;
 | 
				
			||||||
 | 
						FILE			*f;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((s = cmd_find_session(ctx, data->target)) == NULL)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (data->buffer == -1) {
 | 
				
			||||||
 | 
							if ((pb = paste_get_top(&s->buffers)) == NULL) {
 | 
				
			||||||
 | 
								ctx->error(ctx, "no buffers");
 | 
				
			||||||
 | 
								return (-1);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							if ((pb = paste_get_index(&s->buffers, data->buffer)) == NULL) {
 | 
				
			||||||
 | 
								ctx->error(ctx, "no buffer %d", data->buffer);
 | 
				
			||||||
 | 
								return (-1);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mask = umask(S_IRWXG | S_IRWXO);
 | 
				
			||||||
 | 
						if (data->flags & CMD_AFLAG)
 | 
				
			||||||
 | 
							f = fopen(data->arg, "ab");
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							f = fopen(data->arg, "wb");
 | 
				
			||||||
 | 
						if (f == NULL) {
 | 
				
			||||||
 | 
							ctx->error(ctx, "%s: %s", data->arg, strerror(errno));
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (fwrite(pb->data, 1, strlen(pb->data), f) != strlen(pb->data)) {
 | 
				
			||||||
 | 
						    	ctx->error(ctx, "%s: fwrite error", data->arg);
 | 
				
			||||||
 | 
						    	fclose(f);
 | 
				
			||||||
 | 
						    	return (-1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fclose(f);
 | 
				
			||||||
 | 
						umask(mask);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										72
									
								
								cmd-scroll-mode.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								cmd-scroll-mode.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,72 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Enter scroll mode.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void	cmd_scroll_mode_init(struct cmd *, int);
 | 
				
			||||||
 | 
					int	cmd_scroll_mode_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_scroll_mode_entry = {
 | 
				
			||||||
 | 
						"scroll-mode", NULL,
 | 
				
			||||||
 | 
						CMD_TARGET_WINDOW_USAGE,
 | 
				
			||||||
 | 
						CMD_UFLAG,
 | 
				
			||||||
 | 
						cmd_scroll_mode_init,
 | 
				
			||||||
 | 
						cmd_target_parse,
 | 
				
			||||||
 | 
						cmd_scroll_mode_exec,
 | 
				
			||||||
 | 
						cmd_target_send,
 | 
				
			||||||
 | 
						cmd_target_recv,
 | 
				
			||||||
 | 
						cmd_target_free,
 | 
				
			||||||
 | 
						cmd_target_print
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_scroll_mode_init(struct cmd *self, int key)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_target_data	*data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cmd_target_init(self, key);
 | 
				
			||||||
 | 
						data = self->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (key) {
 | 
				
			||||||
 | 
						case KEYC_PPAGE:
 | 
				
			||||||
 | 
							data->flags |= CMD_UFLAG;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_scroll_mode_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_target_data	*data = self->data;
 | 
				
			||||||
 | 
						struct winlink		*wl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						window_pane_set_mode(wl->window->active, &window_scroll_mode);
 | 
				
			||||||
 | 
						if (data->flags & CMD_UFLAG)
 | 
				
			||||||
 | 
							window_scroll_pageup(wl->window->active);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										86
									
								
								cmd-select-layout.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								cmd-select-layout.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,86 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Switch window to selected layout.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void	cmd_select_layout_init(struct cmd *, int);
 | 
				
			||||||
 | 
					int	cmd_select_layout_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_select_layout_entry = {
 | 
				
			||||||
 | 
						"select-layout", "selectl",
 | 
				
			||||||
 | 
						CMD_TARGET_WINDOW_USAGE " layout-name",
 | 
				
			||||||
 | 
						CMD_ARG1,
 | 
				
			||||||
 | 
						cmd_select_layout_init,
 | 
				
			||||||
 | 
						cmd_target_parse,
 | 
				
			||||||
 | 
						cmd_select_layout_exec,
 | 
				
			||||||
 | 
						cmd_target_send,
 | 
				
			||||||
 | 
						cmd_target_recv,
 | 
				
			||||||
 | 
						cmd_target_free,
 | 
				
			||||||
 | 
						cmd_target_print
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_select_layout_init(struct cmd *self, int key)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_target_data	*data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cmd_target_init(self, key);
 | 
				
			||||||
 | 
						data = self->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (key) {
 | 
				
			||||||
 | 
						case KEYC_ADDESC('0'):
 | 
				
			||||||
 | 
							data->arg = xstrdup("manual-vertical");
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case KEYC_ADDESC('1'):
 | 
				
			||||||
 | 
							data->arg = xstrdup("even-horizontal");
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case KEYC_ADDESC('2'):
 | 
				
			||||||
 | 
							data->arg = xstrdup("even-vertical");
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case KEYC_ADDESC('9'):
 | 
				
			||||||
 | 
							data->arg = xstrdup("active-only");
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_select_layout_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_target_data	*data = self->data;
 | 
				
			||||||
 | 
						struct winlink		*wl;
 | 
				
			||||||
 | 
						int			 layout;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((layout = layout_lookup(data->arg)) == -1) {
 | 
				
			||||||
 | 
							ctx->error(ctx, "unknown or ambiguous layout: %s", data->arg);
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (layout_select(wl->window, layout) == 0)
 | 
				
			||||||
 | 
							ctx->info(ctx, "layout now: %s", layout_name(wl->window));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										69
									
								
								cmd-select-pane.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								cmd-select-pane.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,69 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Select pane.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_select_pane_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_select_pane_entry = {
 | 
				
			||||||
 | 
						"select-pane", "selectp",
 | 
				
			||||||
 | 
						CMD_PANE_WINDOW_USAGE,
 | 
				
			||||||
 | 
						0,
 | 
				
			||||||
 | 
						cmd_pane_init,
 | 
				
			||||||
 | 
						cmd_pane_parse,
 | 
				
			||||||
 | 
						cmd_select_pane_exec,
 | 
				
			||||||
 | 
					       	cmd_pane_send,
 | 
				
			||||||
 | 
						cmd_pane_recv,
 | 
				
			||||||
 | 
						cmd_pane_free,
 | 
				
			||||||
 | 
						cmd_pane_print
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_select_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_pane_data	*data = self->data;
 | 
				
			||||||
 | 
						struct winlink		*wl;
 | 
				
			||||||
 | 
						struct window_pane	*wp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						if (data->pane == -1)
 | 
				
			||||||
 | 
							wp = wl->window->active;
 | 
				
			||||||
 | 
						else {
 | 
				
			||||||
 | 
							wp = window_pane_at_index(wl->window, data->pane);
 | 
				
			||||||
 | 
							if (wp == NULL) {
 | 
				
			||||||
 | 
								ctx->error(ctx, "no pane: %d", data->pane);
 | 
				
			||||||
 | 
								return (-1);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (wp->flags & PANE_HIDDEN) {
 | 
				
			||||||
 | 
							ctx->error(ctx, "pane %d is hidden", data->pane);
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						window_set_active_pane(wl->window, wp);
 | 
				
			||||||
 | 
						layout_refresh(wl->window, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										93
									
								
								cmd-select-prompt.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								cmd-select-prompt.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,93 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Prompt for window index and select it.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_select_prompt_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_select_prompt_callback(void *, const char *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_select_prompt_entry = {
 | 
				
			||||||
 | 
						"select-prompt", NULL,
 | 
				
			||||||
 | 
						CMD_TARGET_CLIENT_USAGE,
 | 
				
			||||||
 | 
						0,
 | 
				
			||||||
 | 
						cmd_target_init,
 | 
				
			||||||
 | 
						cmd_target_parse,
 | 
				
			||||||
 | 
						cmd_select_prompt_exec,
 | 
				
			||||||
 | 
						cmd_target_send,
 | 
				
			||||||
 | 
						cmd_target_recv,
 | 
				
			||||||
 | 
						cmd_target_free,
 | 
				
			||||||
 | 
						cmd_target_print
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_select_prompt_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_target_data	*data = self->data;
 | 
				
			||||||
 | 
						struct client		*c;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((c = cmd_find_client(ctx, data->target)) == NULL)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (c->prompt_string != NULL)
 | 
				
			||||||
 | 
							return (0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						status_prompt_set(c, "index ", cmd_select_prompt_callback, c, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_select_prompt_callback(void *data, const char *s)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct client	*c = data;
 | 
				
			||||||
 | 
						const char	*errstr;
 | 
				
			||||||
 | 
						char		 msg[128];
 | 
				
			||||||
 | 
						u_int		 idx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (s == NULL)
 | 
				
			||||||
 | 
							return (0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						idx = strtonum(s, 0, UINT_MAX, &errstr);
 | 
				
			||||||
 | 
						if (errstr != NULL) {
 | 
				
			||||||
 | 
							xsnprintf(msg, sizeof msg, "Index %s: %s", errstr, s);
 | 
				
			||||||
 | 
							status_message_set(c, msg);
 | 
				
			||||||
 | 
							return (0);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (winlink_find_by_index(&c->session->windows, idx) == NULL) {
 | 
				
			||||||
 | 
							xsnprintf(msg, sizeof msg,
 | 
				
			||||||
 | 
							    "Window not found: %s:%d", c->session->name, idx);
 | 
				
			||||||
 | 
							status_message_set(c, msg);
 | 
				
			||||||
 | 
							return (0);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (session_select(c->session, idx) == 0)
 | 
				
			||||||
 | 
							server_redraw_session(c->session);
 | 
				
			||||||
 | 
						recalculate_sizes();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										71
									
								
								cmd-select-window.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								cmd-select-window.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,71 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Select window by index.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void	cmd_select_window_init(struct cmd *, int);
 | 
				
			||||||
 | 
					int	cmd_select_window_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_select_window_entry = {
 | 
				
			||||||
 | 
						"select-window", "selectw",
 | 
				
			||||||
 | 
						CMD_TARGET_WINDOW_USAGE,
 | 
				
			||||||
 | 
						0,
 | 
				
			||||||
 | 
						cmd_select_window_init,
 | 
				
			||||||
 | 
						cmd_target_parse,
 | 
				
			||||||
 | 
						cmd_select_window_exec,
 | 
				
			||||||
 | 
						cmd_target_send,
 | 
				
			||||||
 | 
						cmd_target_recv,
 | 
				
			||||||
 | 
						cmd_target_free,
 | 
				
			||||||
 | 
						cmd_target_print
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_select_window_init(struct cmd *self, int key)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_target_data	*data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cmd_target_init(self, key);
 | 
				
			||||||
 | 
						data = self->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						xasprintf(&data->target, ":%d", key - '0');
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_select_window_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_target_data	*data = self->data;
 | 
				
			||||||
 | 
						struct winlink		*wl;
 | 
				
			||||||
 | 
						struct session		*s;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (session_select(s, wl->idx) == 0)
 | 
				
			||||||
 | 
							server_redraw_session(s);
 | 
				
			||||||
 | 
						recalculate_sizes();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										184
									
								
								cmd-send-keys.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										184
									
								
								cmd-send-keys.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,184 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Send keys to client.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_send_keys_parse(struct cmd *, int, char **, char **);
 | 
				
			||||||
 | 
					int	cmd_send_keys_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					void	cmd_send_keys_send(struct cmd *, struct buffer *);
 | 
				
			||||||
 | 
					void	cmd_send_keys_recv(struct cmd *, struct buffer *);
 | 
				
			||||||
 | 
					void	cmd_send_keys_free(struct cmd *);
 | 
				
			||||||
 | 
					size_t	cmd_send_keys_print(struct cmd *, char *, size_t);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct cmd_send_keys_data {
 | 
				
			||||||
 | 
						char	*target;
 | 
				
			||||||
 | 
						int	 idx;
 | 
				
			||||||
 | 
					  	u_int	 nkeys;
 | 
				
			||||||
 | 
						int	*keys;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_send_keys_entry = {
 | 
				
			||||||
 | 
						"send-keys", "send",
 | 
				
			||||||
 | 
						"[-t target-window] key ...",
 | 
				
			||||||
 | 
						0,
 | 
				
			||||||
 | 
						NULL,
 | 
				
			||||||
 | 
						cmd_send_keys_parse,
 | 
				
			||||||
 | 
						cmd_send_keys_exec,
 | 
				
			||||||
 | 
						cmd_send_keys_send,
 | 
				
			||||||
 | 
						cmd_send_keys_recv,
 | 
				
			||||||
 | 
						cmd_send_keys_free,
 | 
				
			||||||
 | 
						cmd_send_keys_print
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_send_keys_parse(struct cmd *self, int argc, char **argv, char **cause)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_send_keys_data	*data;
 | 
				
			||||||
 | 
						int				 opt, key;
 | 
				
			||||||
 | 
						char				*s;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						self->data = data = xmalloc(sizeof *data);
 | 
				
			||||||
 | 
						data->target = NULL;
 | 
				
			||||||
 | 
						data->idx = -1;
 | 
				
			||||||
 | 
						data->nkeys = 0;
 | 
				
			||||||
 | 
						data->keys = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while ((opt = getopt(argc, argv, "t:")) != -1) {
 | 
				
			||||||
 | 
							switch (opt) {
 | 
				
			||||||
 | 
							case 't':
 | 
				
			||||||
 | 
								if (data->target == NULL)
 | 
				
			||||||
 | 
									data->target = xstrdup(optarg);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								goto usage;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						argc -= optind;
 | 
				
			||||||
 | 
						argv += optind;
 | 
				
			||||||
 | 
						if (argc == 0)
 | 
				
			||||||
 | 
							goto usage;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while (argc-- != 0) {
 | 
				
			||||||
 | 
							if ((key = key_string_lookup_string(*argv)) != KEYC_NONE) {
 | 
				
			||||||
 | 
								data->keys = xrealloc(
 | 
				
			||||||
 | 
								    data->keys, data->nkeys + 1, sizeof *data->keys);
 | 
				
			||||||
 | 
								data->keys[data->nkeys++] = key;
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								for (s = *argv; *s != '\0'; s++) {
 | 
				
			||||||
 | 
									data->keys = xrealloc(data->keys,
 | 
				
			||||||
 | 
									    data->nkeys + 1, sizeof *data->keys);
 | 
				
			||||||
 | 
									data->keys[data->nkeys++] = *s;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							argv++;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					usage:
 | 
				
			||||||
 | 
						xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						self->entry->free(self);
 | 
				
			||||||
 | 
						return (-1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_send_keys_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_send_keys_data	*data = self->data;
 | 
				
			||||||
 | 
						struct winlink			*wl;
 | 
				
			||||||
 | 
						u_int				 i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (data == NULL)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < data->nkeys; i++) {
 | 
				
			||||||
 | 
							window_pane_key(
 | 
				
			||||||
 | 
							    wl->window->active, ctx->curclient, data->keys[i]);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_send_keys_send(struct cmd *self, struct buffer *b)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_send_keys_data	*data = self->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						buffer_write(b, data, sizeof *data);
 | 
				
			||||||
 | 
						cmd_send_string(b, data->target);
 | 
				
			||||||
 | 
						buffer_write(b, data->keys, data->nkeys * sizeof *data->keys);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_send_keys_recv(struct cmd *self, struct buffer *b)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_send_keys_data	*data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						self->data = data = xmalloc(sizeof *data);
 | 
				
			||||||
 | 
						buffer_read(b, data, sizeof *data);
 | 
				
			||||||
 | 
						data->target = cmd_recv_string(b);
 | 
				
			||||||
 | 
						data->keys = xcalloc(data->nkeys, sizeof *data->keys);
 | 
				
			||||||
 | 
						buffer_read(b, data->keys, data->nkeys * sizeof *data->keys);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_send_keys_free(struct cmd *self)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_send_keys_data	*data = self->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (data->target != NULL)
 | 
				
			||||||
 | 
							xfree(data->target);
 | 
				
			||||||
 | 
						xfree(data);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					size_t
 | 
				
			||||||
 | 
					cmd_send_keys_print(struct cmd *self, char *buf, size_t len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_send_keys_data	*data = self->data;
 | 
				
			||||||
 | 
						size_t				 off = 0;
 | 
				
			||||||
 | 
						u_int				 i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						off += xsnprintf(buf, len, "%s", self->entry->name);
 | 
				
			||||||
 | 
						if (data == NULL)
 | 
				
			||||||
 | 
							return (off);
 | 
				
			||||||
 | 
						if (off < len && data->target != NULL)
 | 
				
			||||||
 | 
							off += cmd_prarg(buf + off, len - off, " -t ", data->target);
 | 
				
			||||||
 | 
						if (off < len && data->idx != -1)
 | 
				
			||||||
 | 
							off += xsnprintf(buf + off, len - off, " -i %d", data->idx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < data->nkeys; i++) {
 | 
				
			||||||
 | 
							if (off >= len)
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							off += xsnprintf(buf + off,
 | 
				
			||||||
 | 
							    len - off, " %s", key_string_lookup_key(data->keys[i]));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return (off);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										57
									
								
								cmd-send-prefix.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								cmd-send-prefix.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,57 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Send prefix key as a key.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_send_prefix_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_send_prefix_entry = {
 | 
				
			||||||
 | 
						"send-prefix", NULL,
 | 
				
			||||||
 | 
						CMD_TARGET_WINDOW_USAGE,
 | 
				
			||||||
 | 
						0,
 | 
				
			||||||
 | 
						cmd_target_init,
 | 
				
			||||||
 | 
						cmd_target_parse,
 | 
				
			||||||
 | 
						cmd_send_prefix_exec,
 | 
				
			||||||
 | 
						cmd_target_send,
 | 
				
			||||||
 | 
						cmd_target_recv,
 | 
				
			||||||
 | 
						cmd_target_free,
 | 
				
			||||||
 | 
						cmd_target_print
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_send_prefix_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_target_data	*data = self->data;
 | 
				
			||||||
 | 
						struct session		*s;
 | 
				
			||||||
 | 
						struct winlink		*wl;
 | 
				
			||||||
 | 
						int			 key;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						key = options_get_number(&s->options, "prefix");
 | 
				
			||||||
 | 
						window_pane_key(wl->window->active, ctx->curclient, key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										179
									
								
								cmd-server-info.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										179
									
								
								cmd-server-info.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,179 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					#include <sys/utsname.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <time.h>
 | 
				
			||||||
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Show various information about server.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_server_info_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_server_info_entry = {
 | 
				
			||||||
 | 
						"server-info", "info",
 | 
				
			||||||
 | 
						"",
 | 
				
			||||||
 | 
						0,
 | 
				
			||||||
 | 
						NULL,
 | 
				
			||||||
 | 
						NULL,
 | 
				
			||||||
 | 
						cmd_server_info_exec,
 | 
				
			||||||
 | 
						NULL,
 | 
				
			||||||
 | 
						NULL,
 | 
				
			||||||
 | 
						NULL,
 | 
				
			||||||
 | 
						NULL
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct tty_term			*term;
 | 
				
			||||||
 | 
						struct client			*c;
 | 
				
			||||||
 | 
						struct session			*s;
 | 
				
			||||||
 | 
						struct winlink			*wl;
 | 
				
			||||||
 | 
						struct window			*w;
 | 
				
			||||||
 | 
						struct window_pane		*wp;
 | 
				
			||||||
 | 
						struct tty_code			*code;
 | 
				
			||||||
 | 
						struct tty_term_code_entry	*ent;
 | 
				
			||||||
 | 
						struct utsname			 un;
 | 
				
			||||||
 | 
						struct grid			*gd;
 | 
				
			||||||
 | 
						u_int		 		 i, j, k;
 | 
				
			||||||
 | 
						char				 out[80];
 | 
				
			||||||
 | 
						char				*tim;
 | 
				
			||||||
 | 
						time_t		 		 t;
 | 
				
			||||||
 | 
						u_int				 lines, ulines;
 | 
				
			||||||
 | 
						size_t				 size, usize;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tim = ctime(&start_time);
 | 
				
			||||||
 | 
						*strchr(tim, '\n') = '\0';
 | 
				
			||||||
 | 
						ctx->print(ctx, "pid %ld, started %s", (long) getpid(), tim);
 | 
				
			||||||
 | 
						ctx->print(ctx, "socket path %s, debug level %d%s",
 | 
				
			||||||
 | 
						    socket_path, debug_level, be_quiet ? ", quiet" : "");
 | 
				
			||||||
 | 
					        if (uname(&un) == 0) {
 | 
				
			||||||
 | 
					                ctx->print(ctx, "system is %s %s %s %s",
 | 
				
			||||||
 | 
							    un.sysname, un.release, un.version, un.machine);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (cfg_file != NULL)
 | 
				
			||||||
 | 
							ctx->print(ctx, "configuration file is %s", cfg_file);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							ctx->print(ctx, "configuration file not specified");
 | 
				
			||||||
 | 
						ctx->print(ctx, "protocol version is %d", PROTOCOL_VERSION);
 | 
				
			||||||
 | 
						ctx->print(ctx, "%u clients, %u sessions",
 | 
				
			||||||
 | 
						    ARRAY_LENGTH(&clients), ARRAY_LENGTH(&sessions));
 | 
				
			||||||
 | 
						ctx->print(ctx, "");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ctx->print(ctx, "Clients:");
 | 
				
			||||||
 | 
						for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
 | 
				
			||||||
 | 
							c = ARRAY_ITEM(&clients, i);
 | 
				
			||||||
 | 
							if (c == NULL || c->session == NULL)
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							ctx->print(ctx, "%2d: %s (%d, %d): %s [%ux%u %s] "
 | 
				
			||||||
 | 
							    "[flags=0x%x/0x%x]", i, c->tty.path, c->fd, c->tty.fd,
 | 
				
			||||||
 | 
							    c->session->name, c->tty.sx, c->tty.sy, c->tty.termname,
 | 
				
			||||||
 | 
							    c->flags, c->tty.flags);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ctx->print(ctx, "");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 	ctx->print(ctx, "Sessions: [%zu/%zu]",
 | 
				
			||||||
 | 
						    sizeof (struct grid_cell), sizeof (struct grid_utf8));
 | 
				
			||||||
 | 
						for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
 | 
				
			||||||
 | 
							s = ARRAY_ITEM(&sessions, i);
 | 
				
			||||||
 | 
							if (s == NULL)
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							t = s->tv.tv_sec;
 | 
				
			||||||
 | 
							tim = ctime(&t);
 | 
				
			||||||
 | 
							*strchr(tim, '\n') = '\0';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							ctx->print(ctx, "%2u: %s: %u windows (created %s) [%ux%u] "
 | 
				
			||||||
 | 
							    "[flags=0x%x]", i, s->name, winlink_count(&s->windows),
 | 
				
			||||||
 | 
							    tim, s->sx, s->sy, s->flags);
 | 
				
			||||||
 | 
							RB_FOREACH(wl, winlinks, &s->windows) {
 | 
				
			||||||
 | 
								w = wl->window;
 | 
				
			||||||
 | 
								ctx->print(ctx, "%4u: %s [%ux%u] [flags=0x%x, "
 | 
				
			||||||
 | 
								    "references=%u, layout=%u]", wl->idx, w->name,
 | 
				
			||||||
 | 
								    w->sx, w->sy, w->flags, w->references,
 | 
				
			||||||
 | 
								    w->layout);
 | 
				
			||||||
 | 
								j = 0;
 | 
				
			||||||
 | 
								TAILQ_FOREACH(wp, &w->panes, entry) {
 | 
				
			||||||
 | 
									lines = ulines = size = usize = 0;
 | 
				
			||||||
 | 
									gd = wp->base.grid;
 | 
				
			||||||
 | 
									for (k = 0; k < gd->hsize + gd->sy; k++) {
 | 
				
			||||||
 | 
										if (gd->data[k] != NULL) {
 | 
				
			||||||
 | 
											lines++;
 | 
				
			||||||
 | 
											size += gd->size[k] *
 | 
				
			||||||
 | 
											    sizeof (**gd->data);
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										if (gd->udata[k] != NULL) {
 | 
				
			||||||
 | 
											ulines++;
 | 
				
			||||||
 | 
											usize += gd->usize[k] *
 | 
				
			||||||
 | 
											    sizeof (**gd->udata);
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									ctx->print(ctx, "%6u: %s %lu %d %u/%u, %zu "
 | 
				
			||||||
 | 
									    "bytes; UTF-8 %u/%u, %zu bytes", j,
 | 
				
			||||||
 | 
									    wp->tty, (u_long) wp->pid, wp->fd, lines,
 | 
				
			||||||
 | 
									    gd->hsize + gd->sy, size, ulines,
 | 
				
			||||||
 | 
									    gd->hsize + gd->sy, usize);
 | 
				
			||||||
 | 
									j++;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ctx->print(ctx, "");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  	ctx->print(ctx, "Terminals:");
 | 
				
			||||||
 | 
						SLIST_FOREACH(term, &tty_terms, entry) {
 | 
				
			||||||
 | 
							ctx->print(ctx, "%s [references=%u, flags=0x%x]:",
 | 
				
			||||||
 | 
							    term->name, term->references, term->flags);
 | 
				
			||||||
 | 
							for (i = 0; i < NTTYCODE; i++) {
 | 
				
			||||||
 | 
								ent = &tty_term_codes[i];
 | 
				
			||||||
 | 
								code = &term->codes[ent->code];
 | 
				
			||||||
 | 
								switch (code->type) {
 | 
				
			||||||
 | 
								case TTYCODE_NONE:
 | 
				
			||||||
 | 
									ctx->print(ctx, "%2u: %s: [missing]",
 | 
				
			||||||
 | 
									    ent->code, ent->name);
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								case TTYCODE_STRING:
 | 
				
			||||||
 | 
									clean_string(
 | 
				
			||||||
 | 
									    code->value.string, out, sizeof out);
 | 
				
			||||||
 | 
									ctx->print(ctx, "%2u: %s: (string) %s",
 | 
				
			||||||
 | 
									    ent->code, ent->name, out);
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								case TTYCODE_NUMBER:
 | 
				
			||||||
 | 
									ctx->print(ctx, "%2u: %s: (number) %d",
 | 
				
			||||||
 | 
									    ent->code, ent->name, code->value.number);
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								case TTYCODE_FLAG:
 | 
				
			||||||
 | 
									ctx->print(ctx, "%2u: %s: (flag) %s",
 | 
				
			||||||
 | 
									    ent->code, ent->name,
 | 
				
			||||||
 | 
									    code->value.flag ? "true" : "false");
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ctx->print(ctx, "");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										64
									
								
								cmd-set-buffer.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								cmd-set-buffer.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,64 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Add or set a session paste buffer.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_set_buffer_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_set_buffer_entry = {
 | 
				
			||||||
 | 
						"set-buffer", "setb",
 | 
				
			||||||
 | 
						CMD_BUFFER_SESSION_USAGE " data",
 | 
				
			||||||
 | 
						CMD_ARG1,
 | 
				
			||||||
 | 
						cmd_buffer_init,
 | 
				
			||||||
 | 
						cmd_buffer_parse,
 | 
				
			||||||
 | 
						cmd_set_buffer_exec,
 | 
				
			||||||
 | 
						cmd_buffer_send,
 | 
				
			||||||
 | 
						cmd_buffer_recv,
 | 
				
			||||||
 | 
						cmd_buffer_free,
 | 
				
			||||||
 | 
						cmd_buffer_print
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_set_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_buffer_data	*data = self->data;
 | 
				
			||||||
 | 
						struct session		*s;
 | 
				
			||||||
 | 
						u_int			 limit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((s = cmd_find_session(ctx, data->target)) == NULL)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						limit = options_get_number(&s->options, "buffer-limit");
 | 
				
			||||||
 | 
						if (data->buffer == -1) {
 | 
				
			||||||
 | 
							paste_add(&s->buffers, xstrdup(data->arg), limit);
 | 
				
			||||||
 | 
							return (0);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (paste_replace(&s->buffers, data->buffer, xstrdup(data->arg)) != 0) {
 | 
				
			||||||
 | 
							ctx->error(ctx, "no buffer %d", data->buffer);
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										169
									
								
								cmd-set-option.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										169
									
								
								cmd-set-option.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,169 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Set an option.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_set_option_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_set_option_entry = {
 | 
				
			||||||
 | 
						"set-option", "set",
 | 
				
			||||||
 | 
						CMD_OPTION_SESSION_USAGE,
 | 
				
			||||||
 | 
						CMD_GFLAG|CMD_UFLAG,
 | 
				
			||||||
 | 
						NULL,
 | 
				
			||||||
 | 
						cmd_option_parse,
 | 
				
			||||||
 | 
						cmd_set_option_exec,
 | 
				
			||||||
 | 
						cmd_option_send,
 | 
				
			||||||
 | 
						cmd_option_recv,
 | 
				
			||||||
 | 
						cmd_option_free,
 | 
				
			||||||
 | 
						cmd_option_print
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const char *set_option_status_keys_list[] = {
 | 
				
			||||||
 | 
						"emacs", "vi", NULL
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					const char *set_option_bell_action_list[] = {
 | 
				
			||||||
 | 
						"none", "any", "current", NULL
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					const struct set_option_entry set_option_table[NSETOPTION] = {
 | 
				
			||||||
 | 
						{ "bell-action", SET_OPTION_CHOICE, 0, 0, set_option_bell_action_list },
 | 
				
			||||||
 | 
						{ "buffer-limit", SET_OPTION_NUMBER, 1, INT_MAX, NULL },
 | 
				
			||||||
 | 
						{ "default-command", SET_OPTION_STRING, 0, 0, NULL },
 | 
				
			||||||
 | 
						{ "default-path", SET_OPTION_STRING, 0, 0, NULL },
 | 
				
			||||||
 | 
						{ "display-time", SET_OPTION_NUMBER, 1, INT_MAX, NULL },
 | 
				
			||||||
 | 
						{ "history-limit", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
 | 
				
			||||||
 | 
						{ "lock-after-time", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
 | 
				
			||||||
 | 
						{ "message-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
 | 
				
			||||||
 | 
						{ "message-bg", SET_OPTION_COLOUR, 0, 0, NULL },
 | 
				
			||||||
 | 
						{ "message-fg", SET_OPTION_COLOUR, 0, 0, NULL },
 | 
				
			||||||
 | 
						{ "prefix", SET_OPTION_KEY, 0, 0, NULL },
 | 
				
			||||||
 | 
						{ "repeat-time", SET_OPTION_NUMBER, 0, SHRT_MAX, NULL },
 | 
				
			||||||
 | 
						{ "set-remain-on-exit", SET_OPTION_FLAG, 0, 0, NULL },
 | 
				
			||||||
 | 
						{ "set-titles", SET_OPTION_FLAG, 0, 0, NULL },
 | 
				
			||||||
 | 
						{ "status", SET_OPTION_FLAG, 0, 0, NULL },
 | 
				
			||||||
 | 
						{ "status-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
 | 
				
			||||||
 | 
						{ "status-bg", SET_OPTION_COLOUR, 0, 0, NULL },
 | 
				
			||||||
 | 
						{ "status-fg", SET_OPTION_COLOUR, 0, 0, NULL },
 | 
				
			||||||
 | 
						{ "status-interval", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
 | 
				
			||||||
 | 
						{ "status-keys", SET_OPTION_CHOICE, 0, 0, set_option_status_keys_list },
 | 
				
			||||||
 | 
						{ "status-left", SET_OPTION_STRING, 0, 0, NULL },
 | 
				
			||||||
 | 
						{ "status-left-length", SET_OPTION_NUMBER, 0, SHRT_MAX, NULL },
 | 
				
			||||||
 | 
						{ "status-right", SET_OPTION_STRING, 0, 0, NULL },
 | 
				
			||||||
 | 
						{ "status-right-length", SET_OPTION_NUMBER, 0, SHRT_MAX, NULL },
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_set_option_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_option_data		*data = self->data;
 | 
				
			||||||
 | 
						struct session			*s;
 | 
				
			||||||
 | 
						struct client			*c;
 | 
				
			||||||
 | 
						struct options			*oo;
 | 
				
			||||||
 | 
						const struct set_option_entry   *entry;
 | 
				
			||||||
 | 
						u_int				 i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (data->flags & CMD_GFLAG)
 | 
				
			||||||
 | 
							oo = &global_options;
 | 
				
			||||||
 | 
						else {
 | 
				
			||||||
 | 
							if ((s = cmd_find_session(ctx, data->target)) == NULL)
 | 
				
			||||||
 | 
								return (-1);
 | 
				
			||||||
 | 
							oo = &s->options;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (*data->option == '\0') {
 | 
				
			||||||
 | 
							ctx->error(ctx, "invalid option");
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						entry = NULL;
 | 
				
			||||||
 | 
						for (i = 0; i < NSETOPTION; i++) {
 | 
				
			||||||
 | 
							if (strncmp(set_option_table[i].name,
 | 
				
			||||||
 | 
							    data->option, strlen(data->option)) != 0)
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							if (entry != NULL) {
 | 
				
			||||||
 | 
								ctx->error(ctx, "ambiguous option: %s", data->option);
 | 
				
			||||||
 | 
								return (-1);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							entry = &set_option_table[i];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Bail now if an exact match. */
 | 
				
			||||||
 | 
							if (strcmp(entry->name, data->option) == 0)
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (entry == NULL) {
 | 
				
			||||||
 | 
							ctx->error(ctx, "unknown option: %s", data->option);
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (data->flags & CMD_UFLAG) {
 | 
				
			||||||
 | 
							if (data->flags & CMD_GFLAG) {
 | 
				
			||||||
 | 
								ctx->error(ctx,
 | 
				
			||||||
 | 
								    "can't unset global option: %s", entry->name);
 | 
				
			||||||
 | 
								return (-1);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (data->value != NULL) {
 | 
				
			||||||
 | 
								ctx->error(ctx,
 | 
				
			||||||
 | 
								    "value passed to unset option: %s", entry->name);
 | 
				
			||||||
 | 
								return (-1);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							options_remove(oo, entry->name);
 | 
				
			||||||
 | 
							ctx->info(ctx, "unset option: %s", entry->name);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							switch (entry->type) {
 | 
				
			||||||
 | 
							case SET_OPTION_STRING:
 | 
				
			||||||
 | 
								set_option_string(ctx, oo, entry, data->value);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case SET_OPTION_NUMBER:
 | 
				
			||||||
 | 
								set_option_number(ctx, oo, entry, data->value);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case SET_OPTION_KEY:
 | 
				
			||||||
 | 
								set_option_key(ctx, oo, entry, data->value);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case SET_OPTION_COLOUR:
 | 
				
			||||||
 | 
								set_option_colour(ctx, oo, entry, data->value);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case SET_OPTION_ATTRIBUTES:
 | 
				
			||||||
 | 
								set_option_attributes(ctx, oo, entry, data->value);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case SET_OPTION_FLAG:
 | 
				
			||||||
 | 
								set_option_flag(ctx, oo, entry, data->value);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case SET_OPTION_CHOICE:
 | 
				
			||||||
 | 
								set_option_choice(ctx, oo, entry, data->value);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						recalculate_sizes();
 | 
				
			||||||
 | 
						for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
 | 
				
			||||||
 | 
							c = ARRAY_ITEM(&clients, i);
 | 
				
			||||||
 | 
							if (c != NULL && c->session != NULL)
 | 
				
			||||||
 | 
								server_redraw_client(c);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										169
									
								
								cmd-set-password.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										169
									
								
								cmd-set-password.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,169 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <pwd.h>
 | 
				
			||||||
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Set server password.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_set_password_parse(struct cmd *, int, char **, char **);
 | 
				
			||||||
 | 
					int	cmd_set_password_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					void	cmd_set_password_send(struct cmd *, struct buffer *);
 | 
				
			||||||
 | 
					void	cmd_set_password_recv(struct cmd *, struct buffer *);
 | 
				
			||||||
 | 
					void	cmd_set_password_free(struct cmd *);
 | 
				
			||||||
 | 
					void	cmd_set_password_init(struct cmd *, int);
 | 
				
			||||||
 | 
					size_t	cmd_set_password_print(struct cmd *, char *, size_t);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct cmd_set_password_data {
 | 
				
			||||||
 | 
						char	*password;
 | 
				
			||||||
 | 
						int	 flag_encrypted;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_set_password_entry = {
 | 
				
			||||||
 | 
						"set-password", "pass",
 | 
				
			||||||
 | 
						"[-c] password",
 | 
				
			||||||
 | 
						0,
 | 
				
			||||||
 | 
						cmd_set_password_init,
 | 
				
			||||||
 | 
						cmd_set_password_parse,
 | 
				
			||||||
 | 
						cmd_set_password_exec,
 | 
				
			||||||
 | 
						cmd_set_password_send,
 | 
				
			||||||
 | 
						cmd_set_password_recv,
 | 
				
			||||||
 | 
						cmd_set_password_free,
 | 
				
			||||||
 | 
						cmd_set_password_print
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_set_password_init(struct cmd *self, unused int arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_set_password_data	 *data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						self->data = data = xmalloc(sizeof *data);
 | 
				
			||||||
 | 
						data->password = NULL;
 | 
				
			||||||
 | 
						data->flag_encrypted = 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_set_password_parse(struct cmd *self, int argc, char **argv, char **cause)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_set_password_data	*data;
 | 
				
			||||||
 | 
						int				 opt;
 | 
				
			||||||
 | 
						char				*out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						self->entry->init(self, 0);
 | 
				
			||||||
 | 
						data = self->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while ((opt = getopt(argc, argv, "c")) != -1) {
 | 
				
			||||||
 | 
							switch (opt) {
 | 
				
			||||||
 | 
							case 'c':
 | 
				
			||||||
 | 
								data->flag_encrypted = 1;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								goto usage;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						argc -= optind;
 | 
				
			||||||
 | 
						argv += optind;
 | 
				
			||||||
 | 
						if (argc != 1)
 | 
				
			||||||
 | 
							goto usage;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!data->flag_encrypted) {
 | 
				
			||||||
 | 
							if ((out = crypt(argv[0], "$1")) != NULL)
 | 
				
			||||||
 | 
								data->password = xstrdup(out);
 | 
				
			||||||
 | 
						} else
 | 
				
			||||||
 | 
							data->password = xstrdup(argv[0]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					usage:
 | 
				
			||||||
 | 
						xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						self->entry->free(self);
 | 
				
			||||||
 | 
						return (-1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_set_password_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_set_password_data	*data = self->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (data->password == NULL) {
 | 
				
			||||||
 | 
							ctx->error(ctx, "failed to encrypt password");
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (server_password != NULL)
 | 
				
			||||||
 | 
							xfree(server_password);
 | 
				
			||||||
 | 
						if (*data->password == '\0')
 | 
				
			||||||
 | 
							server_password = NULL;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							server_password = xstrdup(data->password);
 | 
				
			||||||
 | 
						log_debug("pw now %s", server_password);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 	return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_set_password_send(struct cmd *self, struct buffer *b)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_set_password_data	*data = self->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						buffer_write(b, data, sizeof *data);
 | 
				
			||||||
 | 
						cmd_send_string(b, data->password);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_set_password_recv(struct cmd *self, struct buffer *b)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_set_password_data	*data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						self->data = data = xmalloc(sizeof *data);
 | 
				
			||||||
 | 
						buffer_read(b, data, sizeof *data);
 | 
				
			||||||
 | 
						data->password = cmd_recv_string(b);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_set_password_free(struct cmd *self)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_set_password_data	*data = self->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (data->password != NULL)
 | 
				
			||||||
 | 
							xfree(data->password);
 | 
				
			||||||
 | 
						xfree(data);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					size_t
 | 
				
			||||||
 | 
					cmd_set_password_print(struct cmd *self, char *buf, size_t len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_set_password_data	*data = self->data;
 | 
				
			||||||
 | 
						size_t				 off = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						off += xsnprintf(buf, len, "%s", self->entry->name);
 | 
				
			||||||
 | 
						if (data == NULL)
 | 
				
			||||||
 | 
							return (off);
 | 
				
			||||||
 | 
						if (off < len && data->flag_encrypted)
 | 
				
			||||||
 | 
							off += xsnprintf(buf + off, len - off, " -c");
 | 
				
			||||||
 | 
						if (off < len && data->password != NULL)
 | 
				
			||||||
 | 
							off += xsnprintf(buf + off, len - off, " password");
 | 
				
			||||||
 | 
						return (off);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										170
									
								
								cmd-set-window-option.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										170
									
								
								cmd-set-window-option.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,170 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Set a window option.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_set_window_option_parse(struct cmd *, int, char **, char **);
 | 
				
			||||||
 | 
					int	cmd_set_window_option_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					void	cmd_set_window_option_send(struct cmd *, struct buffer *);
 | 
				
			||||||
 | 
					void	cmd_set_window_option_recv(struct cmd *, struct buffer *);
 | 
				
			||||||
 | 
					void	cmd_set_window_option_free(struct cmd *);
 | 
				
			||||||
 | 
					size_t	cmd_set_window_option_print(struct cmd *, char *, size_t);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_set_window_option_entry = {
 | 
				
			||||||
 | 
						"set-window-option", "setw",
 | 
				
			||||||
 | 
						CMD_OPTION_WINDOW_USAGE,
 | 
				
			||||||
 | 
						CMD_GFLAG|CMD_UFLAG,
 | 
				
			||||||
 | 
						NULL,
 | 
				
			||||||
 | 
						cmd_option_parse,
 | 
				
			||||||
 | 
						cmd_set_window_option_exec,
 | 
				
			||||||
 | 
						cmd_option_send,
 | 
				
			||||||
 | 
						cmd_option_recv,
 | 
				
			||||||
 | 
						cmd_option_free,
 | 
				
			||||||
 | 
						cmd_option_print
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const char *set_option_mode_keys_list[] = {
 | 
				
			||||||
 | 
						"emacs", "vi", NULL
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					const char *set_option_clock_mode_style_list[] = {
 | 
				
			||||||
 | 
						"12", "24", NULL
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					const struct set_option_entry set_window_option_table[NSETWINDOWOPTION] = {
 | 
				
			||||||
 | 
						{ "aggressive-resize", SET_OPTION_FLAG, 0, 0, NULL },
 | 
				
			||||||
 | 
						{ "automatic-rename", SET_OPTION_FLAG, 0, 0, NULL },
 | 
				
			||||||
 | 
						{ "clock-mode-colour", SET_OPTION_COLOUR, 0, 0, NULL },
 | 
				
			||||||
 | 
						{ "clock-mode-style",
 | 
				
			||||||
 | 
						  SET_OPTION_CHOICE, 0, 0, set_option_clock_mode_style_list },
 | 
				
			||||||
 | 
						{ "force-height", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
 | 
				
			||||||
 | 
						{ "force-width", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
 | 
				
			||||||
 | 
						{ "main-pane-width", SET_OPTION_NUMBER, 1, INT_MAX, NULL },
 | 
				
			||||||
 | 
						{ "mode-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
 | 
				
			||||||
 | 
						{ "mode-bg", SET_OPTION_COLOUR, 0, 0, NULL },
 | 
				
			||||||
 | 
						{ "mode-fg", SET_OPTION_COLOUR, 0, 0, NULL },
 | 
				
			||||||
 | 
						{ "mode-keys", SET_OPTION_CHOICE, 0, 0, set_option_mode_keys_list },
 | 
				
			||||||
 | 
						{ "monitor-activity", SET_OPTION_FLAG, 0, 0, NULL },
 | 
				
			||||||
 | 
						{ "monitor-content", SET_OPTION_STRING, 0, 0, NULL },
 | 
				
			||||||
 | 
						{ "remain-on-exit", SET_OPTION_FLAG, 0, 0, NULL },
 | 
				
			||||||
 | 
						{ "utf8", SET_OPTION_FLAG, 0, 0, NULL },
 | 
				
			||||||
 | 
						{ "window-status-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
 | 
				
			||||||
 | 
						{ "window-status-bg", SET_OPTION_COLOUR, 0, 0, NULL },
 | 
				
			||||||
 | 
						{ "window-status-fg", SET_OPTION_COLOUR, 0, 0, NULL },
 | 
				
			||||||
 | 
						{ "xterm-keys", SET_OPTION_FLAG, 0, 0, NULL },
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_set_window_option_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_option_data		*data = self->data;
 | 
				
			||||||
 | 
						struct winlink			*wl;
 | 
				
			||||||
 | 
						struct client			*c;
 | 
				
			||||||
 | 
						struct options			*oo;
 | 
				
			||||||
 | 
						const struct set_option_entry   *entry;
 | 
				
			||||||
 | 
						u_int				 i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (data->flags & CMD_GFLAG)
 | 
				
			||||||
 | 
							oo = &global_window_options;
 | 
				
			||||||
 | 
						else {
 | 
				
			||||||
 | 
							if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
 | 
				
			||||||
 | 
								return (-1);
 | 
				
			||||||
 | 
							oo = &wl->window->options;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (*data->option == '\0') {
 | 
				
			||||||
 | 
							ctx->error(ctx, "invalid option");
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						entry = NULL;
 | 
				
			||||||
 | 
						for (i = 0; i < NSETWINDOWOPTION; i++) {
 | 
				
			||||||
 | 
							if (strncmp(set_window_option_table[i].name,
 | 
				
			||||||
 | 
							    data->option, strlen(data->option)) != 0)
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							if (entry != NULL) {
 | 
				
			||||||
 | 
								ctx->error(ctx, "ambiguous option: %s", data->option);
 | 
				
			||||||
 | 
								return (-1);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							entry = &set_window_option_table[i];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Bail now if an exact match. */
 | 
				
			||||||
 | 
							if (strcmp(entry->name, data->option) == 0)
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (entry == NULL) {
 | 
				
			||||||
 | 
							ctx->error(ctx, "unknown option: %s", data->option);
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (data->flags & CMD_UFLAG) {
 | 
				
			||||||
 | 
							if (data->flags & CMD_GFLAG) {
 | 
				
			||||||
 | 
								ctx->error(ctx,
 | 
				
			||||||
 | 
								    "can't unset global option: %s", entry->name);
 | 
				
			||||||
 | 
								return (-1);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (data->value != NULL) {
 | 
				
			||||||
 | 
								ctx->error(ctx,
 | 
				
			||||||
 | 
								    "value passed to unset option: %s", entry->name);
 | 
				
			||||||
 | 
								return (-1);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							options_remove(oo, entry->name);
 | 
				
			||||||
 | 
							ctx->info(ctx, "unset option: %s", entry->name);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							switch (entry->type) {
 | 
				
			||||||
 | 
							case SET_OPTION_STRING:
 | 
				
			||||||
 | 
								set_option_string(ctx, oo, entry, data->value);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case SET_OPTION_NUMBER:
 | 
				
			||||||
 | 
								set_option_number(ctx, oo, entry, data->value);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case SET_OPTION_KEY:
 | 
				
			||||||
 | 
								set_option_key(ctx, oo, entry, data->value);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case SET_OPTION_COLOUR:
 | 
				
			||||||
 | 
								set_option_colour(ctx, oo, entry, data->value);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case SET_OPTION_ATTRIBUTES:
 | 
				
			||||||
 | 
								set_option_attributes(ctx, oo, entry, data->value);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case SET_OPTION_FLAG:
 | 
				
			||||||
 | 
								set_option_flag(ctx, oo, entry, data->value);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case SET_OPTION_CHOICE:
 | 
				
			||||||
 | 
								set_option_choice(ctx, oo, entry, data->value);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						recalculate_sizes();
 | 
				
			||||||
 | 
						for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
 | 
				
			||||||
 | 
							c = ARRAY_ITEM(&clients, i);
 | 
				
			||||||
 | 
							if (c != NULL && c->session != NULL)
 | 
				
			||||||
 | 
								server_redraw_client(c);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										89
									
								
								cmd-show-buffer.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								cmd-show-buffer.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,89 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Show a session paste buffer.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_show_buffer_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_show_buffer_entry = {
 | 
				
			||||||
 | 
						"show-buffer", "showb",
 | 
				
			||||||
 | 
						CMD_BUFFER_SESSION_USAGE,
 | 
				
			||||||
 | 
						0,
 | 
				
			||||||
 | 
						cmd_buffer_init,
 | 
				
			||||||
 | 
						cmd_buffer_parse,
 | 
				
			||||||
 | 
						cmd_show_buffer_exec,
 | 
				
			||||||
 | 
						cmd_buffer_send,
 | 
				
			||||||
 | 
						cmd_buffer_recv,
 | 
				
			||||||
 | 
						cmd_buffer_free,
 | 
				
			||||||
 | 
						cmd_buffer_print
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_show_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_buffer_data	*data = self->data;
 | 
				
			||||||
 | 
						struct session		*s;
 | 
				
			||||||
 | 
						struct paste_buffer	*pb;
 | 
				
			||||||
 | 
						u_int			 size;
 | 
				
			||||||
 | 
						char			*buf, *ptr;
 | 
				
			||||||
 | 
						size_t			 len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((s = cmd_find_session(ctx, data->target)) == NULL)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (data->buffer == -1) {
 | 
				
			||||||
 | 
							if ((pb = paste_get_top(&s->buffers)) == NULL) {
 | 
				
			||||||
 | 
								ctx->error(ctx, "no buffers");
 | 
				
			||||||
 | 
								return (-1);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else if ((pb = paste_get_index(&s->buffers, data->buffer)) == NULL) {
 | 
				
			||||||
 | 
							ctx->error(ctx, "no buffer %d", data->buffer);
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (pb != NULL) {
 | 
				
			||||||
 | 
							size = s->sx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							buf = xmalloc(size + 1);
 | 
				
			||||||
 | 
							len = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							ptr = pb->data;
 | 
				
			||||||
 | 
							do {
 | 
				
			||||||
 | 
								buf[len++] = *ptr++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (len == size) {
 | 
				
			||||||
 | 
									buf[len] = '\0';
 | 
				
			||||||
 | 
									ctx->print(ctx, buf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									len = 0;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							} while (*ptr != '\0');
 | 
				
			||||||
 | 
							buf[len] = '\0';
 | 
				
			||||||
 | 
							ctx->print(ctx, buf);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										110
									
								
								cmd-show-options.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								cmd-show-options.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,110 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Show options.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_show_options_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_show_options_entry = {
 | 
				
			||||||
 | 
						"show-options", "show",
 | 
				
			||||||
 | 
						"[-g] " CMD_TARGET_SESSION_USAGE,
 | 
				
			||||||
 | 
						CMD_GFLAG,
 | 
				
			||||||
 | 
						cmd_target_init,
 | 
				
			||||||
 | 
						cmd_target_parse,
 | 
				
			||||||
 | 
						cmd_show_options_exec,
 | 
				
			||||||
 | 
						cmd_target_send,
 | 
				
			||||||
 | 
						cmd_target_recv,
 | 
				
			||||||
 | 
						cmd_target_free,
 | 
				
			||||||
 | 
						cmd_target_print
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_show_options_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_target_data		*data = self->data;
 | 
				
			||||||
 | 
						struct session			*s;
 | 
				
			||||||
 | 
						struct options			*oo;
 | 
				
			||||||
 | 
						const struct set_option_entry   *entry;
 | 
				
			||||||
 | 
						u_int				 i;
 | 
				
			||||||
 | 
						char				*vs;
 | 
				
			||||||
 | 
						long long			 vn;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (data->flags & CMD_GFLAG)
 | 
				
			||||||
 | 
							oo = &global_options;
 | 
				
			||||||
 | 
						else {
 | 
				
			||||||
 | 
							if ((s = cmd_find_session(ctx, data->target)) == NULL)
 | 
				
			||||||
 | 
								return (-1);
 | 
				
			||||||
 | 
							oo = &s->options;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < NSETOPTION; i++) {
 | 
				
			||||||
 | 
							entry = &set_option_table[i];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (options_find1(oo, entry->name) == NULL)
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							switch (entry->type) {
 | 
				
			||||||
 | 
							case SET_OPTION_STRING:
 | 
				
			||||||
 | 
								vs = options_get_string(oo, entry->name);
 | 
				
			||||||
 | 
								ctx->print(ctx, "%s \"%s\"", entry->name, vs);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case SET_OPTION_NUMBER:
 | 
				
			||||||
 | 
								vn = options_get_number(oo, entry->name);
 | 
				
			||||||
 | 
								ctx->print(ctx, "%s %lld", entry->name, vn);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case SET_OPTION_KEY:
 | 
				
			||||||
 | 
								vn = options_get_number(oo, entry->name);
 | 
				
			||||||
 | 
					 			ctx->print(ctx, "%s %s",
 | 
				
			||||||
 | 
								    entry->name, key_string_lookup_key(vn));
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case SET_OPTION_COLOUR:
 | 
				
			||||||
 | 
								vn = options_get_number(oo, entry->name);
 | 
				
			||||||
 | 
					 			ctx->print(ctx, "%s %s",
 | 
				
			||||||
 | 
								    entry->name, colour_tostring(vn));
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case SET_OPTION_ATTRIBUTES:
 | 
				
			||||||
 | 
								vn = options_get_number(oo, entry->name);
 | 
				
			||||||
 | 
					 			ctx->print(ctx, "%s %s",
 | 
				
			||||||
 | 
								    entry->name, attributes_tostring(vn));
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case SET_OPTION_FLAG:
 | 
				
			||||||
 | 
								vn = options_get_number(oo, entry->name);
 | 
				
			||||||
 | 
								if (vn)
 | 
				
			||||||
 | 
									ctx->print(ctx, "%s on", entry->name);
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
									ctx->print(ctx, "%s off", entry->name);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case SET_OPTION_CHOICE:
 | 
				
			||||||
 | 
								vn = options_get_number(oo, entry->name);
 | 
				
			||||||
 | 
								ctx->print(ctx, "%s %s",
 | 
				
			||||||
 | 
								    entry->name, entry->choices[vn]);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										110
									
								
								cmd-show-window-options.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								cmd-show-window-options.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,110 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Show window options.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_show_window_options_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_show_window_options_entry = {
 | 
				
			||||||
 | 
						"show-window-options", "showw",
 | 
				
			||||||
 | 
						"[-g] " CMD_TARGET_WINDOW_USAGE,
 | 
				
			||||||
 | 
						CMD_GFLAG,
 | 
				
			||||||
 | 
						cmd_target_init,
 | 
				
			||||||
 | 
						cmd_target_parse,
 | 
				
			||||||
 | 
						cmd_show_window_options_exec,
 | 
				
			||||||
 | 
						cmd_target_send,
 | 
				
			||||||
 | 
						cmd_target_recv,
 | 
				
			||||||
 | 
						cmd_target_free,
 | 
				
			||||||
 | 
						cmd_target_print
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_show_window_options_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_target_data		*data = self->data;
 | 
				
			||||||
 | 
						struct winlink			*wl;
 | 
				
			||||||
 | 
						struct options			*oo;
 | 
				
			||||||
 | 
						const struct set_option_entry	*entry;
 | 
				
			||||||
 | 
						u_int				 i;
 | 
				
			||||||
 | 
						char				*vs;
 | 
				
			||||||
 | 
						long long			 vn;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (data->flags & CMD_GFLAG)
 | 
				
			||||||
 | 
							oo = &global_window_options;
 | 
				
			||||||
 | 
						else {
 | 
				
			||||||
 | 
							if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
 | 
				
			||||||
 | 
								return (-1);
 | 
				
			||||||
 | 
							oo = &wl->window->options;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < NSETWINDOWOPTION; i++) {
 | 
				
			||||||
 | 
							entry = &set_window_option_table[i];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (options_find1(oo, entry->name) == NULL)
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							switch (entry->type) {
 | 
				
			||||||
 | 
							case SET_OPTION_STRING:
 | 
				
			||||||
 | 
								vs = options_get_string(oo, entry->name);
 | 
				
			||||||
 | 
								ctx->print(ctx, "%s \"%s\"", entry->name, vs);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case SET_OPTION_NUMBER:
 | 
				
			||||||
 | 
								vn = options_get_number(oo, entry->name);
 | 
				
			||||||
 | 
								ctx->print(ctx, "%s %lld", entry->name, vn);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case SET_OPTION_KEY:
 | 
				
			||||||
 | 
								vn = options_get_number(oo, entry->name);
 | 
				
			||||||
 | 
					 			ctx->print(ctx, "%s %s",
 | 
				
			||||||
 | 
								    entry->name, key_string_lookup_key(vn));
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case SET_OPTION_COLOUR:
 | 
				
			||||||
 | 
								vn = options_get_number(oo, entry->name);
 | 
				
			||||||
 | 
					 			ctx->print(ctx, "%s %s",
 | 
				
			||||||
 | 
								    entry->name, colour_tostring(vn));
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case SET_OPTION_ATTRIBUTES:
 | 
				
			||||||
 | 
								vn = options_get_number(oo, entry->name);
 | 
				
			||||||
 | 
					 			ctx->print(ctx, "%s %s",
 | 
				
			||||||
 | 
								    entry->name, attributes_tostring(vn));
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case SET_OPTION_FLAG:
 | 
				
			||||||
 | 
								vn = options_get_number(oo, entry->name);
 | 
				
			||||||
 | 
								if (vn)
 | 
				
			||||||
 | 
									ctx->print(ctx, "%s on", entry->name);
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
									ctx->print(ctx, "%s off", entry->name);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case SET_OPTION_CHOICE:
 | 
				
			||||||
 | 
								vn = options_get_number(oo, entry->name);
 | 
				
			||||||
 | 
								ctx->print(ctx, "%s %s",
 | 
				
			||||||
 | 
								    entry->name, entry->choices[vn]);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										147
									
								
								cmd-source-file.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										147
									
								
								cmd-source-file.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,147 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2008 Tiago Cunha <me@tiagocunha.org>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Sources a configuration file.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_source_file_parse(struct cmd *, int, char **, char **);
 | 
				
			||||||
 | 
					int	cmd_source_file_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					void	cmd_source_file_send(struct cmd *, struct buffer *);
 | 
				
			||||||
 | 
					void	cmd_source_file_recv(struct cmd *, struct buffer *);
 | 
				
			||||||
 | 
					void	cmd_source_file_free(struct cmd *);
 | 
				
			||||||
 | 
					void	cmd_source_file_init(struct cmd *, int);
 | 
				
			||||||
 | 
					size_t	cmd_source_file_print(struct cmd *, char *, size_t);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct cmd_source_file_data {
 | 
				
			||||||
 | 
						char *path;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_source_file_entry = {
 | 
				
			||||||
 | 
						"source-file", "source",
 | 
				
			||||||
 | 
						"path",
 | 
				
			||||||
 | 
						0,
 | 
				
			||||||
 | 
						cmd_source_file_init,
 | 
				
			||||||
 | 
						cmd_source_file_parse,
 | 
				
			||||||
 | 
						cmd_source_file_exec,
 | 
				
			||||||
 | 
						cmd_source_file_send,
 | 
				
			||||||
 | 
						cmd_source_file_recv,
 | 
				
			||||||
 | 
						cmd_source_file_free,
 | 
				
			||||||
 | 
						cmd_source_file_print
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_source_file_init(struct cmd *self, unused int arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_source_file_data	*data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						self->data = data = xmalloc(sizeof *data);
 | 
				
			||||||
 | 
						data->path = NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_source_file_parse(struct cmd *self, int argc, char **argv, char **cause)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_source_file_data	*data;
 | 
				
			||||||
 | 
						int				 opt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						self->entry->init(self, 0);
 | 
				
			||||||
 | 
						data = self->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while ((opt = getopt(argc, argv, "")) != -1) {
 | 
				
			||||||
 | 
							switch (opt) {
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								goto usage;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						argc -= optind;
 | 
				
			||||||
 | 
						argv += optind;
 | 
				
			||||||
 | 
						if (argc != 1)
 | 
				
			||||||
 | 
							goto usage;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						data->path = xstrdup(argv[0]);
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					usage:
 | 
				
			||||||
 | 
						xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						self->entry->free(self);
 | 
				
			||||||
 | 
						return (-1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_source_file_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_source_file_data	*data = self->data;
 | 
				
			||||||
 | 
						char				*cause;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (load_cfg(data->path, &cause) != 0) {
 | 
				
			||||||
 | 
							ctx->error(ctx, "%s", cause);
 | 
				
			||||||
 | 
							xfree(cause);
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_source_file_send(struct cmd *self, struct buffer *b)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_source_file_data	*data = self->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						buffer_write(b, data, sizeof *data);
 | 
				
			||||||
 | 
						cmd_send_string(b, data->path);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_source_file_recv(struct cmd *self, struct buffer *b)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_source_file_data	*data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						self->data = data = xmalloc(sizeof *data);
 | 
				
			||||||
 | 
						buffer_read(b, data, sizeof *data);
 | 
				
			||||||
 | 
						data->path = cmd_recv_string(b);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_source_file_free(struct cmd *self)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_source_file_data	*data = self->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (data->path != NULL)
 | 
				
			||||||
 | 
							xfree(data->path);
 | 
				
			||||||
 | 
						xfree(data);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					size_t
 | 
				
			||||||
 | 
					cmd_source_file_print(struct cmd *self, char *buf, size_t len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_source_file_data	*data = self->data;
 | 
				
			||||||
 | 
						size_t				off = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						off += xsnprintf(buf, len, "%s", self->entry->name);
 | 
				
			||||||
 | 
						if (data == NULL)
 | 
				
			||||||
 | 
							return (off);
 | 
				
			||||||
 | 
						if (off < len && data->path != NULL)
 | 
				
			||||||
 | 
							off += cmd_prarg(buf + off, len - off, " ", data->path);
 | 
				
			||||||
 | 
						return (off);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										235
									
								
								cmd-split-window.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										235
									
								
								cmd-split-window.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,235 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Split a window (add a new pane).
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_split_window_parse(struct cmd *, int, char **, char **);
 | 
				
			||||||
 | 
					int	cmd_split_window_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					void	cmd_split_window_send(struct cmd *, struct buffer *);
 | 
				
			||||||
 | 
					void	cmd_split_window_recv(struct cmd *, struct buffer *);
 | 
				
			||||||
 | 
					void	cmd_split_window_free(struct cmd *);
 | 
				
			||||||
 | 
					void	cmd_split_window_init(struct cmd *, int);
 | 
				
			||||||
 | 
					size_t	cmd_split_window_print(struct cmd *, char *, size_t);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct cmd_split_window_data {
 | 
				
			||||||
 | 
						char	*target;
 | 
				
			||||||
 | 
						char	*cmd;
 | 
				
			||||||
 | 
						int	 flag_detached;
 | 
				
			||||||
 | 
						int	 percentage;
 | 
				
			||||||
 | 
						int	 lines;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_split_window_entry = {
 | 
				
			||||||
 | 
						"split-window", "splitw",
 | 
				
			||||||
 | 
						"[-d] [-p percentage|-l lines] [-t target-window] [command]",
 | 
				
			||||||
 | 
						0,
 | 
				
			||||||
 | 
						cmd_split_window_init,
 | 
				
			||||||
 | 
						cmd_split_window_parse,
 | 
				
			||||||
 | 
						cmd_split_window_exec,
 | 
				
			||||||
 | 
						cmd_split_window_send,
 | 
				
			||||||
 | 
						cmd_split_window_recv,
 | 
				
			||||||
 | 
						cmd_split_window_free,
 | 
				
			||||||
 | 
						cmd_split_window_print
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_split_window_init(struct cmd *self, unused int arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_split_window_data	 *data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						self->data = data = xmalloc(sizeof *data);
 | 
				
			||||||
 | 
						data->target = NULL;
 | 
				
			||||||
 | 
						data->cmd = NULL;
 | 
				
			||||||
 | 
						data->flag_detached = 0;
 | 
				
			||||||
 | 
						data->percentage = -1;
 | 
				
			||||||
 | 
						data->lines = -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_split_window_parse(struct cmd *self, int argc, char **argv, char **cause)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_split_window_data	*data;
 | 
				
			||||||
 | 
						int				 opt, n;
 | 
				
			||||||
 | 
						const char			*errstr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						self->entry->init(self, 0);
 | 
				
			||||||
 | 
						data = self->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while ((opt = getopt(argc, argv, "dl:p:t:")) != -1) {
 | 
				
			||||||
 | 
							switch (opt) {
 | 
				
			||||||
 | 
							case 'd':
 | 
				
			||||||
 | 
								data->flag_detached = 1;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case 't':
 | 
				
			||||||
 | 
								if (data->target == NULL)
 | 
				
			||||||
 | 
									data->target = xstrdup(optarg);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case 'l':
 | 
				
			||||||
 | 
								if (data->percentage == -1 && data->lines == -1) {
 | 
				
			||||||
 | 
									n = strtonum(optarg, 1, INT_MAX, &errstr);
 | 
				
			||||||
 | 
									if (errstr != NULL) {
 | 
				
			||||||
 | 
										xasprintf(cause, "lines %s", errstr);
 | 
				
			||||||
 | 
										goto error;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									data->lines = n;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case 'p':
 | 
				
			||||||
 | 
								if (data->lines == -1 && data->percentage == -1) {
 | 
				
			||||||
 | 
									n = strtonum(optarg, 1, 100, &errstr);
 | 
				
			||||||
 | 
									if (errstr != NULL) {
 | 
				
			||||||
 | 
										xasprintf(
 | 
				
			||||||
 | 
										    cause, "percentage %s", errstr);
 | 
				
			||||||
 | 
										goto error;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									data->percentage = n;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								goto usage;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						argc -= optind;
 | 
				
			||||||
 | 
						argv += optind;
 | 
				
			||||||
 | 
						if (argc != 0 && argc != 1)
 | 
				
			||||||
 | 
							goto usage;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (argc == 1)
 | 
				
			||||||
 | 
							data->cmd = xstrdup(argv[0]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					usage:
 | 
				
			||||||
 | 
						xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					error:
 | 
				
			||||||
 | 
						self->entry->free(self);
 | 
				
			||||||
 | 
						return (-1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_split_window_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_split_window_data	*data = self->data;
 | 
				
			||||||
 | 
						struct session			*s;
 | 
				
			||||||
 | 
						struct winlink			*wl;
 | 
				
			||||||
 | 
						struct window			*w;
 | 
				
			||||||
 | 
						struct window_pane		*wp;
 | 
				
			||||||
 | 
						const char		       **env;
 | 
				
			||||||
 | 
						char		 		*cmd, *cwd, *cause;
 | 
				
			||||||
 | 
						u_int				 hlimit, lines;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						w = wl->window;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						env = server_fill_environ(s);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cmd = data->cmd;
 | 
				
			||||||
 | 
						if (cmd == NULL)
 | 
				
			||||||
 | 
							cmd = options_get_string(&s->options, "default-command");
 | 
				
			||||||
 | 
						if (ctx->cmdclient == NULL || ctx->cmdclient->cwd == NULL)
 | 
				
			||||||
 | 
							cwd = options_get_string(&global_options, "default-path");
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							cwd = ctx->cmdclient->cwd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						lines = -1;
 | 
				
			||||||
 | 
						if (data->lines != -1)
 | 
				
			||||||
 | 
							lines = data->lines;
 | 
				
			||||||
 | 
						else if (data->percentage != -1)
 | 
				
			||||||
 | 
							lines = (w->active->sy * data->percentage) / 100;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						hlimit = options_get_number(&s->options, "history-limit");
 | 
				
			||||||
 | 
						wp = window_add_pane(w, lines, cmd, cwd, env, hlimit, &cause);
 | 
				
			||||||
 | 
						if (wp == NULL) {
 | 
				
			||||||
 | 
							ctx->error(ctx, "create pane failed: %s", cause);
 | 
				
			||||||
 | 
							xfree(cause);
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						server_redraw_window(w);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!data->flag_detached) {
 | 
				
			||||||
 | 
							window_set_active_pane(w, wp);
 | 
				
			||||||
 | 
							session_select(s, wl->idx);
 | 
				
			||||||
 | 
							server_redraw_session(s);
 | 
				
			||||||
 | 
						} else
 | 
				
			||||||
 | 
							server_status_session(s);
 | 
				
			||||||
 | 
						layout_refresh(w, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_split_window_send(struct cmd *self, struct buffer *b)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_split_window_data	*data = self->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						buffer_write(b, data, sizeof *data);
 | 
				
			||||||
 | 
						cmd_send_string(b, data->target);
 | 
				
			||||||
 | 
						cmd_send_string(b, data->cmd);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_split_window_recv(struct cmd *self, struct buffer *b)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_split_window_data	*data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						self->data = data = xmalloc(sizeof *data);
 | 
				
			||||||
 | 
						buffer_read(b, data, sizeof *data);
 | 
				
			||||||
 | 
						data->target = cmd_recv_string(b);
 | 
				
			||||||
 | 
						data->cmd = cmd_recv_string(b);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_split_window_free(struct cmd *self)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_split_window_data	*data = self->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (data->target != NULL)
 | 
				
			||||||
 | 
							xfree(data->target);
 | 
				
			||||||
 | 
						if (data->cmd != NULL)
 | 
				
			||||||
 | 
							xfree(data->cmd);
 | 
				
			||||||
 | 
						xfree(data);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					size_t
 | 
				
			||||||
 | 
					cmd_split_window_print(struct cmd *self, char *buf, size_t len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_split_window_data	*data = self->data;
 | 
				
			||||||
 | 
						size_t				 off = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						off += xsnprintf(buf, len, "%s", self->entry->name);
 | 
				
			||||||
 | 
						if (data == NULL)
 | 
				
			||||||
 | 
							return (off);
 | 
				
			||||||
 | 
						if (off < len && data->flag_detached)
 | 
				
			||||||
 | 
							off += xsnprintf(buf + off, len - off, " -d");
 | 
				
			||||||
 | 
						if (off < len && data->target != NULL)
 | 
				
			||||||
 | 
							off += cmd_prarg(buf + off, len - off, " -t ", data->target);
 | 
				
			||||||
 | 
						if (off < len && data->cmd != NULL)
 | 
				
			||||||
 | 
							off += cmd_prarg(buf + off, len - off, " ", data->cmd);
 | 
				
			||||||
 | 
						return (off);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										46
									
								
								cmd-start-server.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								cmd-start-server.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Start the server and do nothing else.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_start_server_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_start_server_entry = {
 | 
				
			||||||
 | 
						"start-server", "start",
 | 
				
			||||||
 | 
						"",
 | 
				
			||||||
 | 
						CMD_STARTSERVER,
 | 
				
			||||||
 | 
						NULL,
 | 
				
			||||||
 | 
						NULL,
 | 
				
			||||||
 | 
						cmd_start_server_exec,
 | 
				
			||||||
 | 
						NULL,
 | 
				
			||||||
 | 
						NULL,
 | 
				
			||||||
 | 
						NULL,
 | 
				
			||||||
 | 
						NULL
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_start_server_exec(unused struct cmd *self, unused struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										309
									
								
								cmd-string.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										309
									
								
								cmd-string.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,309 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <errno.h>
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Parse a command from a string.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_string_getc(const char *, size_t *);
 | 
				
			||||||
 | 
					void	cmd_string_ungetc(const char *, size_t *);
 | 
				
			||||||
 | 
					char   *cmd_string_string(const char *, size_t *, char, int);
 | 
				
			||||||
 | 
					char   *cmd_string_variable(const char *, size_t *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_string_getc(const char *s, size_t *p)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (s[*p] == '\0')
 | 
				
			||||||
 | 
							return (EOF);
 | 
				
			||||||
 | 
						return (s[(*p)++]);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_string_ungetc(unused const char *s, size_t *p)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						(*p)--;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Parse command string. Returns -1 on error. If returning -1, cause is error
 | 
				
			||||||
 | 
					 * string, or NULL for empty command.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_string_parse(const char *s, struct cmd_list **cmdlist, char **cause)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						size_t		p;
 | 
				
			||||||
 | 
						int		ch, argc, rval, have_arg;
 | 
				
			||||||
 | 
						char	      **argv, *buf, *t, *u;
 | 
				
			||||||
 | 
						size_t		len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((t = strchr(s, ' ')) == NULL && (t = strchr(s, '\t')) == NULL)
 | 
				
			||||||
 | 
							t = strchr(s, '\0');
 | 
				
			||||||
 | 
						if ((u = strchr(s, '=')) != NULL && u < t) {
 | 
				
			||||||
 | 
							if (putenv((char *) s) != 0) {
 | 
				
			||||||
 | 
								xasprintf(cause, "assignment failed: %s", s);
 | 
				
			||||||
 | 
								return (-1);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							*cmdlist = NULL;
 | 
				
			||||||
 | 
							return (0);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						argv = NULL;
 | 
				
			||||||
 | 
						argc = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						buf = NULL;
 | 
				
			||||||
 | 
						len = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						have_arg = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						*cause = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						*cmdlist = NULL;
 | 
				
			||||||
 | 
						rval = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						p = 0;
 | 
				
			||||||
 | 
						for (;;) {
 | 
				
			||||||
 | 
							ch = cmd_string_getc(s, &p);
 | 
				
			||||||
 | 
							switch (ch) {
 | 
				
			||||||
 | 
							case '\'':
 | 
				
			||||||
 | 
								if ((t = cmd_string_string(s, &p, '\'', 0)) == NULL)
 | 
				
			||||||
 | 
									goto error;
 | 
				
			||||||
 | 
								buf = xrealloc(buf, 1, len + strlen(t) + 1);
 | 
				
			||||||
 | 
								strlcpy(buf + len, t, strlen(t) + 1);
 | 
				
			||||||
 | 
								len += strlen(t);
 | 
				
			||||||
 | 
								xfree(t);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								have_arg = 1;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case '"':
 | 
				
			||||||
 | 
								if ((t = cmd_string_string(s, &p, '"', 1)) == NULL)
 | 
				
			||||||
 | 
									goto error;
 | 
				
			||||||
 | 
								buf = xrealloc(buf, 1, len + strlen(t) + 1);
 | 
				
			||||||
 | 
								strlcpy(buf + len, t, strlen(t) + 1);
 | 
				
			||||||
 | 
								len += strlen(t);
 | 
				
			||||||
 | 
								xfree(t);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								have_arg = 1;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case '$':
 | 
				
			||||||
 | 
								if ((t = cmd_string_variable(s, &p)) == NULL)
 | 
				
			||||||
 | 
									goto error;
 | 
				
			||||||
 | 
								buf = xrealloc(buf, 1, len + strlen(t) + 1);
 | 
				
			||||||
 | 
								strlcpy(buf + len, t, strlen(t) + 1);
 | 
				
			||||||
 | 
								len += strlen(t);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								have_arg = 1;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case '#':
 | 
				
			||||||
 | 
								/* Comment: discard rest of line. */
 | 
				
			||||||
 | 
								while ((ch = cmd_string_getc(s, &p)) != EOF)
 | 
				
			||||||
 | 
									;
 | 
				
			||||||
 | 
								/* FALLTHROUGH */
 | 
				
			||||||
 | 
							case EOF:
 | 
				
			||||||
 | 
							case ' ':
 | 
				
			||||||
 | 
							case '\t':
 | 
				
			||||||
 | 
					 			if (have_arg) {
 | 
				
			||||||
 | 
									buf = xrealloc(buf, 1, len + 1);
 | 
				
			||||||
 | 
									buf[len] = '\0';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									argv = xrealloc(argv, argc + 1, sizeof *argv);
 | 
				
			||||||
 | 
									argv[argc++] = buf;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									buf = NULL;
 | 
				
			||||||
 | 
									len = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									have_arg = 0;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (ch != EOF)
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								if (argc == 0)
 | 
				
			||||||
 | 
									goto out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								*cmdlist = cmd_list_parse(argc, argv, cause);
 | 
				
			||||||
 | 
								if (*cmdlist == NULL)
 | 
				
			||||||
 | 
									goto out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								do
 | 
				
			||||||
 | 
									xfree(argv[argc - 1]);
 | 
				
			||||||
 | 
								while (--argc > 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								rval = 0;
 | 
				
			||||||
 | 
								goto out;
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								if (len >= SIZE_MAX - 2)
 | 
				
			||||||
 | 
									goto error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								buf = xrealloc(buf, 1, len + 1);
 | 
				
			||||||
 | 
								buf[len++] = ch;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								have_arg = 1;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					error:
 | 
				
			||||||
 | 
						xasprintf(cause, "invalid or unknown command: %s", s);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					out:
 | 
				
			||||||
 | 
						if (buf != NULL)
 | 
				
			||||||
 | 
							xfree(buf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while (--argc >= 0)
 | 
				
			||||||
 | 
							xfree(argv[argc]);
 | 
				
			||||||
 | 
						if (argv != NULL)
 | 
				
			||||||
 | 
							xfree(argv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (rval);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					char *
 | 
				
			||||||
 | 
					cmd_string_string(const char *s, size_t *p, char endch, int esc)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int	ch;
 | 
				
			||||||
 | 
						char   *buf, *t;
 | 
				
			||||||
 | 
						size_t	len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        buf = NULL;
 | 
				
			||||||
 | 
						len = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        while ((ch = cmd_string_getc(s, p)) != endch) {
 | 
				
			||||||
 | 
					                switch (ch) {
 | 
				
			||||||
 | 
							case EOF:
 | 
				
			||||||
 | 
								goto error;
 | 
				
			||||||
 | 
					                case '\\':
 | 
				
			||||||
 | 
								if (!esc)
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
					                        switch (ch = cmd_string_getc(s, p)) {
 | 
				
			||||||
 | 
								case EOF:
 | 
				
			||||||
 | 
									goto error;
 | 
				
			||||||
 | 
					                        case 'r':
 | 
				
			||||||
 | 
					                                ch = '\r';
 | 
				
			||||||
 | 
					                                break;
 | 
				
			||||||
 | 
					                        case 'n':
 | 
				
			||||||
 | 
					                                ch = '\n';
 | 
				
			||||||
 | 
					                                break;
 | 
				
			||||||
 | 
					                        case 't':
 | 
				
			||||||
 | 
					                                ch = '\t';
 | 
				
			||||||
 | 
					                                break;
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                        break;
 | 
				
			||||||
 | 
							case '$':
 | 
				
			||||||
 | 
								if (!esc)
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								if ((t = cmd_string_variable(s, p)) == NULL)
 | 
				
			||||||
 | 
									goto error;
 | 
				
			||||||
 | 
								buf = xrealloc(buf, 1, len + strlen(t) + 1);
 | 
				
			||||||
 | 
								strlcpy(buf + len, t, strlen(t) + 1);
 | 
				
			||||||
 | 
								len += strlen(t);
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (len >= SIZE_MAX - 2)
 | 
				
			||||||
 | 
								goto error;
 | 
				
			||||||
 | 
							buf = xrealloc(buf, 1, len + 1);
 | 
				
			||||||
 | 
					                buf[len++] = ch;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						buf = xrealloc(buf, 1, len + 1);
 | 
				
			||||||
 | 
						buf[len] = '\0';
 | 
				
			||||||
 | 
						return (buf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					error:
 | 
				
			||||||
 | 
						if (buf != NULL)
 | 
				
			||||||
 | 
							xfree(buf);
 | 
				
			||||||
 | 
						return (NULL);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					char *
 | 
				
			||||||
 | 
					cmd_string_variable(const char *s, size_t *p)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int	ch, fch;
 | 
				
			||||||
 | 
						char   *buf, *t;
 | 
				
			||||||
 | 
						size_t	len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define cmd_string_first(ch) ((ch) == '_' || \
 | 
				
			||||||
 | 
						((ch) >= 'a' && (ch) <= 'z') || ((ch) >= 'A' && (ch) <= 'Z'))
 | 
				
			||||||
 | 
					#define cmd_string_other(ch) ((ch) == '_' || \
 | 
				
			||||||
 | 
						((ch) >= 'a' && (ch) <= 'z') || ((ch) >= 'A' && (ch) <= 'Z') || \
 | 
				
			||||||
 | 
						((ch) >= '0' && (ch) <= '9'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        buf = NULL;
 | 
				
			||||||
 | 
						len = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fch = EOF;
 | 
				
			||||||
 | 
						switch (ch = cmd_string_getc(s, p)) {
 | 
				
			||||||
 | 
						case EOF:
 | 
				
			||||||
 | 
							goto error;
 | 
				
			||||||
 | 
						case '{':
 | 
				
			||||||
 | 
							fch = '{';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							ch = cmd_string_getc(s, p);
 | 
				
			||||||
 | 
							if (!cmd_string_first(ch))
 | 
				
			||||||
 | 
								goto error;
 | 
				
			||||||
 | 
							/* FALLTHROUGH */
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							if (!cmd_string_first(ch)) {
 | 
				
			||||||
 | 
								xasprintf(&t, "$%c", ch);
 | 
				
			||||||
 | 
								return (t);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							buf = xrealloc(buf, 1, len + 1);
 | 
				
			||||||
 | 
							buf[len++] = ch;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for (;;) {
 | 
				
			||||||
 | 
								ch = cmd_string_getc(s, p);
 | 
				
			||||||
 | 
								if (ch == EOF || !cmd_string_other(ch))
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								else {
 | 
				
			||||||
 | 
									if (len >= SIZE_MAX - 3)
 | 
				
			||||||
 | 
										goto error;
 | 
				
			||||||
 | 
									buf = xrealloc(buf, 1, len + 1);
 | 
				
			||||||
 | 
									buf[len++] = ch;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (fch == '{' && ch != '}')
 | 
				
			||||||
 | 
							goto error;
 | 
				
			||||||
 | 
						if (ch != EOF && fch != '{')
 | 
				
			||||||
 | 
							cmd_string_ungetc(s, p); /* ch */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						buf = xrealloc(buf, 1, len + 1);
 | 
				
			||||||
 | 
						buf[len] = '\0';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((t = getenv(buf)) == NULL) {
 | 
				
			||||||
 | 
							xfree(buf);
 | 
				
			||||||
 | 
							return (xstrdup(""));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						xfree(buf);
 | 
				
			||||||
 | 
						return (xstrdup(t));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					error:
 | 
				
			||||||
 | 
						if (buf != NULL)
 | 
				
			||||||
 | 
							xfree(buf);
 | 
				
			||||||
 | 
						return (NULL);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										64
									
								
								cmd-suspend-client.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								cmd-suspend-client.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,64 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Suspend client with SIGTSTP.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_suspend_client_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct cmd_suspend_client_data {
 | 
				
			||||||
 | 
						char	*name;
 | 
				
			||||||
 | 
						char	*target;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_suspend_client_entry = {
 | 
				
			||||||
 | 
						"suspend-client", "suspendc",
 | 
				
			||||||
 | 
						"[-c target-client]",
 | 
				
			||||||
 | 
						0,
 | 
				
			||||||
 | 
						cmd_target_init,
 | 
				
			||||||
 | 
						cmd_target_parse,
 | 
				
			||||||
 | 
						cmd_suspend_client_exec,
 | 
				
			||||||
 | 
						cmd_target_send,
 | 
				
			||||||
 | 
						cmd_target_recv,
 | 
				
			||||||
 | 
						cmd_target_free,
 | 
				
			||||||
 | 
						cmd_target_print
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_suspend_client_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_target_data	*data = self->data;
 | 
				
			||||||
 | 
						struct client		*c;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((c = cmd_find_client(ctx, data->target)) == NULL)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tty_stop_tty(&c->tty);
 | 
				
			||||||
 | 
						c->flags |= CLIENT_SUSPENDED;
 | 
				
			||||||
 | 
						server_write_client(c, MSG_SUSPEND, NULL, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										285
									
								
								cmd-swap-pane.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										285
									
								
								cmd-swap-pane.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,285 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Swap two panes.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_swap_pane_parse(struct cmd *, int, char **, char **);
 | 
				
			||||||
 | 
					int	cmd_swap_pane_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					void	cmd_swap_pane_send(struct cmd *, struct buffer *);
 | 
				
			||||||
 | 
					void	cmd_swap_pane_recv(struct cmd *, struct buffer *);
 | 
				
			||||||
 | 
					void	cmd_swap_pane_free(struct cmd *);
 | 
				
			||||||
 | 
					void	cmd_swap_pane_init(struct cmd *, int);
 | 
				
			||||||
 | 
					size_t	cmd_swap_pane_print(struct cmd *, char *, size_t);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct cmd_swap_pane_data {
 | 
				
			||||||
 | 
						char	*target;
 | 
				
			||||||
 | 
					        int	 src;
 | 
				
			||||||
 | 
						int	 dst;
 | 
				
			||||||
 | 
						int	 flag_detached;
 | 
				
			||||||
 | 
						int	 flag_up;
 | 
				
			||||||
 | 
						int	 flag_down;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_swap_pane_entry = {
 | 
				
			||||||
 | 
						"swap-pane", "swapp",
 | 
				
			||||||
 | 
						"[-dDU] [-t target-window] [-p src-index] [-q dst-index]",
 | 
				
			||||||
 | 
						0,
 | 
				
			||||||
 | 
						cmd_swap_pane_init,
 | 
				
			||||||
 | 
						cmd_swap_pane_parse,
 | 
				
			||||||
 | 
						cmd_swap_pane_exec,
 | 
				
			||||||
 | 
						cmd_swap_pane_send,
 | 
				
			||||||
 | 
						cmd_swap_pane_recv,
 | 
				
			||||||
 | 
						cmd_swap_pane_free,
 | 
				
			||||||
 | 
						cmd_swap_pane_print
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_swap_pane_init(struct cmd *self, int key)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_swap_pane_data	 *data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						self->data = data = xmalloc(sizeof *data);
 | 
				
			||||||
 | 
						data->target = NULL;
 | 
				
			||||||
 | 
						data->src = -1;
 | 
				
			||||||
 | 
						data->dst = -1;
 | 
				
			||||||
 | 
						data->flag_detached = 0;
 | 
				
			||||||
 | 
						data->flag_up = 0;
 | 
				
			||||||
 | 
						data->flag_down = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (key) {
 | 
				
			||||||
 | 
						case '{':
 | 
				
			||||||
 | 
							data->flag_up = 1;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case '}':
 | 
				
			||||||
 | 
							data->flag_down = 1;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_swap_pane_parse(struct cmd *self, int argc, char **argv, char **cause)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_swap_pane_data	*data;
 | 
				
			||||||
 | 
						int				 opt, n;
 | 
				
			||||||
 | 
						const char			*errstr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						self->entry->init(self, 0);
 | 
				
			||||||
 | 
						data = self->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while ((opt = getopt(argc, argv, "dDt:p:q:U")) != -1) {
 | 
				
			||||||
 | 
							switch (opt) {
 | 
				
			||||||
 | 
							case 'd':
 | 
				
			||||||
 | 
								data->flag_detached = 1;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case 'D':
 | 
				
			||||||
 | 
								data->flag_up = 0;
 | 
				
			||||||
 | 
								data->flag_down = 1;
 | 
				
			||||||
 | 
								data->dst = -1;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case 't':
 | 
				
			||||||
 | 
								if (data->target == NULL)
 | 
				
			||||||
 | 
									data->target = xstrdup(optarg);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case 'p':
 | 
				
			||||||
 | 
								if (data->src == -1) {
 | 
				
			||||||
 | 
									n = strtonum(optarg, 0, INT_MAX, &errstr);
 | 
				
			||||||
 | 
									if (errstr != NULL) {
 | 
				
			||||||
 | 
										xasprintf(cause, "src %s", errstr);
 | 
				
			||||||
 | 
										goto error;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									data->src = n;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case 'q':
 | 
				
			||||||
 | 
								if (data->dst == -1) {
 | 
				
			||||||
 | 
									n = strtonum(optarg, 0, INT_MAX, &errstr);
 | 
				
			||||||
 | 
									if (errstr != NULL) {
 | 
				
			||||||
 | 
										xasprintf(cause, "dst %s", errstr);
 | 
				
			||||||
 | 
										goto error;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									data->dst = n;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								data->flag_up = 0;
 | 
				
			||||||
 | 
								data->flag_down = 0;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case 'U':
 | 
				
			||||||
 | 
								data->flag_up = 1;
 | 
				
			||||||
 | 
								data->flag_down = 0;
 | 
				
			||||||
 | 
								data->dst = -1;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								goto usage;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						argc -= optind;
 | 
				
			||||||
 | 
						argv += optind;
 | 
				
			||||||
 | 
						if (argc != 0)
 | 
				
			||||||
 | 
							goto usage;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					usage:
 | 
				
			||||||
 | 
						xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					error:
 | 
				
			||||||
 | 
						self->entry->free(self);
 | 
				
			||||||
 | 
						return (-1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_swap_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_swap_pane_data	*data = self->data;
 | 
				
			||||||
 | 
						struct winlink			*wl;
 | 
				
			||||||
 | 
						struct window			*w;
 | 
				
			||||||
 | 
						struct window_pane		*tmp_wp, *src_wp, *dst_wp;
 | 
				
			||||||
 | 
						u_int				 xx, yy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (data == NULL)
 | 
				
			||||||
 | 
							return (0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						w = wl->window;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (data->src == -1)
 | 
				
			||||||
 | 
							src_wp = w->active;
 | 
				
			||||||
 | 
						else {
 | 
				
			||||||
 | 
							src_wp = window_pane_at_index(w, data->src);
 | 
				
			||||||
 | 
							if (src_wp == NULL) {
 | 
				
			||||||
 | 
								ctx->error(ctx, "no pane: %d", data->src);
 | 
				
			||||||
 | 
								return (-1);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (data->dst == -1)
 | 
				
			||||||
 | 
							dst_wp = w->active;
 | 
				
			||||||
 | 
						else {
 | 
				
			||||||
 | 
							dst_wp = window_pane_at_index(w, data->dst);
 | 
				
			||||||
 | 
							if (dst_wp == NULL) {
 | 
				
			||||||
 | 
								ctx->error(ctx, "no pane: %d", data->dst);
 | 
				
			||||||
 | 
								return (-1);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (data->dst == -1 && data->flag_up) {
 | 
				
			||||||
 | 
							if ((dst_wp = TAILQ_PREV(src_wp, window_panes, entry)) == NULL)
 | 
				
			||||||
 | 
								dst_wp = TAILQ_LAST(&w->panes, window_panes);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (data->dst == -1 && data->flag_down) {
 | 
				
			||||||
 | 
							if ((dst_wp = TAILQ_NEXT(src_wp, entry)) == NULL)
 | 
				
			||||||
 | 
								dst_wp = TAILQ_FIRST(&w->panes);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (src_wp == dst_wp)
 | 
				
			||||||
 | 
							return (0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tmp_wp = TAILQ_PREV(dst_wp, window_panes, entry);
 | 
				
			||||||
 | 
						TAILQ_REMOVE(&w->panes, dst_wp, entry);
 | 
				
			||||||
 | 
						TAILQ_REPLACE(&w->panes, src_wp, dst_wp, entry);
 | 
				
			||||||
 | 
						if (tmp_wp == src_wp)
 | 
				
			||||||
 | 
							tmp_wp = dst_wp;
 | 
				
			||||||
 | 
						if (tmp_wp == NULL)
 | 
				
			||||||
 | 
							TAILQ_INSERT_HEAD(&w->panes, src_wp, entry);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							TAILQ_INSERT_AFTER(&w->panes, tmp_wp, src_wp, entry);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						xx = src_wp->xoff;
 | 
				
			||||||
 | 
						yy = src_wp->yoff;
 | 
				
			||||||
 | 
					 	src_wp->xoff = dst_wp->xoff;
 | 
				
			||||||
 | 
					 	src_wp->yoff = dst_wp->yoff;
 | 
				
			||||||
 | 
					 	dst_wp->xoff = xx;
 | 
				
			||||||
 | 
					 	dst_wp->yoff = yy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						xx = src_wp->sx;
 | 
				
			||||||
 | 
						yy = src_wp->sy;
 | 
				
			||||||
 | 
						window_pane_resize(src_wp, dst_wp->sx, dst_wp->sy);
 | 
				
			||||||
 | 
						window_pane_resize(dst_wp, xx, yy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!data->flag_detached) {
 | 
				
			||||||
 | 
							window_set_active_pane(w, dst_wp);
 | 
				
			||||||
 | 
							layout_refresh(w, 0);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_swap_pane_send(struct cmd *self, struct buffer *b)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_swap_pane_data	*data = self->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						buffer_write(b, data, sizeof *data);
 | 
				
			||||||
 | 
						cmd_send_string(b, data->target);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_swap_pane_recv(struct cmd *self, struct buffer *b)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_swap_pane_data	*data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						self->data = data = xmalloc(sizeof *data);
 | 
				
			||||||
 | 
						buffer_read(b, data, sizeof *data);
 | 
				
			||||||
 | 
						data->target = cmd_recv_string(b);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_swap_pane_free(struct cmd *self)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_swap_pane_data	*data = self->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (data->target != NULL)
 | 
				
			||||||
 | 
							xfree(data->target);
 | 
				
			||||||
 | 
						xfree(data);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					size_t
 | 
				
			||||||
 | 
					cmd_swap_pane_print(struct cmd *self, char *buf, size_t len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_swap_pane_data	*data = self->data;
 | 
				
			||||||
 | 
						size_t				 off = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						off += xsnprintf(buf, len, "%s", self->entry->name);
 | 
				
			||||||
 | 
						if (data == NULL)
 | 
				
			||||||
 | 
							return (off);
 | 
				
			||||||
 | 
						if (off < len &&
 | 
				
			||||||
 | 
						    (data->flag_down || data->flag_up || data->flag_detached)) {
 | 
				
			||||||
 | 
							off += xsnprintf(buf + off, len - off, " -");
 | 
				
			||||||
 | 
							if (off < len && data->flag_detached)
 | 
				
			||||||
 | 
								off += xsnprintf(buf + off, len - off, "d");
 | 
				
			||||||
 | 
							if (off < len && data->flag_up)
 | 
				
			||||||
 | 
								off += xsnprintf(buf + off, len - off, "D");
 | 
				
			||||||
 | 
							if (off < len && data->flag_down)
 | 
				
			||||||
 | 
								off += xsnprintf(buf + off, len - off, "U");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (off < len && data->target != NULL)
 | 
				
			||||||
 | 
							off += cmd_prarg(buf + off, len - off, " -t ", data->target);
 | 
				
			||||||
 | 
						if (off < len && data->src != -1)
 | 
				
			||||||
 | 
							off += xsnprintf(buf + off, len - off, " -p %d", data->src);
 | 
				
			||||||
 | 
						if (off < len && data->dst != -1)
 | 
				
			||||||
 | 
							off += xsnprintf(buf + off, len - off, " -q %d", data->dst);
 | 
				
			||||||
 | 
						return (off);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										75
									
								
								cmd-swap-window.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								cmd-swap-window.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,75 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Swap one window with another.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_swap_window_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_swap_window_entry = {
 | 
				
			||||||
 | 
						"swap-window", "swapw",
 | 
				
			||||||
 | 
						"[-d] " CMD_SRCDST_WINDOW_USAGE,
 | 
				
			||||||
 | 
						CMD_DFLAG,
 | 
				
			||||||
 | 
						cmd_srcdst_init,
 | 
				
			||||||
 | 
						cmd_srcdst_parse,
 | 
				
			||||||
 | 
						cmd_swap_window_exec,
 | 
				
			||||||
 | 
						cmd_srcdst_send,
 | 
				
			||||||
 | 
						cmd_srcdst_recv,
 | 
				
			||||||
 | 
						cmd_srcdst_free,
 | 
				
			||||||
 | 
						cmd_srcdst_print
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_swap_window_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_srcdst_data	*data = self->data;
 | 
				
			||||||
 | 
						struct session		*src, *dst;
 | 
				
			||||||
 | 
						struct winlink		*wl_src, *wl_dst;
 | 
				
			||||||
 | 
						struct window		*w;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((wl_src = cmd_find_window(ctx, data->src, &src)) == NULL)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						if ((wl_dst = cmd_find_window(ctx, data->dst, &dst)) == NULL)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (wl_dst->window == wl_src->window)
 | 
				
			||||||
 | 
							return (0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						w = wl_dst->window;
 | 
				
			||||||
 | 
						wl_dst->window = wl_src->window;
 | 
				
			||||||
 | 
						wl_src->window = w;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!(data->flags & CMD_DFLAG)) {
 | 
				
			||||||
 | 
							session_select(dst, wl_dst->idx);
 | 
				
			||||||
 | 
							if (src != dst)
 | 
				
			||||||
 | 
								session_select(src, wl_src->idx);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						server_redraw_session(src);
 | 
				
			||||||
 | 
						if (src != dst)
 | 
				
			||||||
 | 
							server_redraw_session(dst);
 | 
				
			||||||
 | 
						recalculate_sizes();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										161
									
								
								cmd-switch-client.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										161
									
								
								cmd-switch-client.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,161 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Switch client to a different session.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_switch_client_parse(struct cmd *, int, char **, char **);
 | 
				
			||||||
 | 
					int	cmd_switch_client_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					void	cmd_switch_client_send(struct cmd *, struct buffer *);
 | 
				
			||||||
 | 
					void	cmd_switch_client_recv(struct cmd *, struct buffer *);
 | 
				
			||||||
 | 
					void	cmd_switch_client_free(struct cmd *);
 | 
				
			||||||
 | 
					size_t	cmd_switch_client_print(struct cmd *, char *, size_t);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct cmd_switch_client_data {
 | 
				
			||||||
 | 
						char	*name;
 | 
				
			||||||
 | 
						char	*target;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_switch_client_entry = {
 | 
				
			||||||
 | 
						"switch-client", "switchc",
 | 
				
			||||||
 | 
						"[-c target-client] [-t target-session]",
 | 
				
			||||||
 | 
						0,
 | 
				
			||||||
 | 
						NULL,
 | 
				
			||||||
 | 
						cmd_switch_client_parse,
 | 
				
			||||||
 | 
						cmd_switch_client_exec,
 | 
				
			||||||
 | 
						cmd_switch_client_send,
 | 
				
			||||||
 | 
						cmd_switch_client_recv,
 | 
				
			||||||
 | 
						cmd_switch_client_free,
 | 
				
			||||||
 | 
						cmd_switch_client_print
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_switch_client_parse(struct cmd *self, int argc, char **argv, char **cause)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_switch_client_data	*data;
 | 
				
			||||||
 | 
						int				 opt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						self->data = data = xmalloc(sizeof *data);
 | 
				
			||||||
 | 
						data->name = NULL;
 | 
				
			||||||
 | 
						data->target = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while ((opt = getopt(argc, argv, "c:t:")) != -1) {
 | 
				
			||||||
 | 
							switch (opt) {
 | 
				
			||||||
 | 
							case 'c':
 | 
				
			||||||
 | 
								data->name = xstrdup(optarg);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case 't':
 | 
				
			||||||
 | 
								data->target = xstrdup(optarg);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								goto usage;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						argc -= optind;
 | 
				
			||||||
 | 
						argv += optind;
 | 
				
			||||||
 | 
						if (argc != 0)
 | 
				
			||||||
 | 
							goto usage;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					usage:
 | 
				
			||||||
 | 
						xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						self->entry->free(self);
 | 
				
			||||||
 | 
						return (-1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_switch_client_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_switch_client_data	*data = self->data;
 | 
				
			||||||
 | 
						struct client			*c;
 | 
				
			||||||
 | 
						struct session			*s;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (data == NULL)
 | 
				
			||||||
 | 
							return (0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((c = cmd_find_client(ctx, data->name)) == NULL)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						if ((s = cmd_find_session(ctx, data->target)) == NULL)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						c->session = s;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						recalculate_sizes();
 | 
				
			||||||
 | 
						server_redraw_client(c);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_switch_client_send(struct cmd *self, struct buffer *b)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_switch_client_data	*data = self->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						buffer_write(b, data, sizeof *data);
 | 
				
			||||||
 | 
						cmd_send_string(b, data->name);
 | 
				
			||||||
 | 
						cmd_send_string(b, data->target);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_switch_client_recv(struct cmd *self, struct buffer *b)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_switch_client_data	*data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						self->data = data = xmalloc(sizeof *data);
 | 
				
			||||||
 | 
						buffer_read(b, data, sizeof *data);
 | 
				
			||||||
 | 
						data->name = cmd_recv_string(b);
 | 
				
			||||||
 | 
						data->target = cmd_recv_string(b);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_switch_client_free(struct cmd *self)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_switch_client_data	*data = self->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (data->name != NULL)
 | 
				
			||||||
 | 
							xfree(data->name);
 | 
				
			||||||
 | 
						if (data->target != NULL)
 | 
				
			||||||
 | 
							xfree(data->target);
 | 
				
			||||||
 | 
						xfree(data);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					size_t
 | 
				
			||||||
 | 
					cmd_switch_client_print(struct cmd *self, char *buf, size_t len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_switch_client_data	*data = self->data;
 | 
				
			||||||
 | 
						size_t				 off = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						off += xsnprintf(buf, len, "%s", self->entry->name);
 | 
				
			||||||
 | 
						if (data == NULL)
 | 
				
			||||||
 | 
							return (off);
 | 
				
			||||||
 | 
						if (off < len && data->name != NULL)
 | 
				
			||||||
 | 
							off += cmd_prarg(buf + off, len - off, " -c ", data->name);
 | 
				
			||||||
 | 
						if (off < len && data->target != NULL)
 | 
				
			||||||
 | 
							off += cmd_prarg(buf + off, len - off, " -t ", data->target);
 | 
				
			||||||
 | 
						return (off);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										120
									
								
								cmd-unbind-key.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										120
									
								
								cmd-unbind-key.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,120 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Unbind key from command.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_unbind_key_parse(struct cmd *, int, char **, char **);
 | 
				
			||||||
 | 
					int	cmd_unbind_key_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					void	cmd_unbind_key_send(struct cmd *, struct buffer *);
 | 
				
			||||||
 | 
					void	cmd_unbind_key_recv(struct cmd *, struct buffer *);
 | 
				
			||||||
 | 
					void	cmd_unbind_key_free(struct cmd *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct cmd_unbind_key_data {
 | 
				
			||||||
 | 
						int	key;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_unbind_key_entry = {
 | 
				
			||||||
 | 
						"unbind-key", "unbind",
 | 
				
			||||||
 | 
						"key",
 | 
				
			||||||
 | 
						0,
 | 
				
			||||||
 | 
						NULL,
 | 
				
			||||||
 | 
						cmd_unbind_key_parse,
 | 
				
			||||||
 | 
						cmd_unbind_key_exec,
 | 
				
			||||||
 | 
						cmd_unbind_key_send,
 | 
				
			||||||
 | 
						cmd_unbind_key_recv,
 | 
				
			||||||
 | 
						cmd_unbind_key_free,
 | 
				
			||||||
 | 
						NULL
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_unbind_key_parse(struct cmd *self, int argc, char **argv, char **cause)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_unbind_key_data	*data;
 | 
				
			||||||
 | 
						int				 opt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						self->data = data = xmalloc(sizeof *data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while ((opt = getopt(argc, argv, "")) != -1) {
 | 
				
			||||||
 | 
							switch (opt) {
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								goto usage;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						argc -= optind;
 | 
				
			||||||
 | 
						argv += optind;
 | 
				
			||||||
 | 
						if (argc != 1)
 | 
				
			||||||
 | 
							goto usage;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((data->key = key_string_lookup_string(argv[0])) == KEYC_NONE) {
 | 
				
			||||||
 | 
							xasprintf(cause, "unknown key: %s", argv[0]);
 | 
				
			||||||
 | 
							goto error;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					usage:
 | 
				
			||||||
 | 
						xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					error:
 | 
				
			||||||
 | 
						xfree(data);
 | 
				
			||||||
 | 
						return (-1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_unbind_key_exec(struct cmd *self, unused struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_unbind_key_data	*data = self->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (data == NULL)
 | 
				
			||||||
 | 
							return (0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						key_bindings_remove(data->key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_unbind_key_send(struct cmd *self, struct buffer *b)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_unbind_key_data	*data = self->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						buffer_write(b, data, sizeof *data);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_unbind_key_recv(struct cmd *self, struct buffer *b)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_unbind_key_data	*data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						self->data = data = xmalloc(sizeof *data);
 | 
				
			||||||
 | 
						buffer_read(b, data, sizeof *data);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_unbind_key_free(struct cmd *self)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_unbind_key_data	*data = self->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						xfree(data);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										74
									
								
								cmd-unlink-window.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								cmd-unlink-window.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,74 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Unlink a window, unless it would be destroyed by doing so (only one link).
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_unlink_window_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_unlink_window_entry = {
 | 
				
			||||||
 | 
						"unlink-window", "unlinkw",
 | 
				
			||||||
 | 
						CMD_TARGET_WINDOW_USAGE,
 | 
				
			||||||
 | 
						0,
 | 
				
			||||||
 | 
						cmd_target_init,
 | 
				
			||||||
 | 
						cmd_target_parse,
 | 
				
			||||||
 | 
						cmd_unlink_window_exec,
 | 
				
			||||||
 | 
						cmd_target_send,
 | 
				
			||||||
 | 
						cmd_target_recv,
 | 
				
			||||||
 | 
						cmd_target_free,
 | 
				
			||||||
 | 
						cmd_target_print
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_unlink_window_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_target_data	*data = self->data;
 | 
				
			||||||
 | 
						struct winlink		*wl;
 | 
				
			||||||
 | 
						struct session		*s;
 | 
				
			||||||
 | 
						struct client		*c;
 | 
				
			||||||
 | 
						u_int			 i;
 | 
				
			||||||
 | 
						int			 destroyed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (wl->window->references == 1) {
 | 
				
			||||||
 | 
							ctx->error(ctx, "window is only linked to one session");
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 	destroyed = session_detach(s, wl);
 | 
				
			||||||
 | 
						for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
 | 
				
			||||||
 | 
							c = ARRAY_ITEM(&clients, i);
 | 
				
			||||||
 | 
							if (c == NULL || c->session != s)
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							if (destroyed) {
 | 
				
			||||||
 | 
								c->session = NULL;
 | 
				
			||||||
 | 
								server_write_client(c, MSG_EXIT, NULL, 0);
 | 
				
			||||||
 | 
							} else
 | 
				
			||||||
 | 
								server_redraw_client(c);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						recalculate_sizes();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										61
									
								
								cmd-up-pane.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								cmd-up-pane.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,61 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Move up a pane.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	cmd_up_pane_exec(struct cmd *, struct cmd_ctx *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry cmd_up_pane_entry = {
 | 
				
			||||||
 | 
						"up-pane", "upp",
 | 
				
			||||||
 | 
						CMD_TARGET_WINDOW_USAGE,
 | 
				
			||||||
 | 
						0,
 | 
				
			||||||
 | 
						cmd_target_init,
 | 
				
			||||||
 | 
						cmd_target_parse,
 | 
				
			||||||
 | 
						cmd_up_pane_exec,
 | 
				
			||||||
 | 
						cmd_target_send,
 | 
				
			||||||
 | 
						cmd_target_recv,
 | 
				
			||||||
 | 
						cmd_target_free,
 | 
				
			||||||
 | 
						cmd_target_print
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_up_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_target_data	*data = self->data;
 | 
				
			||||||
 | 
						struct winlink		*wl;
 | 
				
			||||||
 | 
						struct window		*w;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						w = wl->window;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						do {
 | 
				
			||||||
 | 
							w->active = TAILQ_PREV(w->active, window_panes, entry);
 | 
				
			||||||
 | 
							if (w->active == NULL)
 | 
				
			||||||
 | 
								w->active = TAILQ_LAST(&w->panes, window_panes);
 | 
				
			||||||
 | 
							layout_refresh(w, 1);
 | 
				
			||||||
 | 
						} while (w->active->flags & PANE_HIDDEN);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										393
									
								
								cmd.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										393
									
								
								cmd.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,393 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					#include <sys/time.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct cmd_entry *cmd_table[] = {
 | 
				
			||||||
 | 
						&cmd_attach_session_entry,
 | 
				
			||||||
 | 
						&cmd_bind_key_entry,
 | 
				
			||||||
 | 
						&cmd_break_pane_entry,
 | 
				
			||||||
 | 
						&cmd_choose_session_entry,
 | 
				
			||||||
 | 
						&cmd_choose_window_entry,
 | 
				
			||||||
 | 
						&cmd_clear_history_entry,
 | 
				
			||||||
 | 
						&cmd_clock_mode_entry,
 | 
				
			||||||
 | 
						&cmd_command_prompt_entry,
 | 
				
			||||||
 | 
						&cmd_confirm_before_entry,
 | 
				
			||||||
 | 
						&cmd_copy_buffer_entry,
 | 
				
			||||||
 | 
						&cmd_copy_mode_entry,
 | 
				
			||||||
 | 
						&cmd_delete_buffer_entry,
 | 
				
			||||||
 | 
						&cmd_detach_client_entry,
 | 
				
			||||||
 | 
						&cmd_down_pane_entry,
 | 
				
			||||||
 | 
						&cmd_find_window_entry,
 | 
				
			||||||
 | 
						&cmd_has_session_entry,
 | 
				
			||||||
 | 
						&cmd_kill_pane_entry,
 | 
				
			||||||
 | 
						&cmd_kill_server_entry,
 | 
				
			||||||
 | 
						&cmd_kill_session_entry,
 | 
				
			||||||
 | 
						&cmd_kill_window_entry,
 | 
				
			||||||
 | 
						&cmd_last_window_entry,
 | 
				
			||||||
 | 
						&cmd_link_window_entry,
 | 
				
			||||||
 | 
						&cmd_list_buffers_entry,
 | 
				
			||||||
 | 
						&cmd_list_clients_entry,
 | 
				
			||||||
 | 
						&cmd_list_commands_entry,
 | 
				
			||||||
 | 
						&cmd_list_keys_entry,
 | 
				
			||||||
 | 
						&cmd_list_sessions_entry,
 | 
				
			||||||
 | 
						&cmd_list_windows_entry,
 | 
				
			||||||
 | 
						&cmd_load_buffer_entry,
 | 
				
			||||||
 | 
						&cmd_lock_server_entry,
 | 
				
			||||||
 | 
						&cmd_move_window_entry,
 | 
				
			||||||
 | 
						&cmd_new_session_entry,
 | 
				
			||||||
 | 
						&cmd_new_window_entry,
 | 
				
			||||||
 | 
						&cmd_next_layout_entry,
 | 
				
			||||||
 | 
						&cmd_next_window_entry,
 | 
				
			||||||
 | 
						&cmd_paste_buffer_entry,
 | 
				
			||||||
 | 
						&cmd_previous_layout_entry,
 | 
				
			||||||
 | 
						&cmd_previous_window_entry,
 | 
				
			||||||
 | 
						&cmd_refresh_client_entry,
 | 
				
			||||||
 | 
						&cmd_rename_session_entry,
 | 
				
			||||||
 | 
						&cmd_rename_window_entry,
 | 
				
			||||||
 | 
						&cmd_resize_pane_entry,
 | 
				
			||||||
 | 
						&cmd_respawn_window_entry,
 | 
				
			||||||
 | 
						&cmd_rotate_window_entry,
 | 
				
			||||||
 | 
						&cmd_save_buffer_entry,
 | 
				
			||||||
 | 
						&cmd_scroll_mode_entry,
 | 
				
			||||||
 | 
						&cmd_select_layout_entry,
 | 
				
			||||||
 | 
						&cmd_select_pane_entry,
 | 
				
			||||||
 | 
						&cmd_select_prompt_entry,
 | 
				
			||||||
 | 
						&cmd_select_window_entry,
 | 
				
			||||||
 | 
						&cmd_send_keys_entry,
 | 
				
			||||||
 | 
						&cmd_send_prefix_entry,
 | 
				
			||||||
 | 
						&cmd_server_info_entry,
 | 
				
			||||||
 | 
						&cmd_set_buffer_entry,
 | 
				
			||||||
 | 
						&cmd_set_option_entry,
 | 
				
			||||||
 | 
						&cmd_set_password_entry,
 | 
				
			||||||
 | 
						&cmd_set_window_option_entry,
 | 
				
			||||||
 | 
						&cmd_show_buffer_entry,
 | 
				
			||||||
 | 
						&cmd_show_options_entry,
 | 
				
			||||||
 | 
						&cmd_show_window_options_entry,
 | 
				
			||||||
 | 
						&cmd_source_file_entry,
 | 
				
			||||||
 | 
						&cmd_split_window_entry,
 | 
				
			||||||
 | 
						&cmd_start_server_entry,
 | 
				
			||||||
 | 
						&cmd_suspend_client_entry,
 | 
				
			||||||
 | 
						&cmd_swap_pane_entry,
 | 
				
			||||||
 | 
						&cmd_swap_window_entry,
 | 
				
			||||||
 | 
						&cmd_switch_client_entry,
 | 
				
			||||||
 | 
						&cmd_unbind_key_entry,
 | 
				
			||||||
 | 
						&cmd_unlink_window_entry,
 | 
				
			||||||
 | 
						&cmd_up_pane_entry,
 | 
				
			||||||
 | 
						NULL
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct cmd *
 | 
				
			||||||
 | 
					cmd_parse(int argc, char **argv, char **cause)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const struct cmd_entry **entryp, *entry;
 | 
				
			||||||
 | 
						struct cmd	        *cmd;
 | 
				
			||||||
 | 
						char			 s[BUFSIZ];
 | 
				
			||||||
 | 
						int			 opt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						*cause = NULL;
 | 
				
			||||||
 | 
						if (argc == 0)
 | 
				
			||||||
 | 
							return (NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						entry = NULL;
 | 
				
			||||||
 | 
						for (entryp = cmd_table; *entryp != NULL; entryp++) {
 | 
				
			||||||
 | 
							if ((*entryp)->alias != NULL &&
 | 
				
			||||||
 | 
							    strcmp((*entryp)->alias, argv[0]) == 0) {
 | 
				
			||||||
 | 
								entry = *entryp;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (strncmp((*entryp)->name, argv[0], strlen(argv[0])) != 0)
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							if (entry != NULL)
 | 
				
			||||||
 | 
								goto ambiguous;
 | 
				
			||||||
 | 
							entry = *entryp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Bail now if an exact match. */
 | 
				
			||||||
 | 
							if (strcmp(entry->name, argv[0]) == 0)
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (entry == NULL) {
 | 
				
			||||||
 | 
							xasprintf(cause, "unknown command: %s", argv[0]);
 | 
				
			||||||
 | 
							return (NULL);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						optreset = 1;
 | 
				
			||||||
 | 
						optind = 1;
 | 
				
			||||||
 | 
						if (entry->parse == NULL) {
 | 
				
			||||||
 | 
							while ((opt = getopt(argc, argv, "")) != -1) {
 | 
				
			||||||
 | 
								switch (opt) {
 | 
				
			||||||
 | 
								default:
 | 
				
			||||||
 | 
									goto usage;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							argc -= optind;
 | 
				
			||||||
 | 
							argv += optind;
 | 
				
			||||||
 | 
							if (argc != 0)
 | 
				
			||||||
 | 
								goto usage;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cmd = xmalloc(sizeof *cmd);
 | 
				
			||||||
 | 
						cmd->entry = entry;
 | 
				
			||||||
 | 
						cmd->data = NULL;
 | 
				
			||||||
 | 
						if (entry->parse != NULL) {
 | 
				
			||||||
 | 
							if (entry->parse(cmd, argc, argv, cause) != 0) {
 | 
				
			||||||
 | 
								xfree(cmd);
 | 
				
			||||||
 | 
								return (NULL);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return (cmd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ambiguous:
 | 
				
			||||||
 | 
						*s = '\0';
 | 
				
			||||||
 | 
						for (entryp = cmd_table; *entryp != NULL; entryp++) {
 | 
				
			||||||
 | 
							if (strncmp((*entryp)->name, argv[0], strlen(argv[0])) != 0)
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							if (strlcat(s, (*entryp)->name, sizeof s) >= sizeof s)
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							if (strlcat(s, ", ", sizeof s) >= sizeof s)
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						s[strlen(s) - 2] = '\0';
 | 
				
			||||||
 | 
						xasprintf(cause, "ambiguous command: %s, could be: %s", argv[0], s);
 | 
				
			||||||
 | 
						return (NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					usage:
 | 
				
			||||||
 | 
						xasprintf(cause, "usage: %s %s", entry->name, entry->usage);
 | 
				
			||||||
 | 
						return (NULL);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					cmd_exec(struct cmd *cmd, struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (server_locked) {
 | 
				
			||||||
 | 
							ctx->error(ctx, "server is locked");
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return (cmd->entry->exec(cmd, ctx));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_send(struct cmd *cmd, struct buffer *b)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const struct cmd_entry **entryp;
 | 
				
			||||||
 | 
						u_int			 n;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						n = 0;
 | 
				
			||||||
 | 
						for (entryp = cmd_table; *entryp != NULL; entryp++) {
 | 
				
			||||||
 | 
							if (*entryp == cmd->entry)
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							n++;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (*entryp == NULL)
 | 
				
			||||||
 | 
							fatalx("command not found");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						buffer_write(b, &n, sizeof n);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (cmd->entry->send != NULL)
 | 
				
			||||||
 | 
							cmd->entry->send(cmd, b);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct cmd *
 | 
				
			||||||
 | 
					cmd_recv(struct buffer *b)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const struct cmd_entry **entryp;
 | 
				
			||||||
 | 
						struct cmd   	        *cmd;
 | 
				
			||||||
 | 
						u_int			 m, n;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						buffer_read(b, &m, sizeof m);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						n = 0;
 | 
				
			||||||
 | 
						for (entryp = cmd_table; *entryp != NULL; entryp++) {
 | 
				
			||||||
 | 
							if (n == m)
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							n++;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (*entryp == NULL)
 | 
				
			||||||
 | 
							fatalx("command not found");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cmd = xmalloc(sizeof *cmd);
 | 
				
			||||||
 | 
						cmd->entry = *entryp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (cmd->entry->recv != NULL)
 | 
				
			||||||
 | 
							cmd->entry->recv(cmd, b);
 | 
				
			||||||
 | 
						return (cmd);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_free(struct cmd *cmd)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (cmd->data != NULL && cmd->entry->free != NULL)
 | 
				
			||||||
 | 
							cmd->entry->free(cmd);
 | 
				
			||||||
 | 
						xfree(cmd);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					size_t
 | 
				
			||||||
 | 
					cmd_print(struct cmd *cmd, char *buf, size_t len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (cmd->entry->print == NULL) {
 | 
				
			||||||
 | 
							return (xsnprintf(buf, len, "%s", cmd->entry->name));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return (cmd->entry->print(cmd, buf, len));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					cmd_send_string(struct buffer *b, const char *s)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						size_t	n;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (s == NULL) {
 | 
				
			||||||
 | 
							n = 0;
 | 
				
			||||||
 | 
							buffer_write(b, &n, sizeof n);
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						n = strlen(s) + 1;
 | 
				
			||||||
 | 
						buffer_write(b, &n, sizeof n);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						buffer_write(b, s, n);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					char *
 | 
				
			||||||
 | 
					cmd_recv_string(struct buffer *b)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char   *s;
 | 
				
			||||||
 | 
						size_t	n;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						buffer_read(b, &n, sizeof n);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (n == 0)
 | 
				
			||||||
 | 
							return (NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						s = xmalloc(n);
 | 
				
			||||||
 | 
						buffer_read(b, s, n);
 | 
				
			||||||
 | 
						s[n - 1] = '\0';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (s);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct session *
 | 
				
			||||||
 | 
					cmd_current_session(struct cmd_ctx *ctx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct msg_command_data	*data = ctx->msgdata;
 | 
				
			||||||
 | 
						struct timeval		*tv;
 | 
				
			||||||
 | 
						struct session		*s, *newest = NULL;
 | 
				
			||||||
 | 
						u_int			 i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (ctx->cursession != NULL)
 | 
				
			||||||
 | 
							return (ctx->cursession);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (data != NULL && data->pid != -1) {
 | 
				
			||||||
 | 
							if (data->pid != getpid()) {
 | 
				
			||||||
 | 
								ctx->error(ctx, "wrong server: %ld", (long) data->pid);
 | 
				
			||||||
 | 
								return (NULL);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (data->idx > ARRAY_LENGTH(&sessions)) {
 | 
				
			||||||
 | 
								ctx->error(ctx, "index out of range: %d", data->idx);
 | 
				
			||||||
 | 
								return (NULL);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if ((s = ARRAY_ITEM(&sessions, data->idx)) == NULL) {
 | 
				
			||||||
 | 
								ctx->error(ctx, "session doesn't exist: %u", data->idx);
 | 
				
			||||||
 | 
								return (NULL);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return (s);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tv = NULL;
 | 
				
			||||||
 | 
						for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
 | 
				
			||||||
 | 
							s = ARRAY_ITEM(&sessions, i);
 | 
				
			||||||
 | 
							if (s != NULL && (tv == NULL || timercmp(&s->tv, tv, >))) {
 | 
				
			||||||
 | 
								newest = ARRAY_ITEM(&sessions, i);
 | 
				
			||||||
 | 
								tv = &s->tv;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return (newest);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct client *
 | 
				
			||||||
 | 
					cmd_find_client(struct cmd_ctx *ctx, const char *arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct client	*c;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (arg == NULL)
 | 
				
			||||||
 | 
							c = ctx->curclient;
 | 
				
			||||||
 | 
						else {
 | 
				
			||||||
 | 
							if ((c = arg_parse_client(arg)) == NULL) {
 | 
				
			||||||
 | 
								if (arg != NULL)
 | 
				
			||||||
 | 
									ctx->error(ctx, "client not found: %s", arg);
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
									ctx->error(ctx, "no client found");
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return (c);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct session *
 | 
				
			||||||
 | 
					cmd_find_session(struct cmd_ctx *ctx, const char *arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct session	*s;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (arg == NULL)
 | 
				
			||||||
 | 
							s = cmd_current_session(ctx);
 | 
				
			||||||
 | 
						else {
 | 
				
			||||||
 | 
							if ((s = arg_parse_session(arg)) == NULL) {
 | 
				
			||||||
 | 
								if (arg != NULL)
 | 
				
			||||||
 | 
									ctx->error(ctx, "session not found: %s", arg);
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
									ctx->error(ctx, "no session found");
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return (s);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct winlink *
 | 
				
			||||||
 | 
					cmd_find_window(struct cmd_ctx *ctx, const char *arg, struct session **sp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct session	*s;
 | 
				
			||||||
 | 
						struct winlink	*wl;
 | 
				
			||||||
 | 
						int		 idx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wl = NULL;
 | 
				
			||||||
 | 
						if (arg_parse_window(arg, &s, &idx) != 0) {
 | 
				
			||||||
 | 
							ctx->error(ctx, "bad window: %s", arg);
 | 
				
			||||||
 | 
							return (NULL);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (s == NULL)
 | 
				
			||||||
 | 
							s = ctx->cursession;
 | 
				
			||||||
 | 
						if (s == NULL)
 | 
				
			||||||
 | 
							s = cmd_current_session(ctx);
 | 
				
			||||||
 | 
						if (s == NULL)
 | 
				
			||||||
 | 
							return (NULL);
 | 
				
			||||||
 | 
						if (sp != NULL)
 | 
				
			||||||
 | 
							*sp = s;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (idx == -1)
 | 
				
			||||||
 | 
							wl = s->curw;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							wl = winlink_find_by_index(&s->windows, idx);
 | 
				
			||||||
 | 
						if (wl == NULL)
 | 
				
			||||||
 | 
							ctx->error(ctx, "window not found: %s:%d", s->name, idx);
 | 
				
			||||||
 | 
						return (wl);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										123
									
								
								colour.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								colour.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,123 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const char *
 | 
				
			||||||
 | 
					colour_tostring(u_char c)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						switch (c) {
 | 
				
			||||||
 | 
						case 0:
 | 
				
			||||||
 | 
							return ("black");
 | 
				
			||||||
 | 
						case 1:
 | 
				
			||||||
 | 
							return ("red");
 | 
				
			||||||
 | 
						case 2:
 | 
				
			||||||
 | 
							return ("green");
 | 
				
			||||||
 | 
						case 3:
 | 
				
			||||||
 | 
							return ("yellow");
 | 
				
			||||||
 | 
						case 4:
 | 
				
			||||||
 | 
							return ("blue");
 | 
				
			||||||
 | 
						case 5:
 | 
				
			||||||
 | 
							return ("magenta");
 | 
				
			||||||
 | 
						case 6:
 | 
				
			||||||
 | 
							return ("cyan");
 | 
				
			||||||
 | 
						case 7:
 | 
				
			||||||
 | 
							return ("white");
 | 
				
			||||||
 | 
						case 8:
 | 
				
			||||||
 | 
							return ("default");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return (NULL);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					colour_fromstring(const char *s)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (strcasecmp(s, "black") == 0 || (s[0] == '0' && s[1] == '\0'))
 | 
				
			||||||
 | 
							return (0);
 | 
				
			||||||
 | 
						if (strcasecmp(s, "red") == 0 || (s[0] == '1' && s[1] == '\0'))
 | 
				
			||||||
 | 
							return (1);
 | 
				
			||||||
 | 
						if (strcasecmp(s, "green") == 0 || (s[0] == '2' && s[1] == '\0'))
 | 
				
			||||||
 | 
							return (2);
 | 
				
			||||||
 | 
						if (strcasecmp(s, "yellow") == 0 || (s[0] == '3' && s[1] == '\0'))
 | 
				
			||||||
 | 
							return (3);
 | 
				
			||||||
 | 
						if (strcasecmp(s, "blue") == 0 || (s[0] == '4' && s[1] == '\0'))
 | 
				
			||||||
 | 
							return (4);
 | 
				
			||||||
 | 
						if (strcasecmp(s, "magenta") == 0 || (s[0] == '5' && s[1] == '\0'))
 | 
				
			||||||
 | 
							return (5);
 | 
				
			||||||
 | 
						if (strcasecmp(s, "cyan") == 0 || (s[0] == '6' && s[1] == '\0'))
 | 
				
			||||||
 | 
							return (6);
 | 
				
			||||||
 | 
						if (strcasecmp(s, "white") == 0 || (s[0] == '7' && s[1] == '\0'))
 | 
				
			||||||
 | 
							return (7);
 | 
				
			||||||
 | 
						if (strcasecmp(s, "default") == 0 || (s[0] == '8' && s[1] == '\0'))
 | 
				
			||||||
 | 
							return (8);
 | 
				
			||||||
 | 
						return (-1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u_char
 | 
				
			||||||
 | 
					colour_256to16(u_char c)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						static const u_char table[256] = {
 | 
				
			||||||
 | 
							 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
 | 
				
			||||||
 | 
							 0,  4,  4,  4, 12, 12,  2,  6,  4,  4, 12, 12,  2,  2,  6,  4,
 | 
				
			||||||
 | 
							12, 12,  2,  2,  2,  6, 12, 12, 10, 10, 10, 10, 14, 12, 10, 10,
 | 
				
			||||||
 | 
							10, 10, 10, 14,  1,  5,  4,  4, 12, 12,  3,  8,  4,  4, 12, 12,
 | 
				
			||||||
 | 
							 2,  2,  6,  4, 12, 12,  2,  2,  2,  6, 12, 12, 10, 10, 10, 10,
 | 
				
			||||||
 | 
							14, 12, 10, 10, 10, 10, 10, 14,  1,  1,  5,  4, 12, 12,  1,  1,
 | 
				
			||||||
 | 
							 5,  4, 12, 12,  3,  3,  8,  4, 12, 12,  2,  2,  2,  6, 12, 12,
 | 
				
			||||||
 | 
							10, 10, 10, 10, 14, 12, 10, 10, 10, 10, 10, 14,  1,  1,  1,  5,
 | 
				
			||||||
 | 
							12, 12,  1,  1,  1,  5, 12, 12,  1,  1,  1,  5, 12, 12,  3,  3,
 | 
				
			||||||
 | 
							 3,  7, 12, 12, 10, 10, 10, 10, 14, 12, 10, 10, 10, 10, 10, 14,
 | 
				
			||||||
 | 
							 9,  9,  9,  9, 13, 12,  9,  9,  9,  9, 13, 12,  9,  9,  9,  9,
 | 
				
			||||||
 | 
							13, 12,  9,  9,  9,  9, 13, 12, 11, 11, 11, 11,  7, 12, 10, 10,
 | 
				
			||||||
 | 
							10, 10, 10, 14,  9,  9,  9,  9,  9, 13,  9,  9,  9,  9,  9, 13,
 | 
				
			||||||
 | 
							 9,  9,  9,  9,  9, 13,  9,  9,  9,  9,  9, 13,  9,  9,  9,  9,
 | 
				
			||||||
 | 
							 9, 13, 11, 11, 11, 11, 11, 15,  0,  0,  0,  0,  0,  0,  8,  8,
 | 
				
			||||||
 | 
							 8,  8,  8,  8,  7,  7,  7,  7,  7,  7, 15, 15, 15, 15, 15, 15
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (table[c]);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u_char
 | 
				
			||||||
 | 
					colour_256to88(u_char c)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						static const u_char table[256] = {
 | 
				
			||||||
 | 
							 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
 | 
				
			||||||
 | 
							16, 17, 17, 18, 18, 19, 20, 21, 21, 22, 22, 23, 20, 21, 21, 22,
 | 
				
			||||||
 | 
							22, 23, 24, 25, 25, 26, 26, 27, 24, 25, 25, 26, 26, 27, 28, 29,
 | 
				
			||||||
 | 
							29, 30, 30, 31, 32, 33, 33, 34, 34, 35, 36, 37, 37, 38, 38, 39,
 | 
				
			||||||
 | 
							36, 37, 37, 38, 38, 39, 40, 41, 41, 42, 42, 43, 40, 41, 41, 42,
 | 
				
			||||||
 | 
							42, 43, 44, 45, 45, 46, 46, 47, 32, 33, 33, 34, 34, 35, 36, 37,
 | 
				
			||||||
 | 
							37, 38, 38, 39, 36, 37, 37, 38, 38, 39, 40, 41, 41, 42, 42, 43,
 | 
				
			||||||
 | 
							40, 41, 41, 42, 42, 43, 44, 45, 45, 46, 46, 47, 48, 49, 49, 50,
 | 
				
			||||||
 | 
							50, 51, 52, 53, 53, 54, 54, 55, 52, 53, 53, 54, 54, 55, 56, 57,
 | 
				
			||||||
 | 
							57, 58, 58, 59, 56, 57, 57, 58, 58, 59, 60, 61, 61, 62, 62, 63,
 | 
				
			||||||
 | 
							48, 49, 49, 50, 50, 51, 52, 53, 53, 54, 54, 55, 52, 53, 53, 54,
 | 
				
			||||||
 | 
							54, 55, 56, 57, 57, 58, 58, 59, 56, 57, 57, 58, 58, 59, 60, 61,
 | 
				
			||||||
 | 
							61, 62, 62, 63, 64, 65, 65, 66, 66, 67, 68, 69, 69, 70, 70, 71,
 | 
				
			||||||
 | 
							68, 69, 69, 70, 70, 71, 72, 73, 73, 74, 74, 75, 72, 73, 73, 74,
 | 
				
			||||||
 | 
							74, 75, 76, 77, 77, 78, 78, 79,  0,  0, 80, 80, 80, 81, 81, 81,
 | 
				
			||||||
 | 
							82, 82, 82, 83, 83, 83, 84, 84, 84, 85, 85, 85, 86, 86, 86, 87
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (table[c]);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										211
									
								
								grid-view.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										211
									
								
								grid-view.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,211 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Grid view functions. These work using coordinates relative to the visible
 | 
				
			||||||
 | 
					 * screen area.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define grid_view_x(gd, x) (x)
 | 
				
			||||||
 | 
					#define grid_view_y(gd, y) ((gd)->hsize + (y))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Get cell for reading. */
 | 
				
			||||||
 | 
					const struct grid_cell *
 | 
				
			||||||
 | 
					grid_view_peek_cell(struct grid *gd, u_int px, u_int py)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return (grid_peek_cell(gd, grid_view_x(gd, px), grid_view_y(gd, py)));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Get cell for writing. */
 | 
				
			||||||
 | 
					struct grid_cell *
 | 
				
			||||||
 | 
					grid_view_get_cell(struct grid *gd, u_int px, u_int py)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return (grid_get_cell(gd, grid_view_x(gd, px), grid_view_y(gd, py)));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Set cell. */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					grid_view_set_cell(
 | 
				
			||||||
 | 
					    struct grid *gd, u_int px, u_int py, const struct grid_cell *gc)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						grid_set_cell(gd, grid_view_x(gd, px), grid_view_y(gd, py), gc);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Get UTF-8 for reading. */
 | 
				
			||||||
 | 
					const struct grid_utf8 *
 | 
				
			||||||
 | 
					grid_view_peek_utf8(struct grid *gd, u_int px, u_int py)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return (grid_peek_utf8(gd, grid_view_x(gd, px), grid_view_y(gd, py)));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Get UTF-8 for writing. */
 | 
				
			||||||
 | 
					struct grid_utf8 *
 | 
				
			||||||
 | 
					grid_view_get_utf8(struct grid *gd, u_int px, u_int py)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return (grid_get_utf8(gd, grid_view_x(gd, px), grid_view_y(gd, py)));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Set UTF-8. */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					grid_view_set_utf8(
 | 
				
			||||||
 | 
					    struct grid *gd, u_int px, u_int py, const struct grid_utf8 *gu)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						grid_set_utf8(gd, grid_view_x(gd, px), grid_view_y(gd, py), gu);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Clear area. */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					grid_view_clear(struct grid *gd, u_int px, u_int py, u_int nx, u_int ny)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						GRID_DEBUG(gd, "px=%u, py=%u, nx=%u, ny=%u", px, py, nx, ny);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						px = grid_view_x(gd, px);
 | 
				
			||||||
 | 
						py = grid_view_y(gd, py);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						grid_clear(gd, px, py, nx, ny);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Scroll region up. */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					grid_view_scroll_region_up(struct grid *gd, u_int rupper, u_int rlower)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						GRID_DEBUG(gd, "rupper=%u, rlower=%u", rupper, rlower);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (rupper == 0 && rlower == gd->sy - 1) {
 | 
				
			||||||
 | 
							grid_scroll_line(gd);
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rupper = grid_view_y(gd, rupper);
 | 
				
			||||||
 | 
						rlower = grid_view_y(gd, rlower);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						grid_move_lines(gd, rupper, rupper + 1, rlower - rupper);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Scroll region down. */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					grid_view_scroll_region_down(struct grid *gd, u_int rupper, u_int rlower)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						GRID_DEBUG(gd, "rupper=%u, rlower=%u", rupper, rlower);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rupper = grid_view_y(gd, rupper);
 | 
				
			||||||
 | 
						rlower = grid_view_y(gd, rlower);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						grid_move_lines(gd, rupper + 1, rupper, rlower - rupper);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Insert lines. */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					grid_view_insert_lines(struct grid *gd, u_int py, u_int ny)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u_int	sy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						GRID_DEBUG(gd, "py=%u, ny=%u", py, ny);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						py = grid_view_y(gd, py);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sy = grid_view_y(gd, gd->sy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						grid_move_lines(gd, py + ny, py, sy - py - ny);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Insert lines in region. */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					grid_view_insert_lines_region(
 | 
				
			||||||
 | 
					    struct grid *gd, unused u_int rupper, u_int rlower, u_int py, u_int ny)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						GRID_DEBUG(
 | 
				
			||||||
 | 
						    gd, "rupper=%u, rlower=%u, py=%u, ny=%u", rupper, rlower, py, ny);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rlower = grid_view_y(gd, rlower);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						py = grid_view_y(gd, py);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						grid_move_lines(gd, py + ny, py, (rlower + 1) - py - ny);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Delete lines. */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					grid_view_delete_lines(struct grid *gd, u_int py, u_int ny)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u_int	sy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						GRID_DEBUG(gd, "py=%u, ny=%u", py, ny);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						py = grid_view_y(gd, py);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sy = grid_view_y(gd, gd->sy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						grid_move_lines(gd, py, py + ny, sy - py - ny);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Delete lines inside scroll region. */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					grid_view_delete_lines_region(
 | 
				
			||||||
 | 
					    struct grid *gd, unused u_int rupper, u_int rlower, u_int py, u_int ny)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						GRID_DEBUG(
 | 
				
			||||||
 | 
						    gd, "rupper=%u, rlower=%u, py=%u, ny=%u", rupper, rlower, py, ny);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rlower = grid_view_y(gd, rlower);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						py = grid_view_y(gd, py);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						grid_move_lines(gd, py, py + ny, (rlower + 1) - py - ny);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Insert characters. */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					grid_view_insert_cells(struct grid *gd, u_int px, u_int py, u_int nx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u_int	sx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						GRID_DEBUG(gd, "px=%u, py=%u, nx=%u", px, py, nx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						px = grid_view_x(gd, px);
 | 
				
			||||||
 | 
						py = grid_view_y(gd, py);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sx = grid_view_x(gd, gd->sx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (px == sx - 1)
 | 
				
			||||||
 | 
							grid_clear(gd, px, py, 1, 1);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							grid_move_cells(gd, px + nx, px, py, (sx - 1) - (px + nx));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Delete characters. */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					grid_view_delete_cells(struct grid *gd, u_int px, u_int py, u_int nx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u_int	sx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						GRID_DEBUG(gd, "px=%u, py=%u, nx=%u", px, py, nx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						px = grid_view_x(gd, px);
 | 
				
			||||||
 | 
						py = grid_view_y(gd, py);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sx = grid_view_x(gd, gd->sx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						grid_move_cells(gd, px, px + nx, py, (sx - 1) - (px + nx));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										497
									
								
								grid.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										497
									
								
								grid.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,497 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Grid data. This is the basic data structure that represents what is shown on
 | 
				
			||||||
 | 
					 * screen.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * A grid is a grid of cells (struct grid_cell). Lines are not allocated until
 | 
				
			||||||
 | 
					 * cells in that line are written to. The grid is split into history and
 | 
				
			||||||
 | 
					 * viewable data with the history starting at row (line) 0 and extending to
 | 
				
			||||||
 | 
					 * (hsize - 1); from hsize to hsize + (sy - 1) is the viewable data. All
 | 
				
			||||||
 | 
					 * functions in this file work on absolute coordinates, grid-view.c has
 | 
				
			||||||
 | 
					 * functions which work on the screen data.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Default grid cell data. */
 | 
				
			||||||
 | 
					const struct grid_cell grid_default_cell = { 0, 0, 8, 8, ' ' };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define grid_put_cell(gd, px, py, gc) do {			\
 | 
				
			||||||
 | 
						memcpy(&gd->data[py][px], gc, sizeof gd->data[py][px]);	\
 | 
				
			||||||
 | 
					} while (0)
 | 
				
			||||||
 | 
					#define grid_put_utf8(gd, px, py, gc) do {			\
 | 
				
			||||||
 | 
						memcpy(&gd->udata[py][px], gc, sizeof gd->udata[py][px]); \
 | 
				
			||||||
 | 
					} while (0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	grid_check_x(struct grid *, u_int);
 | 
				
			||||||
 | 
					int	grid_check_y(struct grid *, u_int);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef DEBUG
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					grid_check_x(struct grid *gd, u_int px)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if ((px) >= (gd)->sx)
 | 
				
			||||||
 | 
							log_fatalx("x out of range: %u", px);
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					grid_check_y(struct grid *gd, u_int py)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if ((py) >= (gd)->hsize + (gd)->sy)
 | 
				
			||||||
 | 
							log_fatalx("y out of range: %u", py);
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					grid_check_x(struct grid *gd, u_int px)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if ((px) >= (gd)->sx) {
 | 
				
			||||||
 | 
							log_debug("x out of range: %u", px);
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					grid_check_y(struct grid *gd, u_int py)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if ((py) >= (gd)->hsize + (gd)->sy) {
 | 
				
			||||||
 | 
							log_debug("y out of range: %u", py);
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Create a new grid. */
 | 
				
			||||||
 | 
					struct grid *
 | 
				
			||||||
 | 
					grid_create(u_int sx, u_int sy, u_int hlimit)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct grid	*gd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						gd = xmalloc(sizeof *gd);
 | 
				
			||||||
 | 
						gd->sx = sx;
 | 
				
			||||||
 | 
						gd->sy = sy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						gd->hsize = 0;
 | 
				
			||||||
 | 
						gd->hlimit = hlimit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						gd->size = xcalloc(gd->sy, sizeof *gd->size);
 | 
				
			||||||
 | 
						gd->data = xcalloc(gd->sy, sizeof *gd->data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						gd->usize = xcalloc(gd->sy, sizeof *gd->usize);
 | 
				
			||||||
 | 
						gd->udata = xcalloc(gd->sy, sizeof *gd->udata);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (gd);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Destroy grid. */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					grid_destroy(struct grid *gd)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u_int	yy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (yy = 0; yy < gd->hsize + gd->sy; yy++) {
 | 
				
			||||||
 | 
							if (gd->udata[yy] != NULL)
 | 
				
			||||||
 | 
								xfree(gd->udata[yy]);
 | 
				
			||||||
 | 
							if (gd->data[yy] != NULL)
 | 
				
			||||||
 | 
								xfree(gd->data[yy]);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (gd->udata != NULL)
 | 
				
			||||||
 | 
							xfree(gd->udata);
 | 
				
			||||||
 | 
						if (gd->usize != NULL)
 | 
				
			||||||
 | 
							xfree(gd->usize);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (gd->data != NULL)
 | 
				
			||||||
 | 
							xfree(gd->data);
 | 
				
			||||||
 | 
						if (gd->size != NULL)
 | 
				
			||||||
 | 
							xfree(gd->size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						xfree(gd);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Compare grids. */
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					grid_compare(struct grid *ga, struct grid *gb)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct grid_cell	*gca, *gcb;
 | 
				
			||||||
 | 
						struct grid_utf8	*gua, *gub;
 | 
				
			||||||
 | 
						u_int			 xx, yy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (ga->sx != gb->sx || ga->sy != ga->sy)
 | 
				
			||||||
 | 
							return (1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (yy = 0; yy < ga->sy; yy++) {
 | 
				
			||||||
 | 
							if (ga->size[yy] != gb->size[yy])
 | 
				
			||||||
 | 
								return (1);
 | 
				
			||||||
 | 
							for (xx = 0; xx < ga->sx; xx++) {
 | 
				
			||||||
 | 
								gca = &ga->data[yy][xx];
 | 
				
			||||||
 | 
								gcb = &gb->data[yy][xx];
 | 
				
			||||||
 | 
								if (memcmp(gca, gcb, sizeof (struct grid_cell)) != 0)
 | 
				
			||||||
 | 
									return (1);
 | 
				
			||||||
 | 
								if (!(gca->flags & GRID_FLAG_UTF8))
 | 
				
			||||||
 | 
									continue;
 | 
				
			||||||
 | 
								gua = &ga->udata[yy][xx];
 | 
				
			||||||
 | 
								gub = &gb->udata[yy][xx];
 | 
				
			||||||
 | 
								if (memcmp(gua, gub, sizeof (struct grid_utf8)) != 0)
 | 
				
			||||||
 | 
									return (1);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Scroll a line into the history. */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					grid_scroll_line(struct grid *gd)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u_int	yy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 	GRID_DEBUG(gd, "");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (gd->hsize >= gd->hlimit - 1) {
 | 
				
			||||||
 | 
							/* If the limit is hit, free the bottom 10% and shift up. */
 | 
				
			||||||
 | 
							yy = gd->hlimit / 10;
 | 
				
			||||||
 | 
							if (yy < 1)
 | 
				
			||||||
 | 
								yy = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							grid_move_lines(gd, 0, yy, gd->hsize + gd->sy - yy);
 | 
				
			||||||
 | 
							gd->hsize -= yy;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						yy = gd->hsize + gd->sy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						gd->size = xrealloc(gd->size, yy + 1, sizeof *gd->size);
 | 
				
			||||||
 | 
						gd->size[yy] = 0;
 | 
				
			||||||
 | 
						gd->data = xrealloc(gd->data, yy + 1, sizeof *gd->data);
 | 
				
			||||||
 | 
						gd->data[yy] = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						gd->usize = xrealloc(gd->usize, yy + 1, sizeof *gd->usize);
 | 
				
			||||||
 | 
						gd->usize[yy] = 0;
 | 
				
			||||||
 | 
						gd->udata = xrealloc(gd->udata, yy + 1, sizeof *gd->udata);
 | 
				
			||||||
 | 
						gd->udata[yy] = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						gd->hsize++;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Reduce line to fit to cell. */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					grid_reduce_line(struct grid *gd, u_int py, u_int sx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (sx < gd->size[py]) {
 | 
				
			||||||
 | 
							gd->data[py] = xrealloc(gd->data[py], sx, sizeof **gd->data);
 | 
				
			||||||
 | 
							gd->size[py] = sx;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (sx < gd->usize[py]) {
 | 
				
			||||||
 | 
							gd->udata[py] = xrealloc(gd->udata[py], sx, sizeof **gd->udata);
 | 
				
			||||||
 | 
							gd->usize[py] = sx;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Expand line to fit to cell. */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					grid_expand_line(struct grid *gd, u_int py, u_int sx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u_int	xx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (sx <= gd->size[py])
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						gd->data[py] = xrealloc(gd->data[py], sx, sizeof **gd->data);
 | 
				
			||||||
 | 
						for (xx = gd->size[py]; xx < sx; xx++)
 | 
				
			||||||
 | 
							grid_put_cell(gd, xx, py, &grid_default_cell);
 | 
				
			||||||
 | 
						gd->size[py] = sx;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Expand line to fit to cell for UTF-8. */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					grid_expand_line_utf8(struct grid *gd, u_int py, u_int sx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (sx <= gd->usize[py])
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						gd->udata[py] = xrealloc(gd->udata[py], sx, sizeof **gd->udata);
 | 
				
			||||||
 | 
						gd->usize[py] = sx;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Get cell for reading. */
 | 
				
			||||||
 | 
					const struct grid_cell *
 | 
				
			||||||
 | 
					grid_peek_cell(struct grid *gd, u_int px, u_int py)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (grid_check_x(gd, px) != 0)
 | 
				
			||||||
 | 
							return (&grid_default_cell);
 | 
				
			||||||
 | 
						if (grid_check_y(gd, py) != 0)
 | 
				
			||||||
 | 
							return (&grid_default_cell);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (px >= gd->size[py])
 | 
				
			||||||
 | 
							return (&grid_default_cell);
 | 
				
			||||||
 | 
						return (&gd->data[py][px]);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Get cell at relative position (for writing). */
 | 
				
			||||||
 | 
					struct grid_cell *
 | 
				
			||||||
 | 
					grid_get_cell(struct grid *gd, u_int px, u_int py)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (grid_check_x(gd, px) != 0)
 | 
				
			||||||
 | 
							return (NULL);
 | 
				
			||||||
 | 
						if (grid_check_y(gd, py) != 0)
 | 
				
			||||||
 | 
							return (NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						grid_expand_line(gd, py, px + 1);
 | 
				
			||||||
 | 
						return (&gd->data[py][px]);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Set cell at relative position. */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					grid_set_cell(
 | 
				
			||||||
 | 
					    struct grid *gd, u_int px, u_int py, const struct grid_cell *gc)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (grid_check_x(gd, px) != 0)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						if (grid_check_y(gd, py) != 0)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						grid_expand_line(gd, py, px + 1);
 | 
				
			||||||
 | 
						grid_put_cell(gd, px, py, gc);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Get UTF-8 for reading. */
 | 
				
			||||||
 | 
					const struct grid_utf8 *
 | 
				
			||||||
 | 
					grid_peek_utf8(struct grid *gd, u_int px, u_int py)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (grid_check_x(gd, px) != 0)
 | 
				
			||||||
 | 
							return (NULL);
 | 
				
			||||||
 | 
						if (grid_check_y(gd, py) != 0)
 | 
				
			||||||
 | 
							return (NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (px >= gd->usize[py])
 | 
				
			||||||
 | 
							return (NULL);
 | 
				
			||||||
 | 
						return (&gd->udata[py][px]);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Get utf8 at relative position (for writing). */
 | 
				
			||||||
 | 
					struct grid_utf8 *
 | 
				
			||||||
 | 
					grid_get_utf8(struct grid *gd, u_int px, u_int py)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (grid_check_x(gd, px) != 0)
 | 
				
			||||||
 | 
							return (NULL);
 | 
				
			||||||
 | 
						if (grid_check_y(gd, py) != 0)
 | 
				
			||||||
 | 
							return (NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						grid_expand_line_utf8(gd, py, px + 1);
 | 
				
			||||||
 | 
						return (&gd->udata[py][px]);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Set utf8 at relative position. */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					grid_set_utf8(
 | 
				
			||||||
 | 
					    struct grid *gd, u_int px, u_int py, const struct grid_utf8 *gc)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (grid_check_x(gd, px) != 0)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						if (grid_check_y(gd, py) != 0)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						grid_expand_line_utf8(gd, py, px + 1);
 | 
				
			||||||
 | 
						grid_put_utf8(gd, px, py, gc);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Clear area. Note this is different from a fill as it just omits unallocated
 | 
				
			||||||
 | 
					 * cells.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					grid_clear(struct grid *gd, u_int px, u_int py, u_int nx, u_int ny)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u_int	xx, yy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 	GRID_DEBUG(gd, "px=%u, py=%u, nx=%u, ny=%u", px, py, nx, ny);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (nx == 0 || ny == 0)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (px == 0 && nx == gd->sx) {
 | 
				
			||||||
 | 
							grid_clear_lines(gd, py, ny);
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (grid_check_x(gd, px) != 0)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						if (grid_check_x(gd, px + nx - 1) != 0)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						if (grid_check_y(gd, py) != 0)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						if (grid_check_y(gd, py + ny - 1) != 0)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (yy = py; yy < py + ny; yy++) {
 | 
				
			||||||
 | 
							for (xx = px; xx < px + nx; xx++) {
 | 
				
			||||||
 | 
								if (xx >= gd->size[yy])
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								grid_put_cell(gd, xx, yy, &grid_default_cell);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Clear lines. This just frees and truncates the lines. */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					grid_clear_lines(struct grid *gd, u_int py, u_int ny)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u_int	yy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 	GRID_DEBUG(gd, "py=%u, ny=%u", py, ny);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (ny == 0)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (grid_check_y(gd, py) != 0)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						if (grid_check_y(gd, py + ny - 1) != 0)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (yy = py; yy < py + ny; yy++) {
 | 
				
			||||||
 | 
							if (gd->data[yy] != NULL) {
 | 
				
			||||||
 | 
								xfree(gd->data[yy]);
 | 
				
			||||||
 | 
								gd->data[yy] = NULL;
 | 
				
			||||||
 | 
								gd->size[yy] = 0;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (gd->udata[yy] != NULL) {
 | 
				
			||||||
 | 
								xfree(gd->udata[yy]);
 | 
				
			||||||
 | 
								gd->udata[yy] = NULL;
 | 
				
			||||||
 | 
								gd->usize[yy] = 0;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Move a group of lines. */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					grid_move_lines(struct grid *gd, u_int dy, u_int py, u_int ny)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u_int	yy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 	GRID_DEBUG(gd, "dy=%u, py=%u, ny=%u", dy, py, ny);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (ny == 0 || py == dy)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (grid_check_y(gd, py) != 0)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						if (grid_check_y(gd, py + ny - 1) != 0)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						if (grid_check_y(gd, dy) != 0)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						if (grid_check_y(gd, dy + ny - 1) != 0)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Free any lines which are being replaced. */
 | 
				
			||||||
 | 
						for (yy = dy; yy < dy + ny; yy++) {
 | 
				
			||||||
 | 
							if (yy >= py && yy < py + ny)
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							grid_clear_lines(gd, yy, 1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						memmove(&gd->data[dy], &gd->data[py], ny * (sizeof *gd->data));
 | 
				
			||||||
 | 
						memmove(&gd->size[dy], &gd->size[py], ny * (sizeof *gd->size));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						memmove(&gd->udata[dy], &gd->udata[py], ny * (sizeof *gd->udata));
 | 
				
			||||||
 | 
						memmove(&gd->usize[dy], &gd->usize[py], ny * (sizeof *gd->usize));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Wipe any lines that have been moved (without freeing them). */
 | 
				
			||||||
 | 
						for (yy = py; yy < py + ny; yy++) {
 | 
				
			||||||
 | 
							if (yy >= dy && yy < dy + ny)
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							gd->data[yy] = NULL;
 | 
				
			||||||
 | 
							gd->size[yy] = 0;
 | 
				
			||||||
 | 
							gd->udata[yy] = NULL;
 | 
				
			||||||
 | 
							gd->usize[yy] = 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Clear a group of cells. */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					grid_clear_cells(struct grid *gd, u_int px, u_int py, u_int nx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u_int	xx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 	GRID_DEBUG(gd, "px=%u, py=%u, nx=%u", px, py, nx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (nx == 0)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (grid_check_x(gd, px) != 0)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						if (grid_check_x(gd, px + nx - 1) != 0)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						if (grid_check_y(gd, py) != 0)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (xx = px; xx < px + nx; xx++) {
 | 
				
			||||||
 | 
							if (xx >= gd->size[py])
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							grid_put_cell(gd, xx, py, &grid_default_cell);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Move a group of cells. */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					grid_move_cells(struct grid *gd, u_int dx, u_int px, u_int py, u_int nx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u_int	xx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 	GRID_DEBUG(gd, "dx=%u, px=%u, py=%u, nx=%u", dx, px, py, nx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (nx == 0 || px == dx)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (grid_check_x(gd, px) != 0)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						if (grid_check_x(gd, px + nx - 1) != 0)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						if (grid_check_x(gd, dx + nx - 1) != 0)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						if (grid_check_y(gd, py) != 0)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						grid_expand_line(gd, py, px + nx);
 | 
				
			||||||
 | 
						grid_expand_line(gd, py, dx + nx);
 | 
				
			||||||
 | 
						memmove(&gd->data[py][dx], &gd->data[py][px], nx * (sizeof **gd->data));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (gd->udata[py] != NULL) {
 | 
				
			||||||
 | 
							grid_expand_line_utf8(gd, py, px + nx);
 | 
				
			||||||
 | 
							grid_expand_line_utf8(gd, py, dx + nx);
 | 
				
			||||||
 | 
							memmove(&gd->udata[py][dx],
 | 
				
			||||||
 | 
							    &gd->udata[py][px], nx * (sizeof **gd->udata));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Wipe any cells that have been moved. */
 | 
				
			||||||
 | 
						for (xx = px; xx < px + nx; xx++) {
 | 
				
			||||||
 | 
							if (xx >= dx && xx < dx + nx)
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							grid_put_cell(gd, xx, py, &grid_default_cell);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										227
									
								
								input-keys.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										227
									
								
								input-keys.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,227 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct input_key_ent {
 | 
				
			||||||
 | 
						int		 key;
 | 
				
			||||||
 | 
						const char	*data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						int		 flags;
 | 
				
			||||||
 | 
					#define INPUTKEY_KEYPAD 0x1	/* keypad key */
 | 
				
			||||||
 | 
					#define INPUTKEY_CURSOR 0x2	/* cursor key */
 | 
				
			||||||
 | 
					#define INPUTKEY_CTRL 0x4	/* may be modified with ctrl */
 | 
				
			||||||
 | 
					#define INPUTKEY_XTERM 0x4	/* may have xterm argument appended */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct input_key_ent input_keys[] = {
 | 
				
			||||||
 | 
						/* Function keys. */
 | 
				
			||||||
 | 
						{ KEYC_F1,     "\033OP",   INPUTKEY_CTRL|INPUTKEY_XTERM },
 | 
				
			||||||
 | 
						{ KEYC_F2,     "\033OQ",   INPUTKEY_CTRL|INPUTKEY_XTERM },
 | 
				
			||||||
 | 
						{ KEYC_F3,     "\033OR",   INPUTKEY_CTRL|INPUTKEY_XTERM },
 | 
				
			||||||
 | 
						{ KEYC_F4,     "\033OS",   INPUTKEY_CTRL|INPUTKEY_XTERM },
 | 
				
			||||||
 | 
						{ KEYC_F5,     "\033[15~", INPUTKEY_CTRL|INPUTKEY_XTERM },
 | 
				
			||||||
 | 
						{ KEYC_F6,     "\033[17~", INPUTKEY_CTRL|INPUTKEY_XTERM },
 | 
				
			||||||
 | 
						{ KEYC_F7,     "\033[18~", INPUTKEY_CTRL|INPUTKEY_XTERM },
 | 
				
			||||||
 | 
						{ KEYC_F8,     "\033[19~", INPUTKEY_CTRL|INPUTKEY_XTERM },
 | 
				
			||||||
 | 
						{ KEYC_F9,     "\033[20~", INPUTKEY_CTRL|INPUTKEY_XTERM },
 | 
				
			||||||
 | 
						{ KEYC_F10,    "\033[21~", INPUTKEY_CTRL|INPUTKEY_XTERM },
 | 
				
			||||||
 | 
						{ KEYC_F11,    "\033[23~", INPUTKEY_CTRL|INPUTKEY_XTERM },
 | 
				
			||||||
 | 
						{ KEYC_F12,    "\033[24~", INPUTKEY_CTRL|INPUTKEY_XTERM },
 | 
				
			||||||
 | 
						{ KEYC_F13,    "\033[25~", INPUTKEY_CTRL|INPUTKEY_XTERM },
 | 
				
			||||||
 | 
						{ KEYC_F14,    "\033[26~", INPUTKEY_CTRL|INPUTKEY_XTERM },
 | 
				
			||||||
 | 
						{ KEYC_F15,    "\033[28~", INPUTKEY_CTRL|INPUTKEY_XTERM },
 | 
				
			||||||
 | 
						{ KEYC_F16,    "\033[29~", INPUTKEY_CTRL|INPUTKEY_XTERM },
 | 
				
			||||||
 | 
						{ KEYC_F17,    "\033[31~", INPUTKEY_CTRL|INPUTKEY_XTERM },
 | 
				
			||||||
 | 
						{ KEYC_F18,    "\033[32~", INPUTKEY_CTRL|INPUTKEY_XTERM },
 | 
				
			||||||
 | 
						{ KEYC_F19,    "\033[33~", INPUTKEY_CTRL|INPUTKEY_XTERM },
 | 
				
			||||||
 | 
						{ KEYC_F20,    "\033[34~", INPUTKEY_CTRL|INPUTKEY_XTERM },
 | 
				
			||||||
 | 
						{ KEYC_IC,     "\033[2~",  INPUTKEY_CTRL|INPUTKEY_XTERM },
 | 
				
			||||||
 | 
						{ KEYC_DC,     "\033[3~",  INPUTKEY_CTRL|INPUTKEY_XTERM },
 | 
				
			||||||
 | 
						{ KEYC_HOME,   "\033[1~",  INPUTKEY_CTRL|INPUTKEY_XTERM },
 | 
				
			||||||
 | 
						{ KEYC_END,    "\033[4~",  INPUTKEY_CTRL|INPUTKEY_XTERM },
 | 
				
			||||||
 | 
						{ KEYC_NPAGE,  "\033[6~",  INPUTKEY_CTRL|INPUTKEY_XTERM },
 | 
				
			||||||
 | 
						{ KEYC_PPAGE,  "\033[5~",  INPUTKEY_CTRL|INPUTKEY_XTERM },
 | 
				
			||||||
 | 
						{ KEYC_BTAB,   "\033[Z",   INPUTKEY_CTRL },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Arrow keys. Cursor versions must come first. */
 | 
				
			||||||
 | 
						{ KEYC_ADDCTL(KEYC_UP),    "\033Oa", 0 },
 | 
				
			||||||
 | 
						{ KEYC_ADDCTL(KEYC_DOWN),  "\033Ob", 0 },
 | 
				
			||||||
 | 
						{ KEYC_ADDCTL(KEYC_RIGHT), "\033Oc", 0 },
 | 
				
			||||||
 | 
						{ KEYC_ADDCTL(KEYC_LEFT),  "\033Od", 0 },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						{ KEYC_ADDSFT(KEYC_UP),    "\033[a", 0 },
 | 
				
			||||||
 | 
						{ KEYC_ADDSFT(KEYC_DOWN),  "\033[b", 0 },
 | 
				
			||||||
 | 
						{ KEYC_ADDSFT(KEYC_RIGHT), "\033[c", 0 },
 | 
				
			||||||
 | 
						{ KEYC_ADDSFT(KEYC_LEFT),  "\033[d", 0 },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						{ KEYC_UP,     "\033OA",   INPUTKEY_CURSOR },
 | 
				
			||||||
 | 
						{ KEYC_DOWN,   "\033OB",   INPUTKEY_CURSOR },
 | 
				
			||||||
 | 
						{ KEYC_RIGHT,  "\033OC",   INPUTKEY_CURSOR },
 | 
				
			||||||
 | 
						{ KEYC_LEFT,   "\033OD",   INPUTKEY_CURSOR },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						{ KEYC_UP,     "\033[A",   0 },
 | 
				
			||||||
 | 
						{ KEYC_DOWN,   "\033[B",   0 },
 | 
				
			||||||
 | 
						{ KEYC_RIGHT,  "\033[C",   0 },
 | 
				
			||||||
 | 
						{ KEYC_LEFT,   "\033[D",   0 },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Keypad keys. Keypad versions must come first. */
 | 
				
			||||||
 | 
						{ KEYC_KP0_1,  "/", INPUTKEY_KEYPAD },
 | 
				
			||||||
 | 
						{ KEYC_KP0_2,  "*", INPUTKEY_KEYPAD },
 | 
				
			||||||
 | 
						{ KEYC_KP0_3,  "-", INPUTKEY_KEYPAD },
 | 
				
			||||||
 | 
						{ KEYC_KP1_0,  "7", INPUTKEY_KEYPAD },
 | 
				
			||||||
 | 
						{ KEYC_KP1_1,  "8", INPUTKEY_KEYPAD },
 | 
				
			||||||
 | 
						{ KEYC_KP1_2,  "9", INPUTKEY_KEYPAD },
 | 
				
			||||||
 | 
						{ KEYC_KP1_3,  "+", INPUTKEY_KEYPAD },
 | 
				
			||||||
 | 
						{ KEYC_KP2_0,  "4", INPUTKEY_KEYPAD },
 | 
				
			||||||
 | 
						{ KEYC_KP2_1,  "5", INPUTKEY_KEYPAD },
 | 
				
			||||||
 | 
						{ KEYC_KP2_2,  "6", INPUTKEY_KEYPAD },
 | 
				
			||||||
 | 
						{ KEYC_KP3_0,  "1", INPUTKEY_KEYPAD },
 | 
				
			||||||
 | 
						{ KEYC_KP3_1,  "2", INPUTKEY_KEYPAD },
 | 
				
			||||||
 | 
						{ KEYC_KP3_2,  "3", INPUTKEY_KEYPAD },
 | 
				
			||||||
 | 
						{ KEYC_KP3_3,  "\n", INPUTKEY_KEYPAD }, /* this can be CRLF too? */
 | 
				
			||||||
 | 
						{ KEYC_KP4_0,  "0", INPUTKEY_KEYPAD },
 | 
				
			||||||
 | 
						{ KEYC_KP4_2,  ".", INPUTKEY_KEYPAD },
 | 
				
			||||||
 | 
						{ KEYC_KP0_1,  "\033Oo", 0 },
 | 
				
			||||||
 | 
						{ KEYC_KP0_2,  "\033Oj", 0 },
 | 
				
			||||||
 | 
						{ KEYC_KP0_3,  "\033Om", 0 },
 | 
				
			||||||
 | 
						{ KEYC_KP1_0,  "\033Ow", 0 },
 | 
				
			||||||
 | 
						{ KEYC_KP1_1,  "\033Ox", 0 },
 | 
				
			||||||
 | 
						{ KEYC_KP1_2,  "\033Oy", 0 },
 | 
				
			||||||
 | 
						{ KEYC_KP1_3,  "\033Ok", 0 },
 | 
				
			||||||
 | 
						{ KEYC_KP2_0,  "\033Ot", 0 },
 | 
				
			||||||
 | 
						{ KEYC_KP2_1,  "\033Ou", 0 },
 | 
				
			||||||
 | 
						{ KEYC_KP2_2,  "\033Ov", 0 },
 | 
				
			||||||
 | 
						{ KEYC_KP3_0,  "\033Oq", 0 },
 | 
				
			||||||
 | 
						{ KEYC_KP3_1,  "\033Or", 0 },
 | 
				
			||||||
 | 
						{ KEYC_KP3_2,  "\033Os", 0 },
 | 
				
			||||||
 | 
						{ KEYC_KP3_3,  "\033OM", 0 },
 | 
				
			||||||
 | 
						{ KEYC_KP4_0,  "\033Op", 0 },
 | 
				
			||||||
 | 
						{ KEYC_KP4_2,  "\033On", 0 },
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Translate a key code from client into an output key sequence. */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					input_key(struct window_pane *wp, int key)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct input_key_ent   *ike;
 | 
				
			||||||
 | 
						u_int			i;
 | 
				
			||||||
 | 
						char			ch;
 | 
				
			||||||
 | 
						size_t			dlen;
 | 
				
			||||||
 | 
						int			xterm_keys;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						log_debug2("writing key 0x%x", key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (key != KEYC_NONE && KEYC_REMOVEESC(key) < KEYC_OFFSET) {
 | 
				
			||||||
 | 
							if (KEYC_ISESC(key))
 | 
				
			||||||
 | 
								buffer_write8(wp->out, '\033');
 | 
				
			||||||
 | 
							buffer_write8(wp->out, (uint8_t) KEYC_REMOVEESC(key));
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < nitems(input_keys); i++) {
 | 
				
			||||||
 | 
							ike = &input_keys[i];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if ((ike->flags & INPUTKEY_KEYPAD) &&
 | 
				
			||||||
 | 
							    !(wp->screen->mode & MODE_KKEYPAD))
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							if ((ike->flags & INPUTKEY_CURSOR) &&
 | 
				
			||||||
 | 
							    !(wp->screen->mode & MODE_KCURSOR))
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (KEYC_ISESC(key) && KEYC_ADDESC(ike->key) == key)
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							if (KEYC_ISSFT(key) && KEYC_ADDSFT(ike->key) == key)
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							if (KEYC_ISCTL(key) && KEYC_ADDCTL(ike->key) == key) {
 | 
				
			||||||
 | 
								if (ike->flags & INPUTKEY_CTRL)
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (ike->key == key)
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (i == nitems(input_keys)) {
 | 
				
			||||||
 | 
							log_debug2("key 0x%x missing", key);
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						dlen = strlen(ike->data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						log_debug2("found key 0x%x: \"%s\"", key, ike->data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * If in xterm keys mode, work out and append the modifier as an
 | 
				
			||||||
 | 
						 * argument.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						xterm_keys = options_get_number(&wp->window->options, "xterm-keys");
 | 
				
			||||||
 | 
						if (xterm_keys && ike->flags & INPUTKEY_XTERM) {
 | 
				
			||||||
 | 
							ch = '\0';
 | 
				
			||||||
 | 
							if (KEYC_ISSFT(key) && KEYC_ISESC(key) && KEYC_ISCTL(key))
 | 
				
			||||||
 | 
								ch = '8';
 | 
				
			||||||
 | 
							else if (KEYC_ISESC(key) && KEYC_ISCTL(key))
 | 
				
			||||||
 | 
								ch = '7';
 | 
				
			||||||
 | 
							else if (KEYC_ISSFT(key) && KEYC_ISCTL(key))
 | 
				
			||||||
 | 
								ch = '6';
 | 
				
			||||||
 | 
							else if (KEYC_ISCTL(key))
 | 
				
			||||||
 | 
								ch = '5';
 | 
				
			||||||
 | 
							else if (KEYC_ISSFT(key) && KEYC_ISESC(key))
 | 
				
			||||||
 | 
								ch = '4';
 | 
				
			||||||
 | 
							else if (KEYC_ISESC(key))
 | 
				
			||||||
 | 
								ch = '3';
 | 
				
			||||||
 | 
							else if (KEYC_ISSFT(key))
 | 
				
			||||||
 | 
								ch = '2';
 | 
				
			||||||
 | 
							if (ch != '\0') {
 | 
				
			||||||
 | 
								buffer_write(wp->out, ike->data, dlen - 1);
 | 
				
			||||||
 | 
								buffer_write8(wp->out, ';');
 | 
				
			||||||
 | 
								buffer_write8(wp->out, ch);
 | 
				
			||||||
 | 
								buffer_write8(wp->out, ike->data[dlen - 1]);
 | 
				
			||||||
 | 
							} else
 | 
				
			||||||
 | 
								buffer_write(wp->out, ike->data, dlen);
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * Not in xterm mode. Prefix a \033 for escape, and set bit 5 of the
 | 
				
			||||||
 | 
						 * last byte for ctrl.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						if (KEYC_ISESC(key))
 | 
				
			||||||
 | 
							buffer_write8(wp->out, '\033');
 | 
				
			||||||
 | 
						if (KEYC_ISCTL(key) && ike->flags & INPUTKEY_CTRL) {
 | 
				
			||||||
 | 
							buffer_write(wp->out, ike->data, dlen - 1);
 | 
				
			||||||
 | 
							buffer_write8(wp->out, ike->data[dlen - 1] ^ 0x20);
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						buffer_write(wp->out, ike->data, dlen);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Handle input mouse. */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					input_mouse(struct window_pane *wp, u_char b, u_char x, u_char y)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (wp->screen->mode & MODE_MOUSE) {
 | 
				
			||||||
 | 
							buffer_write(wp->out, "\033[M", 3);
 | 
				
			||||||
 | 
							buffer_write8(wp->out, b + 32);
 | 
				
			||||||
 | 
							buffer_write8(wp->out, x + 33);
 | 
				
			||||||
 | 
							buffer_write8(wp->out, y + 33);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										237
									
								
								key-bindings.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										237
									
								
								key-bindings.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,237 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <ctype.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SPLAY_GENERATE(key_bindings, key_binding, entry, key_bindings_cmp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct key_bindings	key_bindings;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					key_bindings_cmp(struct key_binding *bd1, struct key_binding *bd2)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return (bd1->key - bd2->key);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct key_binding *
 | 
				
			||||||
 | 
					key_bindings_lookup(int key)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct key_binding	bd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bd.key = key;
 | 
				
			||||||
 | 
						return (SPLAY_FIND(key_bindings, &key_bindings, &bd));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					key_bindings_add(int key, int can_repeat, struct cmd_list *cmdlist)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct key_binding	*bd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((bd = key_bindings_lookup(key)) == NULL) {
 | 
				
			||||||
 | 
							bd = xmalloc(sizeof *bd);
 | 
				
			||||||
 | 
							bd->key = key;
 | 
				
			||||||
 | 
							SPLAY_INSERT(key_bindings, &key_bindings, bd);
 | 
				
			||||||
 | 
						} else
 | 
				
			||||||
 | 
							cmd_list_free(bd->cmdlist);
 | 
				
			||||||
 | 
						bd->can_repeat = can_repeat;
 | 
				
			||||||
 | 
						bd->cmdlist = cmdlist;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					key_bindings_remove(int key)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct key_binding	*bd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((bd = key_bindings_lookup(key)) == NULL)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						SPLAY_REMOVE(key_bindings, &key_bindings, bd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cmd_list_free(bd->cmdlist);
 | 
				
			||||||
 | 
						xfree(bd);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					key_bindings_init(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						static const struct {
 | 
				
			||||||
 | 
							int			 key;
 | 
				
			||||||
 | 
							int			 can_repeat;
 | 
				
			||||||
 | 
							const struct cmd_entry	*entry;
 | 
				
			||||||
 | 
						} table[] = {
 | 
				
			||||||
 | 
							{ ' ',			  0, &cmd_next_layout_entry },
 | 
				
			||||||
 | 
							{ '!', 			  0, &cmd_break_pane_entry },
 | 
				
			||||||
 | 
							{ '"', 			  0, &cmd_split_window_entry },
 | 
				
			||||||
 | 
							{ '#', 			  0, &cmd_list_buffers_entry },
 | 
				
			||||||
 | 
							{ '&', 			  0, &cmd_confirm_before_entry },
 | 
				
			||||||
 | 
							{ ',', 			  0, &cmd_command_prompt_entry },
 | 
				
			||||||
 | 
							{ '-', 			  0, &cmd_delete_buffer_entry },
 | 
				
			||||||
 | 
							{ '.', 			  0, &cmd_command_prompt_entry },
 | 
				
			||||||
 | 
							{ '0', 			  0, &cmd_select_window_entry },
 | 
				
			||||||
 | 
							{ '1', 			  0, &cmd_select_window_entry },
 | 
				
			||||||
 | 
							{ '2', 			  0, &cmd_select_window_entry },
 | 
				
			||||||
 | 
							{ '3', 			  0, &cmd_select_window_entry },
 | 
				
			||||||
 | 
							{ '4', 			  0, &cmd_select_window_entry },
 | 
				
			||||||
 | 
							{ '5', 			  0, &cmd_select_window_entry },
 | 
				
			||||||
 | 
							{ '6', 			  0, &cmd_select_window_entry },
 | 
				
			||||||
 | 
							{ '7', 			  0, &cmd_select_window_entry },
 | 
				
			||||||
 | 
							{ '8', 			  0, &cmd_select_window_entry },
 | 
				
			||||||
 | 
							{ '9', 			  0, &cmd_select_window_entry },
 | 
				
			||||||
 | 
							{ ':', 			  0, &cmd_command_prompt_entry },
 | 
				
			||||||
 | 
							{ '=', 			  0, &cmd_scroll_mode_entry },
 | 
				
			||||||
 | 
							{ '?', 			  0, &cmd_list_keys_entry },
 | 
				
			||||||
 | 
							{ '[', 			  0, &cmd_copy_mode_entry },
 | 
				
			||||||
 | 
							{ '\'',			  0, &cmd_select_prompt_entry },
 | 
				
			||||||
 | 
							{ '\032', /* C-z */	  0, &cmd_suspend_client_entry },
 | 
				
			||||||
 | 
							{ ']', 			  0, &cmd_paste_buffer_entry },
 | 
				
			||||||
 | 
							{ 'c', 			  0, &cmd_new_window_entry },
 | 
				
			||||||
 | 
							{ 'd', 			  0, &cmd_detach_client_entry },
 | 
				
			||||||
 | 
							{ 'f', 			  0, &cmd_command_prompt_entry },
 | 
				
			||||||
 | 
							{ 'l', 			  0, &cmd_last_window_entry },
 | 
				
			||||||
 | 
							{ 'n', 			  0, &cmd_next_window_entry },
 | 
				
			||||||
 | 
							{ 'o', 			  0, &cmd_down_pane_entry },
 | 
				
			||||||
 | 
							{ 'p', 			  0, &cmd_previous_window_entry },
 | 
				
			||||||
 | 
							{ 'r', 			  0, &cmd_refresh_client_entry },
 | 
				
			||||||
 | 
							{ 's', 			  0, &cmd_choose_session_entry },
 | 
				
			||||||
 | 
							{ 't', 			  0, &cmd_clock_mode_entry },
 | 
				
			||||||
 | 
							{ 'w', 			  0, &cmd_choose_window_entry },
 | 
				
			||||||
 | 
							{ 'x', 			  0, &cmd_confirm_before_entry },
 | 
				
			||||||
 | 
							{ '{',			  0, &cmd_swap_pane_entry },
 | 
				
			||||||
 | 
							{ '}',			  0, &cmd_swap_pane_entry },
 | 
				
			||||||
 | 
							{ '\002', 		  0, &cmd_send_prefix_entry },
 | 
				
			||||||
 | 
							{ KEYC_ADDESC('0'),	  0, &cmd_select_layout_entry },
 | 
				
			||||||
 | 
							{ KEYC_ADDESC('1'),	  0, &cmd_select_layout_entry },
 | 
				
			||||||
 | 
							{ KEYC_ADDESC('2'),	  0, &cmd_select_layout_entry },
 | 
				
			||||||
 | 
							{ KEYC_ADDESC('9'),	  0, &cmd_select_layout_entry },
 | 
				
			||||||
 | 
							{ KEYC_ADDCTL(KEYC_DOWN), 1, &cmd_resize_pane_entry },
 | 
				
			||||||
 | 
							{ KEYC_PPAGE, 		  0, &cmd_scroll_mode_entry },
 | 
				
			||||||
 | 
							{ KEYC_ADDESC('n'), 	  0, &cmd_next_window_entry },
 | 
				
			||||||
 | 
							{ KEYC_ADDESC('p'), 	  0, &cmd_previous_window_entry },
 | 
				
			||||||
 | 
							{ KEYC_UP, 		  1, &cmd_up_pane_entry },
 | 
				
			||||||
 | 
							{ KEYC_DOWN, 		  1, &cmd_down_pane_entry },
 | 
				
			||||||
 | 
							{ KEYC_ADDESC(KEYC_UP),   1, &cmd_resize_pane_entry },
 | 
				
			||||||
 | 
							{ KEYC_ADDESC(KEYC_DOWN), 1, &cmd_resize_pane_entry },
 | 
				
			||||||
 | 
							{ KEYC_ADDCTL(KEYC_UP),   1, &cmd_resize_pane_entry },
 | 
				
			||||||
 | 
							{ KEYC_ADDCTL(KEYC_DOWN), 1, &cmd_resize_pane_entry },
 | 
				
			||||||
 | 
							{ KEYC_ADDESC('o'),	  0, &cmd_rotate_window_entry },
 | 
				
			||||||
 | 
							{ '\017',	          0, &cmd_rotate_window_entry },
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
						u_int		 i;
 | 
				
			||||||
 | 
						struct cmd	*cmd;
 | 
				
			||||||
 | 
						struct cmd_list	*cmdlist;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						SPLAY_INIT(&key_bindings);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < nitems(table); i++) {
 | 
				
			||||||
 | 
							cmdlist = xmalloc(sizeof *cmdlist);
 | 
				
			||||||
 | 
							TAILQ_INIT(cmdlist);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							cmd = xmalloc(sizeof *cmd);
 | 
				
			||||||
 | 
							cmd->entry = table[i].entry;
 | 
				
			||||||
 | 
							cmd->data = NULL;
 | 
				
			||||||
 | 
							if (cmd->entry->init != NULL)
 | 
				
			||||||
 | 
								cmd->entry->init(cmd, table[i].key);
 | 
				
			||||||
 | 
							TAILQ_INSERT_HEAD(cmdlist, cmd, qentry);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							key_bindings_add(table[i].key, table[i].can_repeat, cmdlist);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					key_bindings_free(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct key_binding	*bd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while (!SPLAY_EMPTY(&key_bindings)) {
 | 
				
			||||||
 | 
							bd = SPLAY_ROOT(&key_bindings);
 | 
				
			||||||
 | 
							SPLAY_REMOVE(key_bindings, &key_bindings, bd);
 | 
				
			||||||
 | 
							cmd_list_free(bd->cmdlist);
 | 
				
			||||||
 | 
							xfree(bd);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void printflike2
 | 
				
			||||||
 | 
					key_bindings_error(struct cmd_ctx *ctx, const char *fmt, ...)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						va_list	ap;
 | 
				
			||||||
 | 
						char   *msg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						va_start(ap, fmt);
 | 
				
			||||||
 | 
						xvasprintf(&msg, fmt, ap);
 | 
				
			||||||
 | 
						va_end(ap);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						*msg = toupper((u_char) *msg);
 | 
				
			||||||
 | 
					 	status_message_set(ctx->curclient, msg);
 | 
				
			||||||
 | 
						xfree(msg);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void printflike2
 | 
				
			||||||
 | 
					key_bindings_print(struct cmd_ctx *ctx, const char *fmt, ...)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct winlink	*wl = ctx->cursession->curw;
 | 
				
			||||||
 | 
						va_list		 ap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (wl->window->active->mode != &window_more_mode)
 | 
				
			||||||
 | 
							window_pane_reset_mode(wl->window->active);
 | 
				
			||||||
 | 
						window_pane_set_mode(wl->window->active, &window_more_mode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						va_start(ap, fmt);
 | 
				
			||||||
 | 
						window_more_vadd(wl->window->active, fmt, ap);
 | 
				
			||||||
 | 
						va_end(ap);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void printflike2
 | 
				
			||||||
 | 
					key_bindings_info(struct cmd_ctx *ctx, const char *fmt, ...)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						va_list	ap;
 | 
				
			||||||
 | 
						char   *msg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (be_quiet)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						va_start(ap, fmt);
 | 
				
			||||||
 | 
						xvasprintf(&msg, fmt, ap);
 | 
				
			||||||
 | 
						va_end(ap);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						*msg = toupper((u_char) *msg);
 | 
				
			||||||
 | 
					 	status_message_set(ctx->curclient, msg);
 | 
				
			||||||
 | 
						xfree(msg);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					key_bindings_dispatch(struct key_binding *bd, struct client *c)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct cmd_ctx	 	 ctx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ctx.msgdata = NULL;
 | 
				
			||||||
 | 
						ctx.cursession = c->session;
 | 
				
			||||||
 | 
						ctx.curclient = c;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ctx.error = key_bindings_error;
 | 
				
			||||||
 | 
						ctx.print = key_bindings_print;
 | 
				
			||||||
 | 
						ctx.info = key_bindings_info;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ctx.cmdclient = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cmd_list_exec(bd->cmdlist, &ctx);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										198
									
								
								key-string.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										198
									
								
								key-string.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,198 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int	key_string_search_table(const char *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct {
 | 
				
			||||||
 | 
						const char *string;
 | 
				
			||||||
 | 
						int	 key;
 | 
				
			||||||
 | 
					} key_string_table[] = {
 | 
				
			||||||
 | 
						/* Function keys. */
 | 
				
			||||||
 | 
						{ "F1",		KEYC_F1 },
 | 
				
			||||||
 | 
						{ "F2",		KEYC_F2 },
 | 
				
			||||||
 | 
						{ "F3",		KEYC_F3 },
 | 
				
			||||||
 | 
						{ "F4",		KEYC_F4 },
 | 
				
			||||||
 | 
						{ "F5",		KEYC_F5 },
 | 
				
			||||||
 | 
						{ "F6",		KEYC_F6 },
 | 
				
			||||||
 | 
						{ "F7",		KEYC_F7 },
 | 
				
			||||||
 | 
						{ "F8",		KEYC_F8 },
 | 
				
			||||||
 | 
						{ "F9",		KEYC_F9 },
 | 
				
			||||||
 | 
						{ "F10",	KEYC_F10 },
 | 
				
			||||||
 | 
						{ "F11",	KEYC_F11 },
 | 
				
			||||||
 | 
						{ "F12",	KEYC_F12 },
 | 
				
			||||||
 | 
						{ "F13",	KEYC_F13 },
 | 
				
			||||||
 | 
						{ "F14",	KEYC_F14 },
 | 
				
			||||||
 | 
						{ "F15",	KEYC_F15 },
 | 
				
			||||||
 | 
						{ "F16",	KEYC_F16 },
 | 
				
			||||||
 | 
						{ "F17",	KEYC_F17 },
 | 
				
			||||||
 | 
						{ "F18",	KEYC_F18 },
 | 
				
			||||||
 | 
						{ "F19",	KEYC_F19 },
 | 
				
			||||||
 | 
						{ "F20",	KEYC_F20 },
 | 
				
			||||||
 | 
						{ "IC",		KEYC_IC },
 | 
				
			||||||
 | 
						{ "DC",		KEYC_DC },
 | 
				
			||||||
 | 
						{ "Home",	KEYC_HOME },
 | 
				
			||||||
 | 
						{ "End",	KEYC_END },
 | 
				
			||||||
 | 
						{ "NPage",	KEYC_NPAGE },
 | 
				
			||||||
 | 
						{ "PPage",	KEYC_PPAGE },
 | 
				
			||||||
 | 
						{ "Tab",	'\011' },
 | 
				
			||||||
 | 
						{ "BTab",	KEYC_BTAB },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Arrow keys. */
 | 
				
			||||||
 | 
						{ "Up",		KEYC_UP },
 | 
				
			||||||
 | 
						{ "Down",	KEYC_DOWN },
 | 
				
			||||||
 | 
						{ "Left",	KEYC_LEFT },
 | 
				
			||||||
 | 
						{ "Right",	KEYC_RIGHT },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Numeric keypad. */
 | 
				
			||||||
 | 
						{ "KP/", 	KEYC_KP0_1 },
 | 
				
			||||||
 | 
						{ "KP*",	KEYC_KP0_2 },
 | 
				
			||||||
 | 
						{ "KP-",	KEYC_KP0_3 },
 | 
				
			||||||
 | 
						{ "KP7",	KEYC_KP1_0 },
 | 
				
			||||||
 | 
						{ "KP8",	KEYC_KP1_1 },
 | 
				
			||||||
 | 
						{ "KP9",	KEYC_KP1_2 },
 | 
				
			||||||
 | 
						{ "KP+",	KEYC_KP1_3 },
 | 
				
			||||||
 | 
						{ "KP4",	KEYC_KP2_0 },
 | 
				
			||||||
 | 
						{ "KP5",	KEYC_KP2_1 },
 | 
				
			||||||
 | 
						{ "KP6",	KEYC_KP2_2 },
 | 
				
			||||||
 | 
						{ "KP1",	KEYC_KP3_0 },
 | 
				
			||||||
 | 
						{ "KP2",	KEYC_KP3_1 },
 | 
				
			||||||
 | 
						{ "KP3",	KEYC_KP3_2 },
 | 
				
			||||||
 | 
						{ "KPEnter",	KEYC_KP3_3 },
 | 
				
			||||||
 | 
						{ "KP0",	KEYC_KP4_0 },
 | 
				
			||||||
 | 
						{ "KP.",	KEYC_KP4_2 },
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					key_string_search_table(const char *string)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u_int	i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < nitems(key_string_table); i++) {
 | 
				
			||||||
 | 
							if (strcasecmp(string, key_string_table[i].string) == 0)
 | 
				
			||||||
 | 
								return (key_string_table[i].key);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return (KEYC_NONE);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					key_string_lookup_string(const char *string)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int	      	 key;
 | 
				
			||||||
 | 
						const u_char	*ptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (string[0] == '\0')
 | 
				
			||||||
 | 
							return (KEYC_NONE);
 | 
				
			||||||
 | 
						if (string[1] == '\0')
 | 
				
			||||||
 | 
							return (string[0]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ptr = NULL;
 | 
				
			||||||
 | 
						if (string[0] == 'C' && string[1] == '-')
 | 
				
			||||||
 | 
							ptr = string + 2;
 | 
				
			||||||
 | 
						else if (string[0] == '^')
 | 
				
			||||||
 | 
							ptr = string + 1;
 | 
				
			||||||
 | 
						if (ptr != NULL) {
 | 
				
			||||||
 | 
							if (ptr[0] == '\0')
 | 
				
			||||||
 | 
								return (KEYC_NONE);
 | 
				
			||||||
 | 
							if (ptr[1] == '\0') {
 | 
				
			||||||
 | 
								if (ptr[0] == 32)
 | 
				
			||||||
 | 
									return (0);
 | 
				
			||||||
 | 
								if (ptr[0] >= 64 && ptr[0] <= 95)
 | 
				
			||||||
 | 
									return (ptr[0] - 64);
 | 
				
			||||||
 | 
								if (ptr[0] >= 97 && ptr[0] <= 122)
 | 
				
			||||||
 | 
									return (ptr[0] - 96);
 | 
				
			||||||
 | 
								return (KEYC_NONE);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							key = key_string_search_table(ptr);
 | 
				
			||||||
 | 
							if (key != KEYC_NONE)
 | 
				
			||||||
 | 
								return (KEYC_ADDCTL(key));
 | 
				
			||||||
 | 
							return (KEYC_NONE);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (string[0] == 'M' && string[1] == '-') {
 | 
				
			||||||
 | 
							ptr = string + 2;
 | 
				
			||||||
 | 
							if (ptr[0] == '\0')
 | 
				
			||||||
 | 
								return (KEYC_NONE);
 | 
				
			||||||
 | 
							if (ptr[1] == '\0') {
 | 
				
			||||||
 | 
								if (ptr[0] < 32 || ptr[0] > 127)
 | 
				
			||||||
 | 
									return (KEYC_NONE);
 | 
				
			||||||
 | 
								return (KEYC_ADDESC(ptr[0]));
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							key = key_string_lookup_string(ptr);
 | 
				
			||||||
 | 
							if (key != KEYC_NONE)
 | 
				
			||||||
 | 
								return (KEYC_ADDESC(key));
 | 
				
			||||||
 | 
							return (KEYC_NONE);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (key_string_search_table(string));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const char *
 | 
				
			||||||
 | 
					key_string_lookup_key(int key)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						static char tmp[24], tmp2[24];
 | 
				
			||||||
 | 
						const char *s;
 | 
				
			||||||
 | 
						u_int	    i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (key == 127)
 | 
				
			||||||
 | 
							return (NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (KEYC_ISESC(key)) {
 | 
				
			||||||
 | 
							if ((s = key_string_lookup_key(KEYC_REMOVEESC(key))) == NULL)
 | 
				
			||||||
 | 
								return (NULL);
 | 
				
			||||||
 | 
							xsnprintf(tmp2, sizeof tmp2, "M-%s", s);
 | 
				
			||||||
 | 
							return (tmp2);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (KEYC_ISCTL(key)) {
 | 
				
			||||||
 | 
							if ((s = key_string_lookup_key(KEYC_REMOVECTL(key))) == NULL)
 | 
				
			||||||
 | 
								return (NULL);
 | 
				
			||||||
 | 
							xsnprintf(tmp2, sizeof tmp2, "C-%s", s);
 | 
				
			||||||
 | 
							return (tmp2);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (KEYC_ISSFT(key)) {
 | 
				
			||||||
 | 
							if ((s = key_string_lookup_key(KEYC_REMOVESFT(key))) == NULL)
 | 
				
			||||||
 | 
								return (NULL);
 | 
				
			||||||
 | 
							xsnprintf(tmp2, sizeof tmp2, "S-%s", s);
 | 
				
			||||||
 | 
							return (tmp2);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (key >= 32 && key <= 255) {
 | 
				
			||||||
 | 
							tmp[0] = key;
 | 
				
			||||||
 | 
							tmp[1] = '\0';
 | 
				
			||||||
 | 
							return (tmp);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (key >= 0 && key <= 32) {
 | 
				
			||||||
 | 
							if (key == 0 || key > 26)
 | 
				
			||||||
 | 
								xsnprintf(tmp, sizeof tmp, "C-%c", 64 + key);
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								xsnprintf(tmp, sizeof tmp, "C-%c", 96 + key);
 | 
				
			||||||
 | 
							return (tmp);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < nitems(key_string_table); i++) {
 | 
				
			||||||
 | 
							if (key == key_string_table[i].key)
 | 
				
			||||||
 | 
								return (key_string_table[i].string);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return (NULL);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										183
									
								
								layout-manual.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										183
									
								
								layout-manual.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,183 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void	layout_manual_v_update_offsets(struct window *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					layout_manual_v_refresh(struct window *w, unused int active_only)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct window_pane	*wp;
 | 
				
			||||||
 | 
						u_int			 npanes, canfit, total;
 | 
				
			||||||
 | 
						int			 left;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (active_only)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (TAILQ_EMPTY(&w->panes))
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Clear hidden flags. */
 | 
				
			||||||
 | 
						TAILQ_FOREACH(wp, &w->panes, entry)
 | 
				
			||||||
 | 
						    	wp->flags &= ~PANE_HIDDEN;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Check the new size. */
 | 
				
			||||||
 | 
						npanes = window_count_panes(w);
 | 
				
			||||||
 | 
						if (w->sy <= PANE_MINIMUM * npanes) {
 | 
				
			||||||
 | 
							/* How many can we fit? */
 | 
				
			||||||
 | 
							canfit = w->sy / PANE_MINIMUM;
 | 
				
			||||||
 | 
							if (canfit == 0) {
 | 
				
			||||||
 | 
								/* None. Just use this size for the first. */
 | 
				
			||||||
 | 
								TAILQ_FOREACH(wp, &w->panes, entry) {
 | 
				
			||||||
 | 
									if (wp == TAILQ_FIRST(&w->panes))
 | 
				
			||||||
 | 
										wp->sy = w->sy;
 | 
				
			||||||
 | 
									else
 | 
				
			||||||
 | 
										wp->flags |= PANE_HIDDEN;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								/* >=1, set minimum for them all. */
 | 
				
			||||||
 | 
								TAILQ_FOREACH(wp, &w->panes, entry) {
 | 
				
			||||||
 | 
									if (canfit-- > 0)
 | 
				
			||||||
 | 
										wp->sy = PANE_MINIMUM - 1;
 | 
				
			||||||
 | 
									else
 | 
				
			||||||
 | 
										wp->flags |= PANE_HIDDEN;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								/* And increase the first by the rest. */
 | 
				
			||||||
 | 
								TAILQ_FIRST(&w->panes)->sy += 1 + w->sy % PANE_MINIMUM;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							/* In theory they will all fit. Find the current total. */
 | 
				
			||||||
 | 
							total = 0;
 | 
				
			||||||
 | 
							TAILQ_FOREACH(wp, &w->panes, entry)
 | 
				
			||||||
 | 
								total += wp->sy;
 | 
				
			||||||
 | 
							total += npanes - 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Growing or shrinking? */
 | 
				
			||||||
 | 
							left = w->sy - total;
 | 
				
			||||||
 | 
							if (left > 0) {
 | 
				
			||||||
 | 
								/* Growing. Expand evenly. */
 | 
				
			||||||
 | 
								while (left > 0) {
 | 
				
			||||||
 | 
									TAILQ_FOREACH(wp, &w->panes, entry) {
 | 
				
			||||||
 | 
										wp->sy++;
 | 
				
			||||||
 | 
										if (--left == 0)
 | 
				
			||||||
 | 
											break;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								/* Shrinking. Reduce evenly down to minimum. */
 | 
				
			||||||
 | 
								while (left < 0) {
 | 
				
			||||||
 | 
									TAILQ_FOREACH(wp, &w->panes, entry) {
 | 
				
			||||||
 | 
										if (wp->sy <= PANE_MINIMUM - 1)
 | 
				
			||||||
 | 
											continue;
 | 
				
			||||||
 | 
										wp->sy--;
 | 
				
			||||||
 | 
										if (++left == 0)
 | 
				
			||||||
 | 
											break;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Now do the resize. */
 | 
				
			||||||
 | 
						TAILQ_FOREACH(wp, &w->panes, entry) {
 | 
				
			||||||
 | 
							wp->sy--;
 | 
				
			||||||
 | 
						    	window_pane_resize(wp, w->sx, wp->sy + 1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Fill in the offsets. */
 | 
				
			||||||
 | 
						layout_manual_v_update_offsets(w);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Switch the active window if necessary. */
 | 
				
			||||||
 | 
						window_set_active_pane(w, w->active);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					layout_manual_v_resize(struct window_pane *wp, int adjust)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct window		*w = wp->window;
 | 
				
			||||||
 | 
						struct window_pane	*wq;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (adjust > 0) {
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
							 * If this is not the last pane, keep trying to increase size
 | 
				
			||||||
 | 
							 * and remove it from the next panes. If it is the last, do
 | 
				
			||||||
 | 
							 * so on the previous pane.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							if (TAILQ_NEXT(wp, entry) == NULL) {
 | 
				
			||||||
 | 
								if (wp == TAILQ_FIRST(&w->panes)) {
 | 
				
			||||||
 | 
									/* Only one pane. */
 | 
				
			||||||
 | 
									return;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								wp = TAILQ_PREV(wp, window_panes, entry);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							while (adjust-- > 0) {
 | 
				
			||||||
 | 
								wq = wp;
 | 
				
			||||||
 | 
								while ((wq = TAILQ_NEXT(wq, entry)) != NULL) {
 | 
				
			||||||
 | 
									if (wq->sy <= PANE_MINIMUM)
 | 
				
			||||||
 | 
										continue;
 | 
				
			||||||
 | 
									window_pane_resize(wq, wq->sx, wq->sy - 1);
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if (wq == NULL)
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								window_pane_resize(wp, wp->sx, wp->sy + 1);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							adjust = -adjust;
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
							 * If this is not the last pane, keep trying to reduce size
 | 
				
			||||||
 | 
							 * and add to the following pane. If it is the last, do so on
 | 
				
			||||||
 | 
							 * the previous pane.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							wq = TAILQ_NEXT(wp, entry);
 | 
				
			||||||
 | 
							if (wq == NULL) {
 | 
				
			||||||
 | 
								if (wp == TAILQ_FIRST(&w->panes)) {
 | 
				
			||||||
 | 
									/* Only one pane. */
 | 
				
			||||||
 | 
									return;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								wq = wp;
 | 
				
			||||||
 | 
								wp = TAILQ_PREV(wq, window_panes, entry);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							while (adjust-- > 0) {
 | 
				
			||||||
 | 
								if (wp->sy <= PANE_MINIMUM)
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								window_pane_resize(wq, wq->sx, wq->sy + 1);
 | 
				
			||||||
 | 
								window_pane_resize(wp, wp->sx, wp->sy - 1);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						layout_manual_v_update_offsets(w);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					layout_manual_v_update_offsets(struct window *w)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct window_pane     *wp;
 | 
				
			||||||
 | 
						u_int			yoff;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						yoff = 0;
 | 
				
			||||||
 | 
						TAILQ_FOREACH(wp, &w->panes, entry) {
 | 
				
			||||||
 | 
							if (wp->flags & PANE_HIDDEN)
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							wp->xoff = 0;
 | 
				
			||||||
 | 
							wp->yoff = yoff;
 | 
				
			||||||
 | 
							yoff += wp->sy + 1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										373
									
								
								layout.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										373
									
								
								layout.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,373 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Each layout has two functions, _refresh to relayout the panes and _resize to
 | 
				
			||||||
 | 
					 * resize a single pane.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Second argument (int) to _refresh is 1 if the only change has been that the
 | 
				
			||||||
 | 
					 * active pane has changed. If 0 then panes, active pane or both may have
 | 
				
			||||||
 | 
					 * changed.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void	layout_active_only_refresh(struct window *, int);
 | 
				
			||||||
 | 
					void	layout_even_h_refresh(struct window *, int);
 | 
				
			||||||
 | 
					void	layout_even_v_refresh(struct window *, int);
 | 
				
			||||||
 | 
					void	layout_main_h_refresh(struct window *, int);
 | 
				
			||||||
 | 
					void	layout_main_v_refresh(struct window *, int);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct {
 | 
				
			||||||
 | 
						const char     *name;
 | 
				
			||||||
 | 
						void		(*refresh)(struct window *, int);
 | 
				
			||||||
 | 
						void		(*resize)(struct window_pane *, int);
 | 
				
			||||||
 | 
					} layouts[] = {
 | 
				
			||||||
 | 
						{ "manual-vertical", layout_manual_v_refresh, layout_manual_v_resize },
 | 
				
			||||||
 | 
						{ "active-only", layout_active_only_refresh, NULL },
 | 
				
			||||||
 | 
						{ "even-horizontal", layout_even_h_refresh, NULL },
 | 
				
			||||||
 | 
						{ "even-vertical", layout_even_v_refresh, NULL },
 | 
				
			||||||
 | 
						{ "main-horizontal", layout_main_h_refresh, NULL },
 | 
				
			||||||
 | 
						{ "main-vertical", layout_main_v_refresh, NULL },
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const char *
 | 
				
			||||||
 | 
					layout_name(struct window *w)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return (layouts[w->layout].name);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					layout_lookup(const char *name)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u_int	i;
 | 
				
			||||||
 | 
						int	matched = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < nitems(layouts); i++) {
 | 
				
			||||||
 | 
							if (strncmp(layouts[i].name, name, strlen(name)) == 0) {
 | 
				
			||||||
 | 
								if (matched != -1)	/* ambiguous */
 | 
				
			||||||
 | 
									return (-1);
 | 
				
			||||||
 | 
								matched = i;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (matched);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					layout_select(struct window *w, u_int layout)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (layout > nitems(layouts) - 1 || layout == w->layout)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						w->layout = layout;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						layout_refresh(w, 0);
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					layout_next(struct window *w)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						w->layout++;
 | 
				
			||||||
 | 
						if (w->layout > nitems(layouts) - 1)
 | 
				
			||||||
 | 
							w->layout = 0;
 | 
				
			||||||
 | 
						layout_refresh(w, 0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					layout_previous(struct window *w)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (w->layout == 0)
 | 
				
			||||||
 | 
							w->layout = nitems(layouts) - 1;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							w->layout--;
 | 
				
			||||||
 | 
						layout_refresh(w, 0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					layout_refresh(struct window *w, int active_only)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						layouts[w->layout].refresh(w, active_only);
 | 
				
			||||||
 | 
						server_redraw_window(w);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					layout_resize(struct window_pane *wp, int adjust)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct window	*w = wp->window;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (layouts[w->layout].resize == NULL)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
						layouts[w->layout].resize(wp, adjust);
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					layout_active_only_refresh(struct window *w, unused int active_only)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct window_pane	*wp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						TAILQ_FOREACH(wp, &w->panes, entry) {
 | 
				
			||||||
 | 
							if (wp == w->active) {
 | 
				
			||||||
 | 
								wp->flags &= ~PANE_HIDDEN;
 | 
				
			||||||
 | 
								wp->xoff = wp->yoff = 0;
 | 
				
			||||||
 | 
								window_pane_resize(wp, w->sx, w->sy);
 | 
				
			||||||
 | 
							} else
 | 
				
			||||||
 | 
								wp->flags |= PANE_HIDDEN;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					layout_even_h_refresh(struct window *w, int active_only)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct window_pane	*wp;
 | 
				
			||||||
 | 
						u_int			 i, n, width, xoff;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (active_only)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Get number of panes. */
 | 
				
			||||||
 | 
						n = window_count_panes(w);
 | 
				
			||||||
 | 
						if (n == 0)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* How many can we fit? */
 | 
				
			||||||
 | 
						if (w->sx / n < PANE_MINIMUM) {
 | 
				
			||||||
 | 
							width = PANE_MINIMUM;
 | 
				
			||||||
 | 
							n = w->sx / PANE_MINIMUM;
 | 
				
			||||||
 | 
						} else
 | 
				
			||||||
 | 
							width = w->sx / n;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Fit the panes. */
 | 
				
			||||||
 | 
						i = xoff = 0;
 | 
				
			||||||
 | 
						TAILQ_FOREACH(wp, &w->panes, entry) {
 | 
				
			||||||
 | 
							if (i > n) {
 | 
				
			||||||
 | 
								wp->flags |= PANE_HIDDEN;
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							wp->flags &= ~PANE_HIDDEN;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							wp->xoff = xoff;
 | 
				
			||||||
 | 
							wp->yoff = 0;
 | 
				
			||||||
 | 
							if (i != n - 1)
 | 
				
			||||||
 | 
					 			window_pane_resize(wp, width - 1, w->sy);
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
					 			window_pane_resize(wp, width, w->sy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							i++;
 | 
				
			||||||
 | 
							xoff += width;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Any space left? */
 | 
				
			||||||
 | 
						while (xoff++ < w->sx) {
 | 
				
			||||||
 | 
							wp = TAILQ_LAST(&w->panes, window_panes);
 | 
				
			||||||
 | 
							window_pane_resize(wp, wp->sx + 1, wp->sy);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					layout_even_v_refresh(struct window *w, int active_only)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct window_pane	*wp;
 | 
				
			||||||
 | 
						u_int			 i, n, height, yoff;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (active_only)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Get number of panes. */
 | 
				
			||||||
 | 
						n = window_count_panes(w);
 | 
				
			||||||
 | 
						if (n == 0)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* How many can we fit? */
 | 
				
			||||||
 | 
						if (w->sy / n < PANE_MINIMUM) {
 | 
				
			||||||
 | 
							height = PANE_MINIMUM;
 | 
				
			||||||
 | 
							n = w->sy / PANE_MINIMUM;
 | 
				
			||||||
 | 
						} else
 | 
				
			||||||
 | 
							height = w->sy / n;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Fit the panes. */
 | 
				
			||||||
 | 
						i = yoff = 0;
 | 
				
			||||||
 | 
						TAILQ_FOREACH(wp, &w->panes, entry) {
 | 
				
			||||||
 | 
							if (i > n) {
 | 
				
			||||||
 | 
								wp->flags |= PANE_HIDDEN;
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							wp->flags &= ~PANE_HIDDEN;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							wp->xoff = 0;
 | 
				
			||||||
 | 
							wp->yoff = yoff;
 | 
				
			||||||
 | 
							if (i != n - 1)
 | 
				
			||||||
 | 
					 			window_pane_resize(wp, w->sx, height - 1);
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
					 			window_pane_resize(wp, w->sx, height);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							i++;
 | 
				
			||||||
 | 
							yoff += height;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Any space left? */
 | 
				
			||||||
 | 
						while (yoff++ < w->sy) {
 | 
				
			||||||
 | 
							wp = TAILQ_LAST(&w->panes, window_panes);
 | 
				
			||||||
 | 
							window_pane_resize(wp, wp->sx, wp->sy + 1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					layout_main_v_refresh(struct window *w, int active_only)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct window_pane	*wp;
 | 
				
			||||||
 | 
						u_int			 i, n, mainwidth, height, yoff;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (active_only)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Get number of panes. */
 | 
				
			||||||
 | 
						n = window_count_panes(w);
 | 
				
			||||||
 | 
						if (n == 0)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Get the main pane width and add one for separator line. */
 | 
				
			||||||
 | 
						mainwidth = options_get_number(&w->options, "main-pane-width") + 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Need >1 pane and minimum columns; if fewer, display active only. */
 | 
				
			||||||
 | 
						if (n == 1 || w->sx < mainwidth + PANE_MINIMUM) {
 | 
				
			||||||
 | 
							layout_active_only_refresh(w, active_only);
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						n--;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* How many can we fit, not including first? */
 | 
				
			||||||
 | 
						if (w->sy / n < PANE_MINIMUM) {
 | 
				
			||||||
 | 
							height = PANE_MINIMUM;
 | 
				
			||||||
 | 
							n = w->sy / PANE_MINIMUM;
 | 
				
			||||||
 | 
						} else
 | 
				
			||||||
 | 
							height = w->sy / n;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Fit the panes. */
 | 
				
			||||||
 | 
						i = yoff = 0;
 | 
				
			||||||
 | 
						TAILQ_FOREACH(wp, &w->panes, entry) {
 | 
				
			||||||
 | 
							if (wp == TAILQ_FIRST(&w->panes)) {
 | 
				
			||||||
 | 
								wp->xoff = 0;
 | 
				
			||||||
 | 
								wp->yoff = 0;
 | 
				
			||||||
 | 
								window_pane_resize(wp, mainwidth - 1, w->sy);
 | 
				
			||||||
 | 
								wp->flags &= ~PANE_HIDDEN;
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (i > n) {
 | 
				
			||||||
 | 
								wp->flags |= PANE_HIDDEN;
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							wp->flags &= ~PANE_HIDDEN;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							wp->xoff = mainwidth;
 | 
				
			||||||
 | 
							wp->yoff = yoff;
 | 
				
			||||||
 | 
							if (i != n - 1)
 | 
				
			||||||
 | 
					 			window_pane_resize(wp, w->sx - mainwidth, height - 1);
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
					 			window_pane_resize(wp, w->sx - mainwidth, height);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							i++;
 | 
				
			||||||
 | 
							yoff += height;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Any space left? */
 | 
				
			||||||
 | 
						while (yoff++ < w->sy) {
 | 
				
			||||||
 | 
							wp = TAILQ_LAST(&w->panes, window_panes);
 | 
				
			||||||
 | 
							while (wp != NULL && wp == TAILQ_FIRST(&w->panes))
 | 
				
			||||||
 | 
								wp = TAILQ_PREV(wp, window_panes, entry);
 | 
				
			||||||
 | 
							if (wp == NULL)
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							window_pane_resize(wp, wp->sx, wp->sy + 1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					layout_main_h_refresh(struct window *w, int active_only)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct window_pane	*wp;
 | 
				
			||||||
 | 
						u_int			 i, n, mainheight, width, xoff;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (active_only)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Get number of panes. */
 | 
				
			||||||
 | 
						n = window_count_panes(w);
 | 
				
			||||||
 | 
						if (n == 0)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Get the main pane height and add one for separator line. */
 | 
				
			||||||
 | 
						mainheight = options_get_number(&w->options, "main-pane-height") + 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Need >1 pane and minimum rows; if fewer, display active only. */
 | 
				
			||||||
 | 
						if (n == 1 || w->sy < mainheight + PANE_MINIMUM) {
 | 
				
			||||||
 | 
							layout_active_only_refresh(w, active_only);
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						n--;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* How many can we fit, not including first? */
 | 
				
			||||||
 | 
						if (w->sx / n < PANE_MINIMUM) {
 | 
				
			||||||
 | 
							width = PANE_MINIMUM;
 | 
				
			||||||
 | 
							n = w->sx / PANE_MINIMUM;
 | 
				
			||||||
 | 
						} else
 | 
				
			||||||
 | 
							width = w->sx / n;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Fit the panes. */
 | 
				
			||||||
 | 
						i = xoff = 0;
 | 
				
			||||||
 | 
						TAILQ_FOREACH(wp, &w->panes, entry) {
 | 
				
			||||||
 | 
							if (wp == TAILQ_FIRST(&w->panes)) {
 | 
				
			||||||
 | 
								wp->xoff = 0;
 | 
				
			||||||
 | 
								wp->yoff = 0;
 | 
				
			||||||
 | 
								window_pane_resize(wp, w->sx, mainheight - 1);
 | 
				
			||||||
 | 
								wp->flags &= ~PANE_HIDDEN;
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (i > n) {
 | 
				
			||||||
 | 
								wp->flags |= PANE_HIDDEN;
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							wp->flags &= ~PANE_HIDDEN;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							wp->xoff = xoff;
 | 
				
			||||||
 | 
							wp->yoff = mainheight;
 | 
				
			||||||
 | 
							if (i != n - 1)
 | 
				
			||||||
 | 
					 			window_pane_resize(wp, width - 1, w->sy - mainheight);
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
					 			window_pane_resize(wp, width - 1, w->sy - mainheight);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							i++;
 | 
				
			||||||
 | 
							xoff += width;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Any space left? */
 | 
				
			||||||
 | 
						while (xoff++ < w->sx + 1) {
 | 
				
			||||||
 | 
							wp = TAILQ_LAST(&w->panes, window_panes);
 | 
				
			||||||
 | 
							while (wp != NULL && wp == TAILQ_FIRST(&w->panes))
 | 
				
			||||||
 | 
								wp = TAILQ_PREV(wp, window_panes, entry);
 | 
				
			||||||
 | 
							if (wp == NULL)
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							window_pane_resize(wp, wp->sx + 1, wp->sy);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										250
									
								
								log.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										250
									
								
								log.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,250 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <errno.h>
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <syslog.h>
 | 
				
			||||||
 | 
					#include <time.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Logging type. */
 | 
				
			||||||
 | 
					#define LOG_TYPE_OFF 0
 | 
				
			||||||
 | 
					#define LOG_TYPE_SYSLOG 1
 | 
				
			||||||
 | 
					#define LOG_TYPE_TTY 2
 | 
				
			||||||
 | 
					#define LOG_TYPE_FILE 3
 | 
				
			||||||
 | 
					int	log_type = LOG_TYPE_OFF;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Log file, if needed. */
 | 
				
			||||||
 | 
					FILE   *log_file;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Debug level. */
 | 
				
			||||||
 | 
					int	log_level;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Open logging to syslog. */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					log_open_syslog(int level)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						log_type = LOG_TYPE_SYSLOG;
 | 
				
			||||||
 | 
						log_level = level;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						openlog(__progname, LOG_PID|LOG_NDELAY, LOG_FACILITY);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tzset();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Open logging to tty. */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					log_open_tty(int level)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						log_type = LOG_TYPE_TTY;
 | 
				
			||||||
 | 
						log_level = level;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						setlinebuf(stderr);
 | 
				
			||||||
 | 
						setlinebuf(stdout);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tzset();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Open logging to file. */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					log_open_file(int level, const char *path)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						log_file = fopen(path, "w");
 | 
				
			||||||
 | 
						if (log_file == NULL)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						log_type = LOG_TYPE_FILE;
 | 
				
			||||||
 | 
						log_level = level;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						setlinebuf(log_file);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tzset();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Close logging. */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					log_close(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (log_type == LOG_TYPE_FILE)
 | 
				
			||||||
 | 
							fclose(log_file);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						log_type = LOG_TYPE_OFF;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Write a log message. */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					log_write(int pri, const char *msg, ...)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						va_list	ap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						va_start(ap, msg);
 | 
				
			||||||
 | 
						log_vwrite(pri, msg, ap);
 | 
				
			||||||
 | 
						va_end(ap);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Write a log message. */
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					log_vwrite(int pri, const char *msg, va_list ap)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char	*fmt;
 | 
				
			||||||
 | 
						FILE	*f = log_file;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (log_type) {
 | 
				
			||||||
 | 
						case LOG_TYPE_SYSLOG:
 | 
				
			||||||
 | 
							vsyslog(pri, msg, ap);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case LOG_TYPE_TTY:
 | 
				
			||||||
 | 
							if (pri == LOG_INFO)
 | 
				
			||||||
 | 
								f = stdout;
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								f = stderr;
 | 
				
			||||||
 | 
							/* FALLTHROUGH */
 | 
				
			||||||
 | 
						case LOG_TYPE_FILE:
 | 
				
			||||||
 | 
							if (asprintf(&fmt, "%s\n", msg) == -1)
 | 
				
			||||||
 | 
								exit(1);
 | 
				
			||||||
 | 
							if (vfprintf(f, fmt, ap) == -1)
 | 
				
			||||||
 | 
								exit(1);
 | 
				
			||||||
 | 
							fflush(f);
 | 
				
			||||||
 | 
							free(fmt);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Log a warning with error string. */
 | 
				
			||||||
 | 
					void printflike1
 | 
				
			||||||
 | 
					log_warn(const char *msg, ...)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						va_list	 ap;
 | 
				
			||||||
 | 
						char	*fmt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						va_start(ap, msg);
 | 
				
			||||||
 | 
						if (asprintf(&fmt, "%s: %s", msg, strerror(errno)) == -1)
 | 
				
			||||||
 | 
							exit(1);
 | 
				
			||||||
 | 
						log_vwrite(LOG_CRIT, fmt, ap);
 | 
				
			||||||
 | 
						free(fmt);
 | 
				
			||||||
 | 
						va_end(ap);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Log a warning. */
 | 
				
			||||||
 | 
					void printflike1
 | 
				
			||||||
 | 
					log_warnx(const char *msg, ...)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						va_list	ap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						va_start(ap, msg);
 | 
				
			||||||
 | 
						log_vwrite(LOG_CRIT, msg, ap);
 | 
				
			||||||
 | 
						va_end(ap);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Log an informational message. */
 | 
				
			||||||
 | 
					void printflike1
 | 
				
			||||||
 | 
					log_info(const char *msg, ...)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						va_list	ap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (log_level > -1) {
 | 
				
			||||||
 | 
							va_start(ap, msg);
 | 
				
			||||||
 | 
							log_vwrite(LOG_INFO, msg, ap);
 | 
				
			||||||
 | 
							va_end(ap);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Log a debug message. */
 | 
				
			||||||
 | 
					void printflike1
 | 
				
			||||||
 | 
					log_debug(const char *msg, ...)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						va_list	ap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (log_level > 0) {
 | 
				
			||||||
 | 
							va_start(ap, msg);
 | 
				
			||||||
 | 
							log_vwrite(LOG_DEBUG, msg, ap);
 | 
				
			||||||
 | 
							va_end(ap);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Log a debug message at level 2. */
 | 
				
			||||||
 | 
					void printflike1
 | 
				
			||||||
 | 
					log_debug2(const char *msg, ...)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						va_list	ap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (log_level > 1) {
 | 
				
			||||||
 | 
							va_start(ap, msg);
 | 
				
			||||||
 | 
							log_vwrite(LOG_DEBUG, msg, ap);
 | 
				
			||||||
 | 
							va_end(ap);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Log a debug message at level 3. */
 | 
				
			||||||
 | 
					void printflike1
 | 
				
			||||||
 | 
					log_debug3(const char *msg, ...)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						va_list	ap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (log_level > 2) {
 | 
				
			||||||
 | 
							va_start(ap, msg);
 | 
				
			||||||
 | 
							log_vwrite(LOG_DEBUG, msg, ap);
 | 
				
			||||||
 | 
							va_end(ap);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Log a critical error, with error string if necessary, and die. */
 | 
				
			||||||
 | 
					__dead void
 | 
				
			||||||
 | 
					log_vfatal(const char *msg, va_list ap)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char	*fmt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (errno != 0) {
 | 
				
			||||||
 | 
							if (asprintf(&fmt, "fatal: %s: %s", msg, strerror(errno)) == -1)
 | 
				
			||||||
 | 
								exit(1);
 | 
				
			||||||
 | 
							log_vwrite(LOG_CRIT, fmt, ap);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							if (asprintf(&fmt, "fatal: %s", msg) == -1)
 | 
				
			||||||
 | 
					       			exit(1);
 | 
				
			||||||
 | 
							log_vwrite(LOG_CRIT, fmt, ap);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						free(fmt);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						exit(1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Log a critical error, with error string, and die. */
 | 
				
			||||||
 | 
					__dead void printflike1
 | 
				
			||||||
 | 
					log_fatal(const char *msg, ...)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						va_list	ap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						va_start(ap, msg);
 | 
				
			||||||
 | 
						log_vfatal(msg, ap);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Log a critical error and die. */
 | 
				
			||||||
 | 
					__dead void printflike1
 | 
				
			||||||
 | 
					log_fatalx(const char *msg, ...)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						va_list	ap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						errno = 0;
 | 
				
			||||||
 | 
						va_start(ap, msg);
 | 
				
			||||||
 | 
						log_vfatal(msg, ap);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										210
									
								
								mode-key.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										210
									
								
								mode-key.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,210 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum mode_key_cmd mode_key_lookup_vi(struct mode_key_data *, int);
 | 
				
			||||||
 | 
					enum mode_key_cmd mode_key_lookup_emacs(struct mode_key_data *, int);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					mode_key_init(struct mode_key_data *mdata, int type, int flags)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						mdata->type = type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (flags & MODEKEY_CANEDIT)
 | 
				
			||||||
 | 
							flags |= MODEKEY_EDITMODE;
 | 
				
			||||||
 | 
						mdata->flags = flags;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					mode_key_free(unused struct mode_key_data *mdata)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum mode_key_cmd
 | 
				
			||||||
 | 
					mode_key_lookup(struct mode_key_data *mdata, int key)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						switch (mdata->type) {
 | 
				
			||||||
 | 
						case MODEKEY_VI:
 | 
				
			||||||
 | 
							return (mode_key_lookup_vi(mdata, key));
 | 
				
			||||||
 | 
						case MODEKEY_EMACS:
 | 
				
			||||||
 | 
							return (mode_key_lookup_emacs(mdata, key));
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							fatalx("unknown mode key type");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum mode_key_cmd
 | 
				
			||||||
 | 
					mode_key_lookup_vi(struct mode_key_data *mdata, int key)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (KEYC_ISESC(key)) {
 | 
				
			||||||
 | 
							key = KEYC_REMOVEESC(key);
 | 
				
			||||||
 | 
							if (mdata->flags & MODEKEY_CANEDIT)
 | 
				
			||||||
 | 
								mdata->flags ^= MODEKEY_EDITMODE;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (mdata->flags & MODEKEY_EDITMODE) {
 | 
				
			||||||
 | 
							switch (key) {
 | 
				
			||||||
 | 
							case '\003':
 | 
				
			||||||
 | 
								return (MODEKEYCMD_QUIT);
 | 
				
			||||||
 | 
							case '\033':
 | 
				
			||||||
 | 
								if (mdata->flags & MODEKEY_CANEDIT)
 | 
				
			||||||
 | 
									mdata->flags &= ~MODEKEY_EDITMODE;
 | 
				
			||||||
 | 
								return (MODEKEYCMD_NONE);
 | 
				
			||||||
 | 
							case '\010':
 | 
				
			||||||
 | 
							case '\177':
 | 
				
			||||||
 | 
								return (MODEKEYCMD_BACKSPACE);
 | 
				
			||||||
 | 
							case '\011':
 | 
				
			||||||
 | 
								return (MODEKEYCMD_COMPLETE);
 | 
				
			||||||
 | 
							case KEYC_DC:
 | 
				
			||||||
 | 
								return (MODEKEYCMD_DELETE);
 | 
				
			||||||
 | 
							case '\r':
 | 
				
			||||||
 | 
								return (MODEKEYCMD_CHOOSE);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return (MODEKEYCMD_OTHERKEY);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (key) {
 | 
				
			||||||
 | 
						case '\010':
 | 
				
			||||||
 | 
						case '\177':
 | 
				
			||||||
 | 
							return (MODEKEYCMD_LEFT);
 | 
				
			||||||
 | 
						case KEYC_DC:
 | 
				
			||||||
 | 
							return (MODEKEYCMD_DELETE);
 | 
				
			||||||
 | 
						case '\011':
 | 
				
			||||||
 | 
							return (MODEKEYCMD_COMPLETE);
 | 
				
			||||||
 | 
						case 'i':
 | 
				
			||||||
 | 
							if (mdata->flags & MODEKEY_CANEDIT)
 | 
				
			||||||
 | 
								mdata->flags |= MODEKEY_EDITMODE;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case 'a':
 | 
				
			||||||
 | 
							if (mdata->flags & MODEKEY_CANEDIT) {
 | 
				
			||||||
 | 
								mdata->flags |= MODEKEY_EDITMODE;
 | 
				
			||||||
 | 
								return (MODEKEYCMD_RIGHT);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case '\r':
 | 
				
			||||||
 | 
							if (mdata->flags & (MODEKEY_CANEDIT|MODEKEY_CHOOSEMODE))
 | 
				
			||||||
 | 
								return (MODEKEYCMD_CHOOSE);
 | 
				
			||||||
 | 
							return (MODEKEYCMD_COPYSELECTION);
 | 
				
			||||||
 | 
						case '0':
 | 
				
			||||||
 | 
						case '^':
 | 
				
			||||||
 | 
							return (MODEKEYCMD_STARTOFLINE);
 | 
				
			||||||
 | 
						case '\033':
 | 
				
			||||||
 | 
							return (MODEKEYCMD_CLEARSELECTION);
 | 
				
			||||||
 | 
						case 'j':
 | 
				
			||||||
 | 
						case KEYC_DOWN:
 | 
				
			||||||
 | 
							return (MODEKEYCMD_DOWN);
 | 
				
			||||||
 | 
						case '$':
 | 
				
			||||||
 | 
							return (MODEKEYCMD_ENDOFLINE);
 | 
				
			||||||
 | 
						case 'h':
 | 
				
			||||||
 | 
						case KEYC_LEFT:
 | 
				
			||||||
 | 
							return (MODEKEYCMD_LEFT);
 | 
				
			||||||
 | 
						case '\006':
 | 
				
			||||||
 | 
						case KEYC_NPAGE:
 | 
				
			||||||
 | 
							return (MODEKEYCMD_NEXTPAGE);
 | 
				
			||||||
 | 
						case 'w':
 | 
				
			||||||
 | 
							return (MODEKEYCMD_NEXTWORD);
 | 
				
			||||||
 | 
						case '\025':
 | 
				
			||||||
 | 
						case KEYC_PPAGE:
 | 
				
			||||||
 | 
							return (MODEKEYCMD_PREVIOUSPAGE);
 | 
				
			||||||
 | 
						case 'b':
 | 
				
			||||||
 | 
							return (MODEKEYCMD_PREVIOUSWORD);
 | 
				
			||||||
 | 
						case 'q':
 | 
				
			||||||
 | 
						case '\003':
 | 
				
			||||||
 | 
							return (MODEKEYCMD_QUIT);
 | 
				
			||||||
 | 
						case 'l':
 | 
				
			||||||
 | 
						case KEYC_RIGHT:
 | 
				
			||||||
 | 
							return (MODEKEYCMD_RIGHT);
 | 
				
			||||||
 | 
						case ' ':
 | 
				
			||||||
 | 
							return (MODEKEYCMD_STARTSELECTION);
 | 
				
			||||||
 | 
						case 'k':
 | 
				
			||||||
 | 
						case KEYC_UP:
 | 
				
			||||||
 | 
							return (MODEKEYCMD_UP);
 | 
				
			||||||
 | 
						case 'p':
 | 
				
			||||||
 | 
							return (MODEKEYCMD_PASTE);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (MODEKEYCMD_NONE);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum mode_key_cmd
 | 
				
			||||||
 | 
					mode_key_lookup_emacs(struct mode_key_data *mdata, int key)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						switch (key) {
 | 
				
			||||||
 | 
						case '\010':
 | 
				
			||||||
 | 
						case '\177':
 | 
				
			||||||
 | 
							return (MODEKEYCMD_BACKSPACE);
 | 
				
			||||||
 | 
						case KEYC_DC:
 | 
				
			||||||
 | 
							return (MODEKEYCMD_DELETE);
 | 
				
			||||||
 | 
						case '\011':
 | 
				
			||||||
 | 
							return (MODEKEYCMD_COMPLETE);
 | 
				
			||||||
 | 
						case '\r':
 | 
				
			||||||
 | 
							return (MODEKEYCMD_CHOOSE);
 | 
				
			||||||
 | 
						case '\001':
 | 
				
			||||||
 | 
							return (MODEKEYCMD_STARTOFLINE);
 | 
				
			||||||
 | 
						case '\007':
 | 
				
			||||||
 | 
							return (MODEKEYCMD_CLEARSELECTION);
 | 
				
			||||||
 | 
						case '\027':
 | 
				
			||||||
 | 
						case KEYC_ADDESC('w'):
 | 
				
			||||||
 | 
							return (MODEKEYCMD_COPYSELECTION);
 | 
				
			||||||
 | 
						case '\016':
 | 
				
			||||||
 | 
						case KEYC_DOWN:
 | 
				
			||||||
 | 
							return (MODEKEYCMD_DOWN);
 | 
				
			||||||
 | 
						case '\005':
 | 
				
			||||||
 | 
							return (MODEKEYCMD_ENDOFLINE);
 | 
				
			||||||
 | 
						case '\002':
 | 
				
			||||||
 | 
						case KEYC_LEFT:
 | 
				
			||||||
 | 
							return (MODEKEYCMD_LEFT);
 | 
				
			||||||
 | 
						case ' ':
 | 
				
			||||||
 | 
							if (mdata->flags & MODEKEY_CANEDIT)
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							/* FALLTHROUGH */
 | 
				
			||||||
 | 
						case '\026':
 | 
				
			||||||
 | 
						case KEYC_NPAGE:
 | 
				
			||||||
 | 
							return (MODEKEYCMD_NEXTPAGE);
 | 
				
			||||||
 | 
						case KEYC_ADDESC('f'):
 | 
				
			||||||
 | 
							return (MODEKEYCMD_NEXTWORD);
 | 
				
			||||||
 | 
						case '\031':
 | 
				
			||||||
 | 
							return (MODEKEYCMD_PASTE);
 | 
				
			||||||
 | 
						case KEYC_ADDESC('v'):
 | 
				
			||||||
 | 
						case KEYC_PPAGE:
 | 
				
			||||||
 | 
							return (MODEKEYCMD_PREVIOUSPAGE);
 | 
				
			||||||
 | 
						case KEYC_ADDESC('b'):
 | 
				
			||||||
 | 
							return (MODEKEYCMD_PREVIOUSWORD);
 | 
				
			||||||
 | 
						case '\006':
 | 
				
			||||||
 | 
						case KEYC_RIGHT:
 | 
				
			||||||
 | 
							return (MODEKEYCMD_RIGHT);
 | 
				
			||||||
 | 
						case '\000':
 | 
				
			||||||
 | 
							return (MODEKEYCMD_STARTSELECTION);
 | 
				
			||||||
 | 
						case '\020':
 | 
				
			||||||
 | 
						case KEYC_UP:
 | 
				
			||||||
 | 
							return (MODEKEYCMD_UP);
 | 
				
			||||||
 | 
						case 'q':
 | 
				
			||||||
 | 
							if (mdata->flags & MODEKEY_CANEDIT)
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							/* FALLTHROUGH */
 | 
				
			||||||
 | 
						case '\003':
 | 
				
			||||||
 | 
						case '\033':
 | 
				
			||||||
 | 
							return (MODEKEYCMD_QUIT);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (MODEKEYCMD_OTHERKEY);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										110
									
								
								names.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								names.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,110 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <ctype.h>
 | 
				
			||||||
 | 
					#include <libgen.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					char	*parse_window_name(const char *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					set_window_names(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct window	*w;
 | 
				
			||||||
 | 
						u_int		 i;
 | 
				
			||||||
 | 
						char		*name, *wname;
 | 
				
			||||||
 | 
						struct timeval	 tv, tv2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (gettimeofday(&tv, NULL) != 0)
 | 
				
			||||||
 | 
							fatal("gettimeofday");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
 | 
				
			||||||
 | 
							w = ARRAY_ITEM(&windows, i);
 | 
				
			||||||
 | 
							if (w == NULL || w->active == NULL)
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							if (!options_get_number(&w->options, "automatic-rename"))
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (timercmp(&tv, &w->name_timer, <))
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							memcpy(&w->name_timer, &tv, sizeof w->name_timer);
 | 
				
			||||||
 | 
							tv2.tv_sec = 0;
 | 
				
			||||||
 | 
							tv2.tv_usec = NAME_INTERVAL * 1000L;
 | 
				
			||||||
 | 
							timeradd(&w->name_timer, &tv2, &w->name_timer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (w->active->screen != &w->active->base)
 | 
				
			||||||
 | 
								name = NULL;
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								name = get_proc_name(w->active->fd, w->active->tty);
 | 
				
			||||||
 | 
							if (name == NULL)
 | 
				
			||||||
 | 
								wname = default_window_name(w);
 | 
				
			||||||
 | 
							else {
 | 
				
			||||||
 | 
								wname = parse_window_name(name);
 | 
				
			||||||
 | 
								xfree(name);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (strcmp(wname, w->name) == 0)
 | 
				
			||||||
 | 
								xfree(wname);
 | 
				
			||||||
 | 
							else {
 | 
				
			||||||
 | 
								xfree(w->name);
 | 
				
			||||||
 | 
								w->name = wname;
 | 
				
			||||||
 | 
								server_status_window(w);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					char *
 | 
				
			||||||
 | 
					default_window_name(struct window *w)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (w->active->screen != &w->active->base)
 | 
				
			||||||
 | 
							return (xstrdup("[tmux]"));
 | 
				
			||||||
 | 
						return (parse_window_name(w->active->cmd));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					char *
 | 
				
			||||||
 | 
					parse_window_name(const char *in)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char	*copy, *name, *ptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						name = copy = xstrdup(in);
 | 
				
			||||||
 | 
						if (strncmp(name, "exec ", (sizeof "exec ") - 1) == 0)
 | 
				
			||||||
 | 
							name = name + (sizeof "exec ") - 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while (*name == ' ')
 | 
				
			||||||
 | 
							name++;
 | 
				
			||||||
 | 
						if ((ptr = strchr(name, ' ')) != NULL)
 | 
				
			||||||
 | 
							*ptr = '\0';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (*name != '\0') {
 | 
				
			||||||
 | 
							ptr = name + strlen(name) - 1;
 | 
				
			||||||
 | 
							while (ptr > name && !isalnum(*ptr))
 | 
				
			||||||
 | 
								*ptr-- = '\0';
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (*name == '/')
 | 
				
			||||||
 | 
							name = basename(name);
 | 
				
			||||||
 | 
						name = xstrdup(name);
 | 
				
			||||||
 | 
						xfree(copy);
 | 
				
			||||||
 | 
						return (name);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										182
									
								
								options-cmd.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										182
									
								
								options-cmd.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,182 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					set_option_string(struct cmd_ctx *ctx, struct options *oo,
 | 
				
			||||||
 | 
					    const struct set_option_entry *entry, char *value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (value == NULL) {
 | 
				
			||||||
 | 
							ctx->error(ctx, "empty value");
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						options_set_string(oo, entry->name, "%s", value);
 | 
				
			||||||
 | 
						ctx->info(ctx, "set option: %s -> %s", entry->name, value);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					set_option_number(struct cmd_ctx *ctx, struct options *oo,
 | 
				
			||||||
 | 
					    const struct set_option_entry *entry, char *value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						long long	number;
 | 
				
			||||||
 | 
						const char     *errstr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (value == NULL) {
 | 
				
			||||||
 | 
							ctx->error(ctx, "empty value");
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						number = strtonum(value, entry->minimum, entry->maximum, &errstr);
 | 
				
			||||||
 | 
						if (errstr != NULL) {
 | 
				
			||||||
 | 
							ctx->error(ctx, "value is %s: %s", errstr, value);
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						options_set_number(oo, entry->name, number);
 | 
				
			||||||
 | 
						ctx->info(ctx, "set option: %s -> %lld", entry->name, number);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					set_option_key(struct cmd_ctx *ctx, struct options *oo,
 | 
				
			||||||
 | 
					    const struct set_option_entry *entry, char *value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int	key;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (value == NULL) {
 | 
				
			||||||
 | 
							ctx->error(ctx, "empty value");
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((key = key_string_lookup_string(value)) == KEYC_NONE) {
 | 
				
			||||||
 | 
							ctx->error(ctx, "unknown key: %s", value);
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						options_set_number(oo, entry->name, key);
 | 
				
			||||||
 | 
						ctx->info(ctx,
 | 
				
			||||||
 | 
						    "set option: %s -> %s", entry->name, key_string_lookup_key(key));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					set_option_colour(struct cmd_ctx *ctx, struct options *oo,
 | 
				
			||||||
 | 
					    const struct set_option_entry *entry, char *value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int	colour;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (value == NULL) {
 | 
				
			||||||
 | 
							ctx->error(ctx, "empty value");
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((colour = colour_fromstring(value)) == -1) {
 | 
				
			||||||
 | 
							ctx->error(ctx, "bad colour: %s", value);
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						options_set_number(oo, entry->name, colour);
 | 
				
			||||||
 | 
						ctx->info(ctx,
 | 
				
			||||||
 | 
						    "set option: %s -> %s", entry->name, colour_tostring(colour));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					set_option_attributes(struct cmd_ctx *ctx, struct options *oo,
 | 
				
			||||||
 | 
					    const struct set_option_entry *entry, char *value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int	attr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (value == NULL) {
 | 
				
			||||||
 | 
							ctx->error(ctx, "empty value");
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((attr = attributes_fromstring(value)) == -1) {
 | 
				
			||||||
 | 
							ctx->error(ctx, "bad attributes: %s", value);
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						options_set_number(oo, entry->name, attr);
 | 
				
			||||||
 | 
						ctx->info(ctx,
 | 
				
			||||||
 | 
						    "set option: %s -> %s", entry->name, attributes_tostring(attr));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					set_option_flag(struct cmd_ctx *ctx, struct options *oo,
 | 
				
			||||||
 | 
					    const struct set_option_entry *entry, char *value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int	flag;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (value == NULL || *value == '\0')
 | 
				
			||||||
 | 
							flag = !options_get_number(oo, entry->name);
 | 
				
			||||||
 | 
						else {
 | 
				
			||||||
 | 
							if ((value[0] == '1' && value[1] == '\0') ||
 | 
				
			||||||
 | 
							    strcasecmp(value, "on") == 0 ||
 | 
				
			||||||
 | 
							    strcasecmp(value, "yes") == 0)
 | 
				
			||||||
 | 
								flag = 1;
 | 
				
			||||||
 | 
							else if ((value[0] == '0' && value[1] == '\0') ||
 | 
				
			||||||
 | 
							    strcasecmp(value, "off") == 0 ||
 | 
				
			||||||
 | 
							    strcasecmp(value, "no") == 0)
 | 
				
			||||||
 | 
								flag = 0;
 | 
				
			||||||
 | 
							else {
 | 
				
			||||||
 | 
								ctx->error(ctx, "bad value: %s", value);
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						options_set_number(oo, entry->name, flag);
 | 
				
			||||||
 | 
						ctx->info(ctx,
 | 
				
			||||||
 | 
						    "set option: %s -> %s", entry->name, flag ? "on" : "off");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					set_option_choice(struct cmd_ctx *ctx, struct options *oo,
 | 
				
			||||||
 | 
					    const struct set_option_entry *entry, char *value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const char     **choicep;
 | 
				
			||||||
 | 
						int		 n, choice = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (value == NULL) {
 | 
				
			||||||
 | 
							ctx->error(ctx, "empty value");
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						n = 0;
 | 
				
			||||||
 | 
						for (choicep = entry->choices; *choicep != NULL; choicep++) {
 | 
				
			||||||
 | 
							n++;
 | 
				
			||||||
 | 
							if (strncmp(*choicep, value, strlen(value)) != 0)
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (choice != -1) {
 | 
				
			||||||
 | 
								ctx->error(ctx, "ambiguous option: %s", value);
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							choice = n - 1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (choice == -1) {
 | 
				
			||||||
 | 
							ctx->error(ctx, "unknown option: %s", value);
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						options_set_number(oo, entry->name, choice);
 | 
				
			||||||
 | 
						ctx->info(ctx,
 | 
				
			||||||
 | 
						    "set option: %s -> %s", entry->name, entry->choices[choice]);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										160
									
								
								options.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										160
									
								
								options.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,160 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdarg.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Option handling; each option has a name, type and value and is stored in
 | 
				
			||||||
 | 
					 * a splay tree.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SPLAY_GENERATE(options_tree, options_entry, entry, options_cmp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					options_cmp(struct options_entry *o1, struct options_entry *o2)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return (strcmp(o1->name, o2->name));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					options_init(struct options *oo, struct options *parent)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						SPLAY_INIT(&oo->tree);
 | 
				
			||||||
 | 
						oo->parent = parent;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					options_free(struct options *oo)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct options_entry	*o;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while (!SPLAY_EMPTY(&oo->tree)) {
 | 
				
			||||||
 | 
							o = SPLAY_ROOT(&oo->tree);
 | 
				
			||||||
 | 
							SPLAY_REMOVE(options_tree, &oo->tree, o);
 | 
				
			||||||
 | 
							xfree(o->name);
 | 
				
			||||||
 | 
							if (o->type == OPTIONS_STRING)
 | 
				
			||||||
 | 
								xfree(o->value.string);
 | 
				
			||||||
 | 
							xfree(o);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct options_entry *
 | 
				
			||||||
 | 
					options_find1(struct options *oo, const char *name)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct options_entry	p;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						p.name = (char *) name;
 | 
				
			||||||
 | 
						return (SPLAY_FIND(options_tree, &oo->tree, &p));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct options_entry *
 | 
				
			||||||
 | 
					options_find(struct options *oo, const char *name)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct options_entry	*o, p;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						p.name = (char *) name;
 | 
				
			||||||
 | 
						o = SPLAY_FIND(options_tree, &oo->tree, &p);
 | 
				
			||||||
 | 
						while (o == NULL) {
 | 
				
			||||||
 | 
							oo = oo->parent;
 | 
				
			||||||
 | 
							if (oo == NULL)
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							o = SPLAY_FIND(options_tree, &oo->tree, &p);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return (o);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					options_remove(struct options *oo, const char *name)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct options_entry	*o;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((o = options_find1(oo, name)) == NULL)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						SPLAY_REMOVE(options_tree, &oo->tree, o);
 | 
				
			||||||
 | 
						xfree(o->name);
 | 
				
			||||||
 | 
						if (o->type == OPTIONS_STRING)
 | 
				
			||||||
 | 
							xfree(o->value.string);
 | 
				
			||||||
 | 
						xfree(o);
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void printflike3
 | 
				
			||||||
 | 
					options_set_string(struct options *oo, const char *name, const char *fmt, ...)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct options_entry	*o;
 | 
				
			||||||
 | 
						va_list			 ap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((o = options_find1(oo, name)) == NULL) {
 | 
				
			||||||
 | 
							o = xmalloc(sizeof *o);
 | 
				
			||||||
 | 
							o->name = xstrdup(name);
 | 
				
			||||||
 | 
							SPLAY_INSERT(options_tree, &oo->tree, o);
 | 
				
			||||||
 | 
						} else if (o->type == OPTIONS_STRING)
 | 
				
			||||||
 | 
							xfree(o->value.string);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						va_start(ap, fmt);
 | 
				
			||||||
 | 
						o->type = OPTIONS_STRING;
 | 
				
			||||||
 | 
						xvasprintf(&o->value.string, fmt, ap);
 | 
				
			||||||
 | 
						va_end(ap);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					char *
 | 
				
			||||||
 | 
					options_get_string(struct options *oo, const char *name)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct options_entry	*o;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((o = options_find(oo, name)) == NULL)
 | 
				
			||||||
 | 
							fatalx("missing option");
 | 
				
			||||||
 | 
						if (o->type != OPTIONS_STRING)
 | 
				
			||||||
 | 
							fatalx("option not a string");
 | 
				
			||||||
 | 
						return (o->value.string);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					options_set_number(struct options *oo, const char *name, long long value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct options_entry	*o;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((o = options_find1(oo, name)) == NULL) {
 | 
				
			||||||
 | 
							o = xmalloc(sizeof *o);
 | 
				
			||||||
 | 
							o->name = xstrdup(name);
 | 
				
			||||||
 | 
							SPLAY_INSERT(options_tree, &oo->tree, o);
 | 
				
			||||||
 | 
						} else if (o->type == OPTIONS_STRING)
 | 
				
			||||||
 | 
							xfree(o->value.string);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						o->type = OPTIONS_NUMBER;
 | 
				
			||||||
 | 
						o->value.number = value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					long long
 | 
				
			||||||
 | 
					options_get_number(struct options *oo, const char *name)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct options_entry	*o;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((o = options_find(oo, name)) == NULL)
 | 
				
			||||||
 | 
							fatalx("missing option");
 | 
				
			||||||
 | 
						if (o->type != OPTIONS_NUMBER)
 | 
				
			||||||
 | 
							fatalx("option not a number");
 | 
				
			||||||
 | 
						return (o->value.number);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										131
									
								
								paste.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										131
									
								
								paste.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,131 @@
 | 
				
			|||||||
 | 
					/* $OpenBSD$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Permission to use, copy, modify, and distribute this software for any
 | 
				
			||||||
 | 
					 * purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 * copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
				
			||||||
 | 
					 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
				
			||||||
 | 
					 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
				
			||||||
 | 
					 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					#include <sys/time.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "tmux.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					paste_init_stack(struct paste_stack *ps)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						ARRAY_INIT(ps);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					paste_free_stack(struct paste_stack *ps)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						while (paste_free_top(ps) == 0)
 | 
				
			||||||
 | 
							;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct paste_buffer *
 | 
				
			||||||
 | 
					paste_walk_stack(struct paste_stack *ps, uint *idx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct paste_buffer	*pb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pb = paste_get_index(ps, *idx);
 | 
				
			||||||
 | 
						(*idx)++;
 | 
				
			||||||
 | 
						return (pb);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct paste_buffer *
 | 
				
			||||||
 | 
					paste_get_top(struct paste_stack *ps)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (ARRAY_LENGTH(ps) == 0)
 | 
				
			||||||
 | 
							return (NULL);
 | 
				
			||||||
 | 
						return (ARRAY_FIRST(ps));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct paste_buffer *
 | 
				
			||||||
 | 
					paste_get_index(struct paste_stack *ps, u_int idx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (idx >= ARRAY_LENGTH(ps))
 | 
				
			||||||
 | 
							return (NULL);
 | 
				
			||||||
 | 
						return (ARRAY_ITEM(ps, idx));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					paste_free_top(struct paste_stack *ps)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct paste_buffer	*pb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (ARRAY_LENGTH(ps) == 0)
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pb = ARRAY_FIRST(ps);
 | 
				
			||||||
 | 
						ARRAY_REMOVE(ps, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						xfree(pb->data);
 | 
				
			||||||
 | 
						xfree(pb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					paste_free_index(struct paste_stack *ps, u_int idx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct paste_buffer	*pb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (idx >= ARRAY_LENGTH(ps))
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pb = ARRAY_ITEM(ps, idx);
 | 
				
			||||||
 | 
						ARRAY_REMOVE(ps, idx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						xfree(pb->data);
 | 
				
			||||||
 | 
						xfree(pb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					paste_add(struct paste_stack *ps, char *data, u_int limit)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct paste_buffer	*pb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while (ARRAY_LENGTH(ps) >= limit)
 | 
				
			||||||
 | 
							ARRAY_TRUNC(ps, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pb = xmalloc(sizeof *pb);
 | 
				
			||||||
 | 
						ARRAY_INSERT(ps, 0, pb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pb->data = data;
 | 
				
			||||||
 | 
						if (gettimeofday(&pb->tv, NULL) != 0)
 | 
				
			||||||
 | 
							fatal("gettimeofday");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					paste_replace(struct paste_stack *ps, u_int idx, char *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct paste_buffer	*pb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (idx >= ARRAY_LENGTH(ps))
 | 
				
			||||||
 | 
							return (-1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pb = ARRAY_ITEM(ps, idx);
 | 
				
			||||||
 | 
						xfree(pb->data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pb->data = data;
 | 
				
			||||||
 | 
						if (gettimeofday(&pb->tv, NULL) != 0)
 | 
				
			||||||
 | 
							fatal("gettimeofday");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user