mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-04 09:26:05 +00:00 
			
		
		
		
	Move command handling into the server and tidy up some bits.
This commit is contained in:
		
							
								
								
									
										7
									
								
								CHANGES
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								CHANGES
									
									
									
									
									
								
							@@ -1,3 +1,8 @@
 | 
			
		||||
03 October 2007
 | 
			
		||||
 | 
			
		||||
* (nicm) Move command parsing into the client. Also rename some messages and
 | 
			
		||||
  tidy up a few bits. Lots more tidying up needed :-/.
 | 
			
		||||
 | 
			
		||||
02 October 2007
 | 
			
		||||
 | 
			
		||||
* (nicm) Redraw client status lines on rename.
 | 
			
		||||
@@ -90,5 +95,5 @@
 | 
			
		||||
  (including mutt, emacs). No status bar yet and no key remapping or other
 | 
			
		||||
  customisation.
 | 
			
		||||
 | 
			
		||||
$Id: CHANGES,v 1.22 2007-10-02 17:45:05 nicm Exp $
 | 
			
		||||
$Id: CHANGES,v 1.23 2007-10-03 10:18:31 nicm Exp $
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										6
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								Makefile
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
# $Id: Makefile,v 1.10 2007-10-03 00:13:46 nicm Exp $
 | 
			
		||||
# $Id: Makefile,v 1.11 2007-10-03 10:18:31 nicm Exp $
 | 
			
		||||
 | 
			
		||||
.SUFFIXES: .c .o .y .h
 | 
			
		||||
.PHONY: clean
 | 
			
		||||
@@ -17,8 +17,8 @@ DEBUG=
 | 
			
		||||
META?= \002 # C-b
 | 
			
		||||
 | 
			
		||||
SRCS= tmux.c server.c server-msg.c server-fn.c buffer.c buffer-poll.c status.c \
 | 
			
		||||
      xmalloc.c xmalloc-debug.c input.c input-keys.c screen.c window.c \
 | 
			
		||||
      session.c local.c log.c client.c client-msg.c client-cmd.c op.c op-list.c
 | 
			
		||||
      xmalloc.c xmalloc-debug.c cmd.c input.c input-keys.c screen.c window.c \
 | 
			
		||||
      session.c local.c log.c client.c client-msg.c client-fn.c op.c op-list.c
 | 
			
		||||
 | 
			
		||||
YACC= yacc -d
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										5
									
								
								TODO
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								TODO
									
									
									
									
									
								
							@@ -27,8 +27,8 @@
 | 
			
		||||
- decide about customised status line
 | 
			
		||||
- rethink data structures. window->index is O(n), could have a w->idx member
 | 
			
		||||
	or use queues/trees and avoid NULLs?
 | 
			
		||||
- client could pass tty fd up to server and then do nothing. what problems 
 | 
			
		||||
  would this cause?
 | 
			
		||||
- client could pass term/tty fd up to server and then do nothing. what problems 
 | 
			
		||||
  would this cause? -- need access to all terminfo data at once... signals?
 | 
			
		||||
- cleanup/redesign IPC
 | 
			
		||||
	IPC is arse-about-face: too much overhead. 8-byte header for each
 | 
			
		||||
	packet... hrm. already scanning output for \e, could add an extra
 | 
			
		||||
@@ -52,3 +52,4 @@
 | 
			
		||||
- fix resize (width problems with multiple clients?)
 | 
			
		||||
- handle tmux in tmux (check $TMUX and abort)
 | 
			
		||||
- check for some reqd terminfo caps on startup
 | 
			
		||||
- sort out the pause mess
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										119
									
								
								client-cmd.c
									
									
									
									
									
								
							
							
						
						
									
										119
									
								
								client-cmd.c
									
									
									
									
									
								
							@@ -1,119 +0,0 @@
 | 
			
		||||
/* $Id: client-cmd.c,v 1.7 2007-10-02 15:38:09 nicm Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * 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"
 | 
			
		||||
 | 
			
		||||
int	client_cmd_prefix = META;
 | 
			
		||||
 | 
			
		||||
int	client_cmd_fn_msg(int, struct client_ctx *, char **);
 | 
			
		||||
int	client_cmd_fn_select(int, struct client_ctx *, char **);
 | 
			
		||||
int	client_cmd_fn_detach(int, struct client_ctx *, char **);
 | 
			
		||||
int	client_cmd_fn_meta(int, struct client_ctx *, char **);
 | 
			
		||||
 | 
			
		||||
struct cmd {
 | 
			
		||||
	int	key;
 | 
			
		||||
	int	(*fn)(int, struct client_ctx *, char **);
 | 
			
		||||
	int	arg;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct cmd client_cmd_table[] = {
 | 
			
		||||
	{ '0', client_cmd_fn_select, 0 },
 | 
			
		||||
	{ '1', client_cmd_fn_select, 1 },
 | 
			
		||||
	{ '2', client_cmd_fn_select, 2 },
 | 
			
		||||
	{ '3', client_cmd_fn_select, 3 },
 | 
			
		||||
	{ '4', client_cmd_fn_select, 4 },
 | 
			
		||||
	{ '5', client_cmd_fn_select, 5 },
 | 
			
		||||
	{ '6', client_cmd_fn_select, 6 },
 | 
			
		||||
	{ '7', client_cmd_fn_select, 7 },
 | 
			
		||||
	{ '8', client_cmd_fn_select, 8 },
 | 
			
		||||
	{ '9', client_cmd_fn_select, 9 },
 | 
			
		||||
	{ 'C', client_cmd_fn_msg, MSG_CREATE },
 | 
			
		||||
	{ 'c', client_cmd_fn_msg, MSG_CREATE },
 | 
			
		||||
	{ 'D', client_cmd_fn_detach, 0 },
 | 
			
		||||
	{ 'd', client_cmd_fn_detach, 0 },
 | 
			
		||||
	{ 'N', client_cmd_fn_msg, MSG_NEXT },
 | 
			
		||||
	{ 'n', client_cmd_fn_msg, MSG_NEXT },
 | 
			
		||||
	{ 'P', client_cmd_fn_msg, MSG_PREVIOUS },
 | 
			
		||||
	{ 'p', client_cmd_fn_msg, MSG_PREVIOUS },
 | 
			
		||||
	{ 'R', client_cmd_fn_msg, MSG_REFRESH },
 | 
			
		||||
	{ 'r', client_cmd_fn_msg, MSG_REFRESH },
 | 
			
		||||
	{ 'L', client_cmd_fn_msg, MSG_LAST },
 | 
			
		||||
	{ 'l', client_cmd_fn_msg, MSG_LAST },
 | 
			
		||||
	{ 'W', client_cmd_fn_msg, MSG_WINDOWLIST },
 | 
			
		||||
	{ 'w', client_cmd_fn_msg, MSG_WINDOWLIST },
 | 
			
		||||
	{ 'I', client_cmd_fn_msg, MSG_WINDOWINFO },
 | 
			
		||||
	{ 'i', client_cmd_fn_msg, MSG_WINDOWINFO },
 | 
			
		||||
	{ META, client_cmd_fn_meta, 0 },
 | 
			
		||||
};
 | 
			
		||||
#define NCLIENTCMD (sizeof client_cmd_table / sizeof client_cmd_table[0])
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
client_cmd_dispatch(int key, struct client_ctx *cctx, char **error)
 | 
			
		||||
{
 | 
			
		||||
	struct cmd	*cmd;
 | 
			
		||||
	u_int		 i;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < NCLIENTCMD; i++) {
 | 
			
		||||
		cmd = client_cmd_table + i;
 | 
			
		||||
		if (cmd->key == key)
 | 
			
		||||
			return (cmd->fn(cmd->arg, cctx, error));
 | 
			
		||||
	}
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Handle generic command. */
 | 
			
		||||
int
 | 
			
		||||
client_cmd_fn_msg(int arg, struct client_ctx *cctx, unused char **error)
 | 
			
		||||
{
 | 
			
		||||
	client_write_server(cctx, arg, NULL, 0);
 | 
			
		||||
 | 
			
		||||
 	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Handle select command. */
 | 
			
		||||
int
 | 
			
		||||
client_cmd_fn_select(int arg, struct client_ctx *cctx, unused char **error)
 | 
			
		||||
{
 | 
			
		||||
	struct select_data	data;
 | 
			
		||||
 | 
			
		||||
	data.idx = arg;
 | 
			
		||||
	client_write_server(cctx, MSG_SELECT, &data, sizeof data);
 | 
			
		||||
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Handle detach command. */
 | 
			
		||||
int
 | 
			
		||||
client_cmd_fn_detach(
 | 
			
		||||
    unused int arg, unused struct client_ctx *cctx, unused char **error)
 | 
			
		||||
{
 | 
			
		||||
	return (-1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Handle meta command. */
 | 
			
		||||
int
 | 
			
		||||
client_cmd_fn_meta(unused int arg, struct client_ctx *cctx, unused char **error)
 | 
			
		||||
{
 | 
			
		||||
	uint8_t	key = META;
 | 
			
		||||
 | 
			
		||||
	client_write_server(cctx, MSG_INPUT, &key, sizeof key);
 | 
			
		||||
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										67
									
								
								client-fn.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								client-fn.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,67 @@
 | 
			
		||||
/* $Id: client-fn.c,v 1.1 2007-10-03 10:18:31 nicm Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * 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_sessid(struct sessid *sid, char name[MAXNAMELEN])
 | 
			
		||||
{
 | 
			
		||||
	char		*env, *ptr, buf[256];
 | 
			
		||||
	const char	*errstr;
 | 
			
		||||
	long long	 ll;
 | 
			
		||||
 | 
			
		||||
	strlcpy(sid->name, name, sizeof sid->name);
 | 
			
		||||
 | 
			
		||||
	sid->pid = -1;
 | 
			
		||||
	if ((env = getenv("TMUX")) == NULL)
 | 
			
		||||
		return;
 | 
			
		||||
	if ((ptr = strchr(env, ',')) == NULL)
 | 
			
		||||
		return;
 | 
			
		||||
	if ((size_t) (ptr - env) > sizeof buf)
 | 
			
		||||
		return;
 | 
			
		||||
	memcpy(buf, env, ptr - env);
 | 
			
		||||
	buf[ptr - env] = '\0';
 | 
			
		||||
 | 
			
		||||
	ll = strtonum(ptr + 1, 0, UINT_MAX, &errstr);
 | 
			
		||||
	if (errstr != NULL)
 | 
			
		||||
		return;
 | 
			
		||||
	sid->idx = ll;
 | 
			
		||||
 | 
			
		||||
	ll = strtonum(buf, 0, LLONG_MAX, &errstr);
 | 
			
		||||
	if (errstr != NULL)
 | 
			
		||||
		return;
 | 
			
		||||
	sid->pid = 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 (len > 0)
 | 
			
		||||
		buffer_write(cctx->srv_out, buf, len);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										51
									
								
								client-msg.c
									
									
									
									
									
								
							
							
						
						
									
										51
									
								
								client-msg.c
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: client-msg.c,v 1.4 2007-09-29 14:57:07 nicm Exp $ */
 | 
			
		||||
/* $Id: client-msg.c,v 1.5 2007-10-03 10:18:31 nicm Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -24,11 +24,11 @@
 | 
			
		||||
 | 
			
		||||
#include "tmux.h"
 | 
			
		||||
 | 
			
		||||
int	client_msg_fn_output(struct hdr *, struct client_ctx *, char **);
 | 
			
		||||
int	client_msg_fn_pause(struct hdr *, struct client_ctx *, char **);
 | 
			
		||||
int	client_msg_fn_done(struct hdr *, struct client_ctx *, char **);
 | 
			
		||||
int	client_msg_fn_exit(struct hdr *, struct client_ctx *, char **);
 | 
			
		||||
int	client_msg_fn_data(struct hdr *, struct client_ctx *, char **);
 | 
			
		||||
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_okay(struct hdr *, struct client_ctx *, char **);
 | 
			
		||||
int	client_msg_fn_pause(struct hdr *, struct client_ctx *, char **);
 | 
			
		||||
 | 
			
		||||
struct client_msg {
 | 
			
		||||
	enum hdrtype   type;
 | 
			
		||||
@@ -36,11 +36,11 @@ struct client_msg {
 | 
			
		||||
	int	       (*fn)(struct hdr *, struct client_ctx *, char **);
 | 
			
		||||
};
 | 
			
		||||
struct client_msg client_msg_table[] = {
 | 
			
		||||
	{ MSG_OUTPUT, client_msg_fn_output },
 | 
			
		||||
	{ MSG_PAUSE, client_msg_fn_pause },
 | 
			
		||||
	{ MSG_DONE, client_msg_fn_done },
 | 
			
		||||
	{ MSG_EXIT, client_msg_fn_exit },
 | 
			
		||||
	{ MSG_DATA, client_msg_fn_data },
 | 
			
		||||
	{ MSG_DETACH, client_msg_fn_detach },
 | 
			
		||||
	{ MSG_ERROR, client_msg_fn_error },
 | 
			
		||||
	{ MSG_OKAY, client_msg_fn_okay },
 | 
			
		||||
	{ MSG_PAUSE, client_msg_fn_pause },
 | 
			
		||||
};
 | 
			
		||||
#define NCLIENTMSG (sizeof client_msg_table / sizeof client_msg_table[0])
 | 
			
		||||
 | 
			
		||||
@@ -73,9 +73,9 @@ client_msg_dispatch(struct client_ctx *cctx, char **error)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Output message from server. */
 | 
			
		||||
/* Data message from server. */
 | 
			
		||||
int
 | 
			
		||||
client_msg_fn_output(
 | 
			
		||||
client_msg_fn_data(
 | 
			
		||||
    struct hdr *hdr, struct client_ctx *cctx, unused char **error)
 | 
			
		||||
{
 | 
			
		||||
	local_output(cctx->srv_in, hdr->size);
 | 
			
		||||
@@ -92,23 +92,13 @@ client_msg_fn_pause(
 | 
			
		||||
	return (1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Exit message from server. */
 | 
			
		||||
/* Okay message from server. */
 | 
			
		||||
int
 | 
			
		||||
client_msg_fn_exit(
 | 
			
		||||
client_msg_fn_okay(
 | 
			
		||||
    struct hdr *hdr, unused struct client_ctx *cctx, unused char **error)
 | 
			
		||||
{
 | 
			
		||||
	if (hdr->size != 0)
 | 
			
		||||
		fatalx("bad MSG_EXIT size");
 | 
			
		||||
	return (-1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Done message from server. */
 | 
			
		||||
int
 | 
			
		||||
client_msg_fn_done(
 | 
			
		||||
    struct hdr *hdr, unused struct client_ctx *cctx, unused char **error)
 | 
			
		||||
{
 | 
			
		||||
	if (hdr->size != 0)
 | 
			
		||||
		fatalx("bad MSG_DONE size");
 | 
			
		||||
		fatalx("bad MSG_OKAY size");
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -125,3 +115,16 @@ client_msg_fn_error(struct hdr *hdr, struct client_ctx *cctx, char **error)
 | 
			
		||||
 | 
			
		||||
	return (-1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Detach message from server. */
 | 
			
		||||
int
 | 
			
		||||
client_msg_fn_detach(
 | 
			
		||||
    struct hdr *hdr, unused struct client_ctx *cctx, char **error)
 | 
			
		||||
{
 | 
			
		||||
	if (hdr->size != 0)
 | 
			
		||||
		fatalx("bad MSG_DETACH size");
 | 
			
		||||
 | 
			
		||||
	*error = NULL;
 | 
			
		||||
 | 
			
		||||
	return (-1);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										86
									
								
								client.c
									
									
									
									
									
								
							
							
						
						
									
										86
									
								
								client.c
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: client.c,v 1.9 2007-09-29 13:22:15 nicm Exp $ */
 | 
			
		||||
/* $Id: client.c,v 1.10 2007-10-03 10:18:32 nicm Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -154,7 +154,7 @@ client_flush(struct client_ctx *cctx)
 | 
			
		||||
			continue;
 | 
			
		||||
		buffer_remove(cctx->srv_in, sizeof hdr);
 | 
			
		||||
 | 
			
		||||
		if (hdr.type == MSG_DONE)
 | 
			
		||||
		if (hdr.type == MSG_OKAY)
 | 
			
		||||
			return (0);
 | 
			
		||||
		if (hdr.type == MSG_ERROR) {
 | 
			
		||||
			if (hdr.size > INT_MAX - 1)
 | 
			
		||||
@@ -241,49 +241,6 @@ local_dead:
 | 
			
		||||
	fatalx("local socket dead");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
client_fill_sessid(struct sessid *sid, char name[MAXNAMELEN])
 | 
			
		||||
{
 | 
			
		||||
	char		*env, *ptr, buf[256];
 | 
			
		||||
	const char	*errstr;
 | 
			
		||||
	long long	 ll;
 | 
			
		||||
 | 
			
		||||
	strlcpy(sid->name, name, sizeof sid->name);
 | 
			
		||||
 | 
			
		||||
	sid->pid = -1;
 | 
			
		||||
	if ((env = getenv("TMUX")) == NULL)
 | 
			
		||||
		return;
 | 
			
		||||
	if ((ptr = strchr(env, ',')) == NULL)
 | 
			
		||||
		return;
 | 
			
		||||
	if ((size_t) (ptr - env) > sizeof buf)
 | 
			
		||||
		return;
 | 
			
		||||
	memcpy(buf, env, ptr - env);
 | 
			
		||||
	buf[ptr - env] = '\0';
 | 
			
		||||
 | 
			
		||||
	ll = strtonum(ptr + 1, 0, UINT_MAX, &errstr);
 | 
			
		||||
	if (errstr != NULL)
 | 
			
		||||
		return;
 | 
			
		||||
	sid->idx = ll;
 | 
			
		||||
 | 
			
		||||
	ll = strtonum(buf, 0, LLONG_MAX, &errstr);
 | 
			
		||||
	if (errstr != NULL)
 | 
			
		||||
		return;
 | 
			
		||||
	sid->pid = 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 (len > 0)
 | 
			
		||||
		buffer_write(cctx->srv_out, buf, len);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
client_handle_winch(struct client_ctx *cctx)
 | 
			
		||||
{
 | 
			
		||||
@@ -300,39 +257,22 @@ client_handle_winch(struct client_ctx *cctx)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
client_process_local(struct client_ctx *cctx, char **error)
 | 
			
		||||
client_process_local(struct client_ctx *cctx, unused char **error)
 | 
			
		||||
{
 | 
			
		||||
	struct buffer	*b;
 | 
			
		||||
	size_t		 size;
 | 
			
		||||
	int		 n, key;
 | 
			
		||||
	int		 key;
 | 
			
		||||
 | 
			
		||||
	n = 0;
 | 
			
		||||
	b = buffer_create(BUFSIZ);
 | 
			
		||||
 | 
			
		||||
	while ((key = local_key(&size)) != KEYC_NONE) {
 | 
			
		||||
		log_debug("key code: %d", key);
 | 
			
		||||
 | 
			
		||||
		if (key == client_cmd_prefix) {
 | 
			
		||||
			if ((key = local_key(NULL)) == KEYC_NONE) {
 | 
			
		||||
				/* XXX sux */
 | 
			
		||||
				buffer_reverse_remove(cctx->loc_in, size);
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			n = client_cmd_dispatch(key, cctx, error);
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		input_store8(b, '\e');
 | 
			
		||||
		input_store16(b, (uint16_t) key /*XXX*/);
 | 
			
		||||
	}
 | 
			
		||||
	while ((key = local_key()) != KEYC_NONE)
 | 
			
		||||
		input_store16(b, (uint16_t) key);
 | 
			
		||||
 | 
			
		||||
	log_debug("transmitting %zu bytes of input", BUFFER_USED(b));
 | 
			
		||||
	if (BUFFER_USED(b) == 0) {
 | 
			
		||||
		buffer_destroy(b);
 | 
			
		||||
		return (n);
 | 
			
		||||
	}
 | 
			
		||||
	client_write_server(cctx, MSG_INPUT, BUFFER_OUT(b), BUFFER_USED(b));
 | 
			
		||||
	buffer_destroy(b);
 | 
			
		||||
	return (n);
 | 
			
		||||
	if (BUFFER_USED(b) != 0) {
 | 
			
		||||
		client_write_server(
 | 
			
		||||
		    cctx, MSG_KEYS, BUFFER_OUT(b), BUFFER_USED(b));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	buffer_destroy(b);
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										176
									
								
								cmd.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										176
									
								
								cmd.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,176 @@
 | 
			
		||||
/* $Id: cmd.c,v 1.1 2007-10-03 10:18:32 nicm Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * 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"
 | 
			
		||||
 | 
			
		||||
int	cmd_prefix = META;
 | 
			
		||||
 | 
			
		||||
void	cmd_fn_create(struct client *, int);
 | 
			
		||||
void	cmd_fn_detach(struct client *, int);
 | 
			
		||||
void	cmd_fn_last(struct client *, int);
 | 
			
		||||
void	cmd_fn_meta(struct client *, int);
 | 
			
		||||
void	cmd_fn_next(struct client *, int);
 | 
			
		||||
void	cmd_fn_previous(struct client *, int);
 | 
			
		||||
void	cmd_fn_refresh(struct client *, int);
 | 
			
		||||
void	cmd_fn_select(struct client *, int);
 | 
			
		||||
void	cmd_fn_windowinfo(struct client *, int);
 | 
			
		||||
 | 
			
		||||
struct cmd {
 | 
			
		||||
	int	key;
 | 
			
		||||
	void	(*fn)(struct client *, int);
 | 
			
		||||
	int	arg;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct cmd cmd_table[] = {
 | 
			
		||||
	{ '0', cmd_fn_select, 0 },
 | 
			
		||||
	{ '1', cmd_fn_select, 1 },
 | 
			
		||||
	{ '2', cmd_fn_select, 2 },
 | 
			
		||||
	{ '3', cmd_fn_select, 3 },
 | 
			
		||||
	{ '4', cmd_fn_select, 4 },
 | 
			
		||||
	{ '5', cmd_fn_select, 5 },
 | 
			
		||||
	{ '6', cmd_fn_select, 6 },
 | 
			
		||||
	{ '7', cmd_fn_select, 7 },
 | 
			
		||||
	{ '8', cmd_fn_select, 8 },
 | 
			
		||||
	{ '9', cmd_fn_select, 9 },
 | 
			
		||||
	{ 'C', cmd_fn_create, 0 },
 | 
			
		||||
	{ 'c', cmd_fn_create, 0 },
 | 
			
		||||
	{ 'D', cmd_fn_detach, 0 },
 | 
			
		||||
	{ 'd', cmd_fn_detach, 0 },
 | 
			
		||||
	{ 'N', cmd_fn_next, 0 },
 | 
			
		||||
	{ 'n', cmd_fn_next, 0 },
 | 
			
		||||
	{ 'P', cmd_fn_previous, 0 },
 | 
			
		||||
	{ 'p', cmd_fn_previous, 0 },
 | 
			
		||||
	{ 'R', cmd_fn_refresh, 0 },
 | 
			
		||||
	{ 'r', cmd_fn_refresh, 0 },
 | 
			
		||||
	{ 'L', cmd_fn_last, 0 },
 | 
			
		||||
	{ 'l', cmd_fn_last, 0 },
 | 
			
		||||
	{ 'I', cmd_fn_windowinfo, 0 },
 | 
			
		||||
	{ 'i', cmd_fn_windowinfo, 0 },
 | 
			
		||||
	{ META, cmd_fn_meta, 0 },
 | 
			
		||||
};
 | 
			
		||||
#define NCMD (sizeof cmd_table / sizeof cmd_table[0])
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
cmd_dispatch(struct client *c, int key)
 | 
			
		||||
{
 | 
			
		||||
	struct cmd	*cmd;
 | 
			
		||||
	u_int		 i;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < NCMD; i++) {
 | 
			
		||||
		cmd = cmd_table + i;
 | 
			
		||||
		if (cmd->key == key)
 | 
			
		||||
			cmd->fn(c, cmd->arg);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
cmd_fn_create(struct client *c, unused int arg)
 | 
			
		||||
{
 | 
			
		||||
	const char	*shell;
 | 
			
		||||
	char		*cmd;
 | 
			
		||||
 | 
			
		||||
	shell = getenv("SHELL");
 | 
			
		||||
	if (shell == NULL)
 | 
			
		||||
		shell = "/bin/ksh";
 | 
			
		||||
	xasprintf(&cmd, "%s -l", shell);
 | 
			
		||||
	if (session_new(c->session, cmd, c->sx, c->sy) != 0)
 | 
			
		||||
		fatalx("session_new failed");
 | 
			
		||||
	xfree(cmd);
 | 
			
		||||
 | 
			
		||||
	server_draw_client(c, 0, c->sy - 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
cmd_fn_detach(struct client *c, unused int arg)
 | 
			
		||||
{
 | 
			
		||||
	server_write_client(c, MSG_DETACH, NULL, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
cmd_fn_last(struct client *c, unused int arg)
 | 
			
		||||
{
 | 
			
		||||
	if (session_last(c->session) == 0)
 | 
			
		||||
		server_window_changed(c);
 | 
			
		||||
	else
 | 
			
		||||
		server_write_message(c, "No last window"); 
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
cmd_fn_meta(struct client *c, unused int arg)
 | 
			
		||||
{
 | 
			
		||||
	window_key(c->session->window, cmd_prefix);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
cmd_fn_next(struct client *c, unused int arg)
 | 
			
		||||
{
 | 
			
		||||
	if (session_next(c->session) == 0)
 | 
			
		||||
		server_window_changed(c);
 | 
			
		||||
	else
 | 
			
		||||
		server_write_message(c, "No next window"); 
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
cmd_fn_previous(struct client *c, unused int arg)
 | 
			
		||||
{
 | 
			
		||||
	if (session_previous(c->session) == 0)
 | 
			
		||||
		server_window_changed(c);
 | 
			
		||||
	else
 | 
			
		||||
		server_write_message(c, "No previous window"); 
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
cmd_fn_refresh(struct client *c, unused int arg)
 | 
			
		||||
{
 | 
			
		||||
	server_draw_client(c, 0, c->sy - 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
cmd_fn_select(struct client *c, int arg)
 | 
			
		||||
{
 | 
			
		||||
	if (session_select(c->session, arg) == 0)
 | 
			
		||||
		server_window_changed(c);
 | 
			
		||||
	else
 | 
			
		||||
		server_write_message(c, "Window %u not present", arg); 
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
cmd_fn_windowinfo(struct client *c, unused int arg)
 | 
			
		||||
{
 | 
			
		||||
	struct window	*w;
 | 
			
		||||
	char 		*buf;
 | 
			
		||||
	size_t		 len;
 | 
			
		||||
	u_int		 i;
 | 
			
		||||
 | 
			
		||||
	len = c->sx + 1;
 | 
			
		||||
	buf = xmalloc(len);
 | 
			
		||||
 | 
			
		||||
	w = c->session->window;
 | 
			
		||||
	window_index(&c->session->windows, w, &i);
 | 
			
		||||
	xsnprintf(buf, len, "%u:%s \"%s\" (size %u,%u) (cursor %u,%u) "
 | 
			
		||||
	    "(region %u,%u)", i, w->name, w->screen.title, w->screen.sx,
 | 
			
		||||
	    w->screen.sy, w->screen.cx, w->screen.cy, w->screen.ry_upper,
 | 
			
		||||
	    w->screen.ry_lower);
 | 
			
		||||
 | 
			
		||||
	server_write_message(c, "%s", buf);
 | 
			
		||||
	xfree(buf);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										12
									
								
								input.c
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								input.c
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: input.c,v 1.18 2007-10-03 09:16:59 nicm Exp $ */
 | 
			
		||||
/* $Id: input.c,v 1.19 2007-10-03 10:18:32 nicm Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -171,16 +171,6 @@ input_free(struct input_ctx *ictx)
 | 
			
		||||
	ARRAY_FREE(&ictx->args);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
input_parse1(struct screen *s, u_char *buf, size_t len, struct buffer *b)
 | 
			
		||||
{
 | 
			
		||||
	struct input_ctx	ictx;
 | 
			
		||||
 | 
			
		||||
	input_init(&ictx, s);
 | 
			
		||||
	input_parse(&ictx, buf, len, b);
 | 
			
		||||
	input_free(&ictx);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
input_parse(struct input_ctx *ictx, u_char *buf, size_t len, struct buffer *b)
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										8
									
								
								local.c
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								local.c
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: local.c,v 1.13 2007-10-02 15:13:59 nicm Exp $ */
 | 
			
		||||
/* $Id: local.c,v 1.14 2007-10-03 10:18:32 nicm Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -349,7 +349,7 @@ local_putp(const char *s)
 | 
			
		||||
 | 
			
		||||
/* Return waiting keys if any. */
 | 
			
		||||
int
 | 
			
		||||
local_key(size_t *used)
 | 
			
		||||
local_key(void)
 | 
			
		||||
{
 | 
			
		||||
	struct local_key	*lk;
 | 
			
		||||
	u_int			 i;
 | 
			
		||||
@@ -368,8 +368,6 @@ local_key(size_t *used)
 | 
			
		||||
			log_debug("got key: "
 | 
			
		||||
			    "%s %d \"%s\"", lk->name, lk->code, lk->string);
 | 
			
		||||
			buffer_remove(local_in, lk->size);
 | 
			
		||||
			if (used != NULL)
 | 
			
		||||
				*used = lk->size;
 | 
			
		||||
			return (lk->code);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@@ -377,8 +375,6 @@ local_key(size_t *used)
 | 
			
		||||
		lk = local_keys + i;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (used != NULL)
 | 
			
		||||
		*used = 1;
 | 
			
		||||
	return (input_extract8(local_in));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										13
									
								
								server-fn.c
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								server-fn.c
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: server-fn.c,v 1.11 2007-10-02 17:45:05 nicm Exp $ */
 | 
			
		||||
/* $Id: server-fn.c,v 1.12 2007-10-03 10:18:32 nicm Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -164,10 +164,9 @@ server_draw_client(struct client *c, u_int py_upper, u_int py_lower)
 | 
			
		||||
	size = BUFFER_USED(c->out) - size;
 | 
			
		||||
	log_debug("redrawing screen, %zu bytes", size);
 | 
			
		||||
	if (size != 0) {
 | 
			
		||||
		hdr.type = MSG_OUTPUT;
 | 
			
		||||
		hdr.type = MSG_DATA;
 | 
			
		||||
		hdr.size = size;
 | 
			
		||||
		memcpy(
 | 
			
		||||
		    BUFFER_IN(c->out) - size - sizeof hdr, &hdr, sizeof hdr);
 | 
			
		||||
		memcpy(BUFFER_IN(c->out) - size - sizeof hdr, &hdr, sizeof hdr);
 | 
			
		||||
	} else
 | 
			
		||||
		buffer_reverse_add(c->out, sizeof hdr);
 | 
			
		||||
 | 
			
		||||
@@ -191,7 +190,7 @@ server_draw_status(struct client *c)
 | 
			
		||||
	status_write(c);
 | 
			
		||||
 | 
			
		||||
	size = BUFFER_USED(c->out) - size;
 | 
			
		||||
	hdr.type = MSG_OUTPUT;
 | 
			
		||||
	hdr.type = MSG_DATA;
 | 
			
		||||
	hdr.size = size;
 | 
			
		||||
	memcpy(BUFFER_IN(c->out) - size - sizeof hdr, &hdr, sizeof hdr);
 | 
			
		||||
}
 | 
			
		||||
@@ -237,7 +236,7 @@ server_write_message(struct client *c, const char *fmt, ...)
 | 
			
		||||
	xfree(msg);
 | 
			
		||||
 | 
			
		||||
	size = BUFFER_USED(c->out) - size;
 | 
			
		||||
	hdr.type = MSG_OUTPUT;
 | 
			
		||||
	hdr.type = MSG_DATA;
 | 
			
		||||
	hdr.size = size;
 | 
			
		||||
	memcpy(BUFFER_IN(c->out) - size - sizeof hdr, &hdr, sizeof hdr);
 | 
			
		||||
 | 
			
		||||
@@ -256,7 +255,7 @@ server_write_message(struct client *c, const char *fmt, ...)
 | 
			
		||||
		status_write(c);
 | 
			
		||||
 | 
			
		||||
	size = BUFFER_USED(c->out) - size;
 | 
			
		||||
	hdr.type = MSG_OUTPUT;
 | 
			
		||||
	hdr.type = MSG_DATA;
 | 
			
		||||
	hdr.size = size;
 | 
			
		||||
	memcpy(BUFFER_IN(c->out) - size - sizeof hdr, &hdr, sizeof hdr);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										186
									
								
								server-msg.c
									
									
									
									
									
								
							
							
						
						
									
										186
									
								
								server-msg.c
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: server-msg.c,v 1.15 2007-10-03 09:17:00 nicm Exp $ */
 | 
			
		||||
/* $Id: server-msg.c,v 1.16 2007-10-03 10:18:32 nicm Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -25,19 +25,12 @@
 | 
			
		||||
#include "tmux.h"
 | 
			
		||||
 | 
			
		||||
int	server_msg_fn_attach(struct hdr *, struct client *);
 | 
			
		||||
int	server_msg_fn_create(struct hdr *, struct client *);
 | 
			
		||||
int	server_msg_fn_input(struct hdr *, struct client *);
 | 
			
		||||
int	server_msg_fn_last(struct hdr *, struct client *);
 | 
			
		||||
int	server_msg_fn_keys(struct hdr *, struct client *);
 | 
			
		||||
int	server_msg_fn_new(struct hdr *, struct client *);
 | 
			
		||||
int	server_msg_fn_next(struct hdr *, struct client *);
 | 
			
		||||
int	server_msg_fn_previous(struct hdr *, struct client *);
 | 
			
		||||
int	server_msg_fn_refresh(struct hdr *, struct client *);
 | 
			
		||||
int	server_msg_fn_rename(struct hdr *, struct client *);
 | 
			
		||||
int	server_msg_fn_select(struct hdr *, struct client *);
 | 
			
		||||
int	server_msg_fn_sessions(struct hdr *, struct client *);
 | 
			
		||||
int	server_msg_fn_size(struct hdr *, struct client *);
 | 
			
		||||
int	server_msg_fn_windowlist(struct hdr *, struct client *);
 | 
			
		||||
int	server_msg_fn_windowinfo(struct hdr *, struct client *);
 | 
			
		||||
int	server_msg_fn_windows(struct hdr *, struct client *);
 | 
			
		||||
 | 
			
		||||
struct server_msg {
 | 
			
		||||
@@ -47,19 +40,12 @@ struct server_msg {
 | 
			
		||||
};
 | 
			
		||||
const struct server_msg server_msg_table[] = {
 | 
			
		||||
	{ MSG_ATTACH, server_msg_fn_attach },
 | 
			
		||||
	{ MSG_CREATE, server_msg_fn_create },
 | 
			
		||||
	{ MSG_INPUT, server_msg_fn_input },
 | 
			
		||||
	{ MSG_LAST, server_msg_fn_last },
 | 
			
		||||
	{ MSG_KEYS, server_msg_fn_keys },
 | 
			
		||||
	{ MSG_NEW, server_msg_fn_new },
 | 
			
		||||
	{ MSG_NEXT, server_msg_fn_next },
 | 
			
		||||
	{ MSG_PREVIOUS, server_msg_fn_previous },
 | 
			
		||||
	{ MSG_REFRESH, server_msg_fn_refresh },
 | 
			
		||||
	{ MSG_RENAME, server_msg_fn_rename },
 | 
			
		||||
	{ MSG_SELECT, server_msg_fn_select },
 | 
			
		||||
	{ MSG_SESSIONS, server_msg_fn_sessions },
 | 
			
		||||
	{ MSG_SIZE, server_msg_fn_size },
 | 
			
		||||
	{ MSG_WINDOWLIST, server_msg_fn_windowlist },
 | 
			
		||||
	{ MSG_WINDOWINFO, server_msg_fn_windowinfo },
 | 
			
		||||
	{ MSG_WINDOWS, server_msg_fn_windows },
 | 
			
		||||
};
 | 
			
		||||
#define NSERVERMSG (sizeof server_msg_table / sizeof server_msg_table[0])
 | 
			
		||||
@@ -134,7 +120,7 @@ server_msg_fn_new(struct hdr *hdr, struct client *c)
 | 
			
		||||
		fatalx("session_create failed");
 | 
			
		||||
	xfree(cmd);
 | 
			
		||||
 | 
			
		||||
	server_write_client(c, MSG_DONE, NULL, 0);
 | 
			
		||||
	server_write_client(c, MSG_OKAY, NULL, 0);
 | 
			
		||||
	server_draw_client(c, 0, c->sy - 1);
 | 
			
		||||
 | 
			
		||||
	return (0);
 | 
			
		||||
@@ -174,65 +160,6 @@ server_msg_fn_attach(struct hdr *hdr, struct client *c)
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Create message from client. */
 | 
			
		||||
int
 | 
			
		||||
server_msg_fn_create(struct hdr *hdr, struct client *c)
 | 
			
		||||
{
 | 
			
		||||
	const char	*shell;
 | 
			
		||||
	char		*cmd;
 | 
			
		||||
 | 
			
		||||
	if (c->session == NULL)
 | 
			
		||||
		return (0);
 | 
			
		||||
	if (hdr->size != 0)
 | 
			
		||||
		fatalx("bad MSG_CREATE size");
 | 
			
		||||
 | 
			
		||||
	shell = getenv("SHELL");
 | 
			
		||||
	if (shell == NULL)
 | 
			
		||||
		shell = "/bin/ksh";
 | 
			
		||||
	xasprintf(&cmd, "%s -l", shell);
 | 
			
		||||
	if (session_new(c->session, cmd, c->sx, c->sy) != 0)
 | 
			
		||||
		fatalx("session_new failed");
 | 
			
		||||
	xfree(cmd);
 | 
			
		||||
 | 
			
		||||
	server_draw_client(c, 0, c->sy - 1);
 | 
			
		||||
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Next message from client. */
 | 
			
		||||
int
 | 
			
		||||
server_msg_fn_next(struct hdr *hdr, struct client *c)
 | 
			
		||||
{
 | 
			
		||||
	if (c->session == NULL)
 | 
			
		||||
		return (0);
 | 
			
		||||
	if (hdr->size != 0)
 | 
			
		||||
		fatalx("bad MSG_NEXT size");
 | 
			
		||||
 | 
			
		||||
	if (session_next(c->session) == 0)
 | 
			
		||||
		server_window_changed(c);
 | 
			
		||||
	else
 | 
			
		||||
		server_write_message(c, "No next window"); 
 | 
			
		||||
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Previous message from client. */
 | 
			
		||||
int
 | 
			
		||||
server_msg_fn_previous(struct hdr *hdr, struct client *c)
 | 
			
		||||
{
 | 
			
		||||
	if (c->session == NULL)
 | 
			
		||||
		return (0);
 | 
			
		||||
	if (hdr->size != 0)
 | 
			
		||||
		fatalx("bad MSG_PREVIOUS size");
 | 
			
		||||
 | 
			
		||||
	if (session_previous(c->session) == 0)
 | 
			
		||||
		server_window_changed(c);
 | 
			
		||||
	else
 | 
			
		||||
		server_write_message(c, "No previous window"); 
 | 
			
		||||
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Size message from client. */
 | 
			
		||||
int
 | 
			
		||||
server_msg_fn_size(struct hdr *hdr, struct client *c)
 | 
			
		||||
@@ -261,52 +188,34 @@ server_msg_fn_size(struct hdr *hdr, struct client *c)
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Input message from client. */
 | 
			
		||||
/* Keys message from client. */
 | 
			
		||||
int
 | 
			
		||||
server_msg_fn_input(struct hdr *hdr, struct client *c)
 | 
			
		||||
server_msg_fn_keys(struct hdr *hdr, struct client *c)
 | 
			
		||||
{
 | 
			
		||||
	int	key;
 | 
			
		||||
	size_t	size;
 | 
			
		||||
 | 
			
		||||
	if (c->session == NULL)
 | 
			
		||||
		return (0);
 | 
			
		||||
	if (hdr->size & 0x1)
 | 
			
		||||
		fatalx("bad MSG_KEYS size");
 | 
			
		||||
 | 
			
		||||
	window_input(c->session->window, c->in, hdr->size);
 | 
			
		||||
	size = hdr->size;
 | 
			
		||||
	while (size != 0) {
 | 
			
		||||
		key = input_extract16(c->in);
 | 
			
		||||
		size -= 2;
 | 
			
		||||
 | 
			
		||||
	return (0);
 | 
			
		||||
		if (c->prefix) {
 | 
			
		||||
			cmd_dispatch(c, key);
 | 
			
		||||
			c->prefix = 0;
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
/* Refresh message from client. */
 | 
			
		||||
int
 | 
			
		||||
server_msg_fn_refresh(struct hdr *hdr, struct client *c)
 | 
			
		||||
{
 | 
			
		||||
	struct refresh_data	data;
 | 
			
		||||
 | 
			
		||||
	if (c->session == NULL)
 | 
			
		||||
		return (0);
 | 
			
		||||
	if (hdr->size != 0 && hdr->size != sizeof data)
 | 
			
		||||
		fatalx("bad MSG_REFRESH size");
 | 
			
		||||
 | 
			
		||||
	server_draw_client(c, 0, c->sy - 1);
 | 
			
		||||
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Select message from client. */
 | 
			
		||||
int
 | 
			
		||||
server_msg_fn_select(struct hdr *hdr, struct client *c)
 | 
			
		||||
{
 | 
			
		||||
	struct select_data	data;
 | 
			
		||||
 | 
			
		||||
	if (c->session == NULL)
 | 
			
		||||
		return (0);
 | 
			
		||||
	if (hdr->size != sizeof data)
 | 
			
		||||
		fatalx("bad MSG_SELECT size");
 | 
			
		||||
	buffer_read(c->in, &data, hdr->size);
 | 
			
		||||
 | 
			
		||||
	if (c->session == NULL)
 | 
			
		||||
		return (0);
 | 
			
		||||
	if (session_select(c->session, data.idx) == 0)
 | 
			
		||||
		server_window_changed(c);
 | 
			
		||||
		if (key == cmd_prefix)
 | 
			
		||||
			c->prefix = 1;
 | 
			
		||||
		else
 | 
			
		||||
		server_write_message(c, "Window %u not present", data.idx); 
 | 
			
		||||
			window_key(c->session->window, key);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
@@ -429,7 +338,7 @@ server_msg_fn_rename(struct hdr *hdr, struct client *c)
 | 
			
		||||
 | 
			
		||||
	strlcpy(w->name, data.newname, sizeof w->name);
 | 
			
		||||
 | 
			
		||||
	server_write_client(c, MSG_DONE, NULL, 0);
 | 
			
		||||
	server_write_client(c, MSG_OKAY, NULL, 0);
 | 
			
		||||
	for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
 | 
			
		||||
		c = ARRAY_ITEM(&clients, i);
 | 
			
		||||
		if (c != NULL && c->session != NULL) {
 | 
			
		||||
@@ -441,23 +350,6 @@ server_msg_fn_rename(struct hdr *hdr, struct client *c)
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Last window message from client */
 | 
			
		||||
int
 | 
			
		||||
server_msg_fn_last(struct hdr *hdr, struct client *c)
 | 
			
		||||
{
 | 
			
		||||
	if (c->session == NULL)
 | 
			
		||||
		return (0);
 | 
			
		||||
	if (hdr->size != 0)
 | 
			
		||||
		fatalx("bad MSG_LAST size");
 | 
			
		||||
 | 
			
		||||
	if (session_last(c->session) == 0)
 | 
			
		||||
		server_window_changed(c);
 | 
			
		||||
	else
 | 
			
		||||
		server_write_message(c, "No last window"); 
 | 
			
		||||
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Window list message from client */
 | 
			
		||||
int
 | 
			
		||||
server_msg_fn_windowlist(struct hdr *hdr, struct client *c)
 | 
			
		||||
@@ -492,33 +384,3 @@ server_msg_fn_windowlist(struct hdr *hdr, struct client *c)
 | 
			
		||||
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Window info message from client */
 | 
			
		||||
int
 | 
			
		||||
server_msg_fn_windowinfo(struct hdr *hdr, struct client *c)
 | 
			
		||||
{
 | 
			
		||||
	struct window	*w;
 | 
			
		||||
	char 		*buf;
 | 
			
		||||
	size_t		 len;
 | 
			
		||||
	u_int		 i;
 | 
			
		||||
 | 
			
		||||
	if (c->session == NULL)
 | 
			
		||||
		return (0);
 | 
			
		||||
	if (hdr->size != 0)
 | 
			
		||||
		fatalx("bad MSG_WINDOWINFO size");
 | 
			
		||||
 | 
			
		||||
	len = c->sx + 1;
 | 
			
		||||
	buf = xmalloc(len);
 | 
			
		||||
 | 
			
		||||
	w = c->session->window;
 | 
			
		||||
	window_index(&c->session->windows, w, &i);
 | 
			
		||||
	xsnprintf(buf, len, "%u:%s \"%s\" (size %u,%u) (cursor %u,%u) "
 | 
			
		||||
	    "(region %u,%u)", i, w->name, w->screen.title, w->screen.sx,
 | 
			
		||||
	    w->screen.sy, w->screen.cx, w->screen.cy, w->screen.ry_upper,
 | 
			
		||||
	    w->screen.ry_lower);
 | 
			
		||||
 | 
			
		||||
	server_write_message(c, "%s", buf);
 | 
			
		||||
	xfree(buf);
 | 
			
		||||
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										9
									
								
								server.c
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								server.c
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: server.c,v 1.16 2007-09-29 09:53:25 nicm Exp $ */
 | 
			
		||||
/* $Id: server.c,v 1.17 2007-10-03 10:18:32 nicm Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -315,11 +315,10 @@ server_handle_window(struct window *w)
 | 
			
		||||
	u_int		 i, j, p;
 | 
			
		||||
 | 
			
		||||
	b = buffer_create(BUFSIZ);
 | 
			
		||||
	window_output(w, b);
 | 
			
		||||
 | 
			
		||||
	window_data(w, b);
 | 
			
		||||
	if (BUFFER_USED(b) != 0) {
 | 
			
		||||
		server_write_clients(
 | 
			
		||||
		    w, MSG_OUTPUT, BUFFER_OUT(b), BUFFER_USED(b));
 | 
			
		||||
		    w, MSG_DATA, BUFFER_OUT(b), BUFFER_USED(b));
 | 
			
		||||
	}
 | 
			
		||||
	buffer_destroy(b);
 | 
			
		||||
 | 
			
		||||
@@ -341,7 +340,7 @@ server_handle_window(struct window *w)
 | 
			
		||||
			  if (s->window != w)
 | 
			
		||||
			  	server_write_message(c, "Bell in window %u", p);
 | 
			
		||||
			*/
 | 
			
		||||
			server_write_client(c, MSG_OUTPUT, "\007", 1);
 | 
			
		||||
			server_write_client(c, MSG_DATA, "\007", 1);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										37
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										37
									
								
								tmux.h
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: tmux.h,v 1.33 2007-10-02 17:45:05 nicm Exp $ */
 | 
			
		||||
/* $Id: tmux.h,v 1.34 2007-10-03 10:18:32 nicm Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -260,23 +260,17 @@ struct buffer {
 | 
			
		||||
/* Message codes. */
 | 
			
		||||
enum hdrtype {
 | 
			
		||||
	MSG_ATTACH,
 | 
			
		||||
	MSG_CREATE,
 | 
			
		||||
	MSG_DONE,
 | 
			
		||||
	MSG_DATA,
 | 
			
		||||
	MSG_DETACH,
 | 
			
		||||
	MSG_ERROR,
 | 
			
		||||
	MSG_EXIT,
 | 
			
		||||
	MSG_INPUT,
 | 
			
		||||
	MSG_LAST,
 | 
			
		||||
	MSG_KEYS,
 | 
			
		||||
	MSG_NEW,
 | 
			
		||||
	MSG_NEXT,
 | 
			
		||||
	MSG_OUTPUT,
 | 
			
		||||
	MSG_OKAY,
 | 
			
		||||
	MSG_PAUSE,
 | 
			
		||||
	MSG_PREVIOUS,
 | 
			
		||||
	MSG_REFRESH,
 | 
			
		||||
	MSG_RENAME,
 | 
			
		||||
	MSG_SELECT,
 | 
			
		||||
	MSG_SESSIONS,
 | 
			
		||||
	MSG_SIZE,
 | 
			
		||||
	MSG_WINDOWINFO,
 | 
			
		||||
	MSG_WINDOWLIST,
 | 
			
		||||
	MSG_WINDOWS,
 | 
			
		||||
};
 | 
			
		||||
@@ -482,6 +476,8 @@ struct client {
 | 
			
		||||
	u_int		 sx;
 | 
			
		||||
	u_int		 sy;
 | 
			
		||||
 | 
			
		||||
	int		 prefix;	/* waiting for command */
 | 
			
		||||
 | 
			
		||||
	struct session	*session;
 | 
			
		||||
};
 | 
			
		||||
ARRAY_DECL(clients, struct client *);
 | 
			
		||||
@@ -522,15 +518,17 @@ int	 op_list_windows(char *, int, char **);
 | 
			
		||||
int	 client_init(char *, struct client_ctx *, int);
 | 
			
		||||
int	 client_flush(struct client_ctx *);
 | 
			
		||||
int	 client_main(struct client_ctx *);
 | 
			
		||||
void	 client_write_server(struct client_ctx *, enum hdrtype, void *, size_t);
 | 
			
		||||
void	 client_fill_sessid(struct sessid *, char [MAXNAMELEN]);
 | 
			
		||||
 | 
			
		||||
/* client-msg.c */
 | 
			
		||||
int	 client_msg_dispatch(struct client_ctx *, char **);
 | 
			
		||||
 | 
			
		||||
/* command.c */
 | 
			
		||||
extern int client_cmd_prefix;
 | 
			
		||||
int	 client_cmd_dispatch(int, struct client_ctx *, char **);
 | 
			
		||||
/* client-fn.c */
 | 
			
		||||
void	 client_write_server(struct client_ctx *, enum hdrtype, void *, size_t);
 | 
			
		||||
void	 client_fill_sessid(struct sessid *, char [MAXNAMELEN]);
 | 
			
		||||
 | 
			
		||||
/* cmd.c */
 | 
			
		||||
extern int cmd_prefix;
 | 
			
		||||
void	 cmd_dispatch(struct client *, int);
 | 
			
		||||
 | 
			
		||||
/* server.c */
 | 
			
		||||
extern struct clients clients;
 | 
			
		||||
@@ -559,7 +557,6 @@ void	 status_write(struct client *c);
 | 
			
		||||
/* input.c */
 | 
			
		||||
void	 input_init(struct input_ctx *, struct screen *);
 | 
			
		||||
void	 input_free(struct input_ctx *);
 | 
			
		||||
void	 input_parse1(struct screen *, u_char *, size_t, struct buffer *);
 | 
			
		||||
void	 input_parse(struct input_ctx *, u_char *, size_t, struct buffer *);
 | 
			
		||||
uint8_t  input_extract8(struct buffer *);
 | 
			
		||||
uint16_t input_extract16(struct buffer *);
 | 
			
		||||
@@ -602,7 +599,7 @@ void	 screen_fill_start_of_line(
 | 
			
		||||
/* local.c */
 | 
			
		||||
int	 local_init(struct buffer **, struct buffer **);
 | 
			
		||||
void	 local_done(void);
 | 
			
		||||
int	 local_key(size_t *);
 | 
			
		||||
int	 local_key(void);
 | 
			
		||||
void	 local_output(struct buffer *, size_t);
 | 
			
		||||
 | 
			
		||||
/* window.c */
 | 
			
		||||
@@ -617,8 +614,8 @@ struct window	*window_previous(struct windows *, struct window *);
 | 
			
		||||
struct window	*window_at(struct windows *, u_int); 
 | 
			
		||||
int		 window_resize(struct window *, u_int, u_int);
 | 
			
		||||
int		 window_poll(struct window *, struct pollfd *);
 | 
			
		||||
void		 window_input(struct window *, struct buffer *, size_t);
 | 
			
		||||
void		 window_output(struct window *, struct buffer *);
 | 
			
		||||
void		 window_key(struct window *, int);
 | 
			
		||||
void		 window_data(struct window *, struct buffer *);
 | 
			
		||||
 | 
			
		||||
/* session.c */
 | 
			
		||||
extern struct sessions sessions;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										22
									
								
								window.c
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								window.c
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: window.c,v 1.15 2007-10-01 14:15:48 nicm Exp $ */
 | 
			
		||||
/* $Id: window.c,v 1.16 2007-10-03 10:18:32 nicm Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -288,33 +288,19 @@ window_poll(struct window *w, struct pollfd *pfd)
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Process window input. */
 | 
			
		||||
/* Process window key. */
 | 
			
		||||
void
 | 
			
		||||
window_input(struct window *w, struct buffer *b, size_t size)
 | 
			
		||||
window_key(struct window *w, int key)
 | 
			
		||||
{
 | 
			
		||||
	int	key;
 | 
			
		||||
 | 
			
		||||
	while (size != 0) {
 | 
			
		||||
		if (size < 1)
 | 
			
		||||
			break;
 | 
			
		||||
		size--;
 | 
			
		||||
		key = input_extract8(b);
 | 
			
		||||
		if (key == '\e') {
 | 
			
		||||
			if (size < 2)
 | 
			
		||||
				fatalx("underflow");
 | 
			
		||||
			size -= 2;
 | 
			
		||||
			key = (int16_t) input_extract16(b);
 | 
			
		||||
		}
 | 
			
		||||
	input_translate_key(w->out, key);
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Process window output. Output is translated into a series of escape
 | 
			
		||||
 * sequences and strings and returned.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
window_output(struct window *w, struct buffer *b)
 | 
			
		||||
window_data(struct window *w, struct buffer *b)
 | 
			
		||||
{
 | 
			
		||||
	FILE	*f;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user