mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-03 16:46:18 +00:00 
			
		
		
		
	Big internal reorganisation to move tty control into parent.
This commit is contained in:
		
							
								
								
									
										12
									
								
								CHANGES
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								CHANGES
									
									
									
									
									
								
							@@ -1,3 +1,13 @@
 | 
			
		||||
27 November 2007
 | 
			
		||||
 | 
			
		||||
* Big internal reorganisation. Rather than leaving control of the tty solely in
 | 
			
		||||
  the client and piping all data through a socket to it, change so that the
 | 
			
		||||
  server opens the tty again and reads and writes to it directly. This avoids
 | 
			
		||||
  a lot of buffering and copying.Also reorganise the redrawing stuff so that
 | 
			
		||||
  everything goes through screen_draw_* - this makes the code simpler, but
 | 
			
		||||
  still needs broken up more, and all the ways of writing to screens should be
 | 
			
		||||
  more consistent.
 | 
			
		||||
 | 
			
		||||
26 November 2007
 | 
			
		||||
 | 
			
		||||
* Rather than shifting up one line at a time once the history is full,
 | 
			
		||||
@@ -273,4 +283,4 @@
 | 
			
		||||
  (including mutt, emacs). No status bar yet and no key remapping or other
 | 
			
		||||
  customisation.
 | 
			
		||||
 | 
			
		||||
$Id: CHANGES,v 1.86 2007-11-26 22:18:57 nicm Exp $
 | 
			
		||||
$Id: CHANGES,v 1.87 2007-11-27 19:23:32 nicm Exp $
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										7
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								Makefile
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
# $Id: Makefile,v 1.48 2007-11-23 17:52:54 nicm Exp $
 | 
			
		||||
# $Id: Makefile,v 1.49 2007-11-27 19:23:33 nicm Exp $
 | 
			
		||||
 | 
			
		||||
.SUFFIXES: .c .o .y .h
 | 
			
		||||
.PHONY: clean update-index.html upload-index.html
 | 
			
		||||
@@ -17,7 +17,7 @@ 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 screen-display.c \
 | 
			
		||||
      window.c session.c local.c log.c client.c client-msg.c client-fn.c \
 | 
			
		||||
      window.c session.c log.c client.c client-msg.c client-fn.c \
 | 
			
		||||
      key-string.c key-bindings.c resize.c cmd.c cmd-new-session.c \
 | 
			
		||||
      cmd-detach-client.c cmd-list-sessions.c cmd-new-window.c cmd-bind-key.c \
 | 
			
		||||
      cmd-unbind-key.c cmd-previous-window.c cmd-last-window.c cmd-list-keys.c \
 | 
			
		||||
@@ -27,7 +27,8 @@ SRCS= tmux.c server.c server-msg.c server-fn.c buffer.c buffer-poll.c status.c \
 | 
			
		||||
      cmd-link-window.c cmd-unlink-window.c cmd-next-window.c \
 | 
			
		||||
      cmd-swap-window.c cmd-rename-session.c cmd-kill-session.c \
 | 
			
		||||
      cmd-switch-client.c cmd-has-session.c cmd-scroll-mode.c cmd-copy-mode.c \
 | 
			
		||||
      cmd-paste-buffer.c window-scroll.c window-more.c window-copy.c
 | 
			
		||||
      cmd-paste-buffer.c window-scroll.c window-more.c window-copy.c \
 | 
			
		||||
      tty.c tty-keys.c tty-write.c
 | 
			
		||||
 | 
			
		||||
CC?= cc
 | 
			
		||||
INCDIRS+= -I. -I- -I/usr/local/include
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										17
									
								
								TODO
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								TODO
									
									
									
									
									
								
							@@ -1,31 +1,16 @@
 | 
			
		||||
- it would be nice if there wasn't so much copying buffers about, audit uses
 | 
			
		||||
- useful env vars like WINDOW?
 | 
			
		||||
- sort out who controls the buffers in local.c a bit
 | 
			
		||||
- better checking/emulation for missing term requirements
 | 
			
		||||
- alt charset, borders etc (terminfo(5)/Line Graphics)
 | 
			
		||||
- new window command prompt
 | 
			
		||||
- mouse handling and some other bits elinks needs
 | 
			
		||||
- server doesn't handle SIGTERM anymore...
 | 
			
		||||
- the whole input/screen/local thing sucks a bit, reorganise/redesign it
 | 
			
		||||
- line mode/char-at-a-time mode a la telnet?
 | 
			
		||||
- some of the uses of buffers really sucks. buffer_reverse_add/remove,
 | 
			
		||||
  and buffer_insert_range/delete_range are abominations. this should be
 | 
			
		||||
  rethought
 | 
			
		||||
- handle ioctl/termios stuff on window sockets
 | 
			
		||||
- figure out once and for all what is going on with backspace and del
 | 
			
		||||
      backspace should be translated per the termios setting.
 | 
			
		||||
      del passed through?
 | 
			
		||||
- window creation/idle time
 | 
			
		||||
- attributes could be 8 not 16 bits
 | 
			
		||||
- profile/optimise, particularly (i suspect) input.c
 | 
			
		||||
- tidy up input.c a bit
 | 
			
		||||
- decide about customised status line
 | 
			
		||||
- 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 slightly arse-about-face: overhead? 8-byte header for
 | 
			
		||||
	each packet... hrm. already scanning output for \e, could add an extra
 | 
			
		||||
	byte to it for message
 | 
			
		||||
- could use bsearch all over the place or get rid of smaller tables (clientmsg)
 | 
			
		||||
- better errors when creating new windows/sessions (how?)
 | 
			
		||||
- commands should have to care less about CMD_KEY
 | 
			
		||||
@@ -71,6 +56,8 @@
 | 
			
		||||
  in $x time (need window creation/use times)
 | 
			
		||||
- lift SHRT_MAX limits for history
 | 
			
		||||
- audit copy/scroll and other modes for problems with very small windows
 | 
			
		||||
- screen_draw_* moved out/renamed (accept TTY_*?)
 | 
			
		||||
- SIGWINCH can probably be handled in server
 | 
			
		||||
 | 
			
		||||
-- For 0.2 --------------------------------------------------------------------
 | 
			
		||||
- window splitting?
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: buffer-poll.c,v 1.2 2007-11-07 19:41:17 nicm Exp $ */
 | 
			
		||||
/* $Id: buffer-poll.c,v 1.3 2007-11-27 19:23:33 nicm Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -53,3 +53,24 @@ buffer_poll(struct pollfd *pfd, struct buffer *in, struct buffer *out)
 | 
			
		||||
	}
 | 
			
		||||
	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) {
 | 
			
		||||
		pfd.fd = fd;
 | 
			
		||||
		pfd.events = POLLIN|POLLOUT;
 | 
			
		||||
 | 
			
		||||
		if (poll(&pfd, 1, INFTIM) == -1) {
 | 
			
		||||
			if (errno == EAGAIN || errno == EINTR)
 | 
			
		||||
				continue;
 | 
			
		||||
			fatal("poll failed");
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (buffer_poll(&pfd, in, out) != 0)
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										43
									
								
								buffer.c
									
									
									
									
									
								
							
							
						
						
									
										43
									
								
								buffer.c
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: buffer.c,v 1.2 2007-07-25 23:13:18 nicm Exp $ */
 | 
			
		||||
/* $Id: buffer.c,v 1.3 2007-11-27 19:23:33 nicm Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -179,3 +179,44 @@ buffer_read(struct buffer *b, void *data, size_t size)
 | 
			
		||||
	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);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										25
									
								
								client-msg.c
									
									
									
									
									
								
							
							
						
						
									
										25
									
								
								client-msg.c
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: client-msg.c,v 1.10 2007-10-19 20:50:01 nicm Exp $ */
 | 
			
		||||
/* $Id: client-msg.c,v 1.11 2007-11-27 19:23:33 nicm Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -25,7 +25,6 @@
 | 
			
		||||
 | 
			
		||||
#include "tmux.h"
 | 
			
		||||
 | 
			
		||||
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_exit(struct hdr *, struct client_ctx *, char **);
 | 
			
		||||
@@ -38,11 +37,9 @@ struct client_msg {
 | 
			
		||||
	int	       (*fn)(struct hdr *, struct client_ctx *, char **);
 | 
			
		||||
};
 | 
			
		||||
struct client_msg client_msg_table[] = {
 | 
			
		||||
	{ MSG_DATA, client_msg_fn_data },
 | 
			
		||||
	{ MSG_DETACH, client_msg_fn_detach },
 | 
			
		||||
	{ MSG_ERROR, client_msg_fn_error },
 | 
			
		||||
	{ MSG_EXIT, client_msg_fn_exit },
 | 
			
		||||
	{ MSG_PAUSE, client_msg_fn_pause },
 | 
			
		||||
};
 | 
			
		||||
#define NCLIENTMSG (sizeof client_msg_table / sizeof client_msg_table[0])
 | 
			
		||||
 | 
			
		||||
@@ -71,26 +68,6 @@ client_msg_dispatch(struct client_ctx *cctx, char **error)
 | 
			
		||||
	fatalx("unexpected message");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
client_msg_fn_data(
 | 
			
		||||
    struct hdr *hdr, struct client_ctx *cctx, unused char **error)
 | 
			
		||||
{
 | 
			
		||||
	local_output(cctx->srv_in, hdr->size);
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
client_msg_fn_pause(
 | 
			
		||||
    struct hdr *hdr, unused struct client_ctx *cctx, unused char **error)
 | 
			
		||||
{
 | 
			
		||||
	if (hdr->size != 0)
 | 
			
		||||
		fatalx("bad MSG_PAUSE size");
 | 
			
		||||
 | 
			
		||||
	cctx->flags |= CCTX_PAUSE;
 | 
			
		||||
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
client_msg_fn_error(struct hdr *hdr, struct client_ctx *cctx, char **error)
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										61
									
								
								client.c
									
									
									
									
									
								
							
							
						
						
									
										61
									
								
								client.c
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: client.c,v 1.22 2007-11-26 20:36:30 nicm Exp $ */
 | 
			
		||||
/* $Id: client.c,v 1.23 2007-11-27 19:23:33 nicm Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -33,7 +33,6 @@
 | 
			
		||||
#include "tmux.h"
 | 
			
		||||
 | 
			
		||||
void	client_handle_winch(struct client_ctx *);
 | 
			
		||||
int	client_process_local(struct client_ctx *, char **);
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
client_init(const char *path, struct client_ctx *cctx, int start_server)
 | 
			
		||||
@@ -113,6 +112,7 @@ retry:
 | 
			
		||||
		if (ttyname_r(STDIN_FILENO, data.tty, sizeof data.tty) != 0)
 | 
			
		||||
			fatal("ttyname_r failed");
 | 
			
		||||
		client_write_server(cctx, MSG_IDENTIFY, &data, sizeof data);
 | 
			
		||||
		cmd_send_string(cctx->srv_out, getenv("TERM"));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return (0);
 | 
			
		||||
@@ -121,13 +121,11 @@ retry:
 | 
			
		||||
int
 | 
			
		||||
client_main(struct client_ctx *cctx)
 | 
			
		||||
{
 | 
			
		||||
	struct pollfd	 pfds[2];
 | 
			
		||||
	struct pollfd	 pfd;
 | 
			
		||||
	char		*error;
 | 
			
		||||
	int		 timeout;
 | 
			
		||||
 | 
			
		||||
	siginit();
 | 
			
		||||
	if ((cctx->loc_fd = local_init(&cctx->loc_in, &cctx->loc_out)) == -1)
 | 
			
		||||
		return (1);
 | 
			
		||||
 | 
			
		||||
	logfile("client");
 | 
			
		||||
#ifndef NO_SETPROCTITLE
 | 
			
		||||
@@ -140,33 +138,19 @@ client_main(struct client_ctx *cctx)
 | 
			
		||||
		if (sigwinch)
 | 
			
		||||
			client_handle_winch(cctx);
 | 
			
		||||
 | 
			
		||||
		pfds[0].fd = cctx->srv_fd;
 | 
			
		||||
		pfds[0].events = POLLIN;
 | 
			
		||||
		pfd.fd = cctx->srv_fd;
 | 
			
		||||
		pfd.events = POLLIN;
 | 
			
		||||
		if (BUFFER_USED(cctx->srv_out) > 0)
 | 
			
		||||
			pfds[0].events |= POLLOUT;
 | 
			
		||||
		pfds[1].fd = cctx->loc_fd;
 | 
			
		||||
		pfds[1].events = POLLIN;
 | 
			
		||||
		if (BUFFER_USED(cctx->loc_out) > 0)
 | 
			
		||||
			pfds[1].events |= POLLOUT;
 | 
			
		||||
			pfd.events |= POLLOUT;
 | 
			
		||||
	
 | 
			
		||||
		if (poll(pfds, 2, timeout) == -1) {
 | 
			
		||||
		if (poll(&pfd, 1, timeout) == -1) {
 | 
			
		||||
			if (errno == EAGAIN || errno == EINTR)
 | 
			
		||||
				continue;
 | 
			
		||||
			fatal("poll failed");
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (buffer_poll(&pfds[0], cctx->srv_in, cctx->srv_out) != 0)
 | 
			
		||||
		if (buffer_poll(&pfd, cctx->srv_in, cctx->srv_out) != 0)
 | 
			
		||||
			goto server_dead;
 | 
			
		||||
		if (buffer_poll(&pfds[1], cctx->loc_in, cctx->loc_out) != 0)
 | 
			
		||||
			goto local_dead;
 | 
			
		||||
 | 
			
		||||
		if (cctx->flags & CCTX_PAUSE) {
 | 
			
		||||
			usleep(750000);	
 | 
			
		||||
			cctx->flags = 0;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (client_process_local(cctx, &error) == -1)
 | 
			
		||||
			goto out;
 | 
			
		||||
 | 
			
		||||
		switch (client_msg_dispatch(cctx, &error)) {
 | 
			
		||||
		case -1:
 | 
			
		||||
@@ -183,8 +167,6 @@ client_main(struct client_ctx *cctx)
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
out:
 | 
			
		||||
 	local_done();
 | 
			
		||||
 
 | 
			
		||||
 	if (sigterm) {
 | 
			
		||||
 		printf("[terminated]\n");
 | 
			
		||||
 		return (1);
 | 
			
		||||
@@ -204,14 +186,8 @@ out:
 | 
			
		||||
	return (1);
 | 
			
		||||
 | 
			
		||||
server_dead:
 | 
			
		||||
	local_done();
 | 
			
		||||
 | 
			
		||||
	printf("[lost server]\n");
 | 
			
		||||
	return (0);
 | 
			
		||||
 | 
			
		||||
local_dead:
 | 
			
		||||
	/* Can't do much here. Log and die. */
 | 
			
		||||
	fatalx("local socket dead");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -229,24 +205,3 @@ client_handle_winch(struct client_ctx *cctx)
 | 
			
		||||
	
 | 
			
		||||
	sigwinch = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
client_process_local(struct client_ctx *cctx, unused char **error)
 | 
			
		||||
{
 | 
			
		||||
	struct buffer	*b;
 | 
			
		||||
	int		 key;
 | 
			
		||||
 | 
			
		||||
	b = buffer_create(BUFSIZ);
 | 
			
		||||
	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) {
 | 
			
		||||
		client_write_server(
 | 
			
		||||
		    cctx, MSG_KEYS, BUFFER_OUT(b), BUFFER_USED(b));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	buffer_destroy(b);
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: cmd-attach-session.c,v 1.9 2007-11-16 21:12:31 nicm Exp $ */
 | 
			
		||||
/* $Id: cmd-attach-session.c,v 1.10 2007-11-27 19:23:33 nicm Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -83,6 +83,7 @@ void
 | 
			
		||||
cmd_attach_session_exec(void *ptr, struct cmd_ctx *ctx)
 | 
			
		||||
{
 | 
			
		||||
	struct cmd_attach_session_data	*data = ptr;
 | 
			
		||||
	char				*cause;
 | 
			
		||||
 | 
			
		||||
	if (ctx->flags & CMD_KEY)
 | 
			
		||||
		return;
 | 
			
		||||
@@ -92,6 +93,12 @@ cmd_attach_session_exec(void *ptr, struct cmd_ctx *ctx)
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (tty_open(&ctx->cmdclient->tty, &cause) != 0) {
 | 
			
		||||
		ctx->error(ctx, "%s", cause);
 | 
			
		||||
		xfree(cause);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (data->flag_detach)
 | 
			
		||||
		server_write_session(ctx->session, MSG_DETACH, NULL, 0);
 | 
			
		||||
	ctx->cmdclient->session = ctx->session;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: cmd-copy-mode.c,v 1.1 2007-11-23 14:28:47 nicm Exp $ */
 | 
			
		||||
/* $Id: cmd-copy-mode.c,v 1.2 2007-11-27 19:23:33 nicm Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -47,7 +47,7 @@ cmd_copy_mode_exec(unused void *ptr, struct cmd_ctx *ctx)
 | 
			
		||||
	if (w->mode == NULL && ctx->flags & CMD_KEY) {
 | 
			
		||||
		w->mode = &window_copy_mode;
 | 
			
		||||
		w->mode->init(w);
 | 
			
		||||
		server_redraw_window_all(w);
 | 
			
		||||
		server_redraw_window(w);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (ctx->cmdclient != NULL)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: cmd-list-clients.c,v 1.2 2007-11-16 21:12:31 nicm Exp $ */
 | 
			
		||||
/* $Id: cmd-list-clients.c,v 1.3 2007-11-27 19:23:33 nicm Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -51,8 +51,8 @@ cmd_list_clients_exec(unused void *ptr, struct cmd_ctx *ctx)
 | 
			
		||||
		if (c == NULL || c->session == NULL)
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		ctx->print(ctx,
 | 
			
		||||
		    "%s: %s [%ux%u]", c->tty, c->session->name, c->sx, c->sy);
 | 
			
		||||
		ctx->print(ctx, "%s: %s [%ux%u]",
 | 
			
		||||
		    c->tty.path, c->session->name, c->sx, c->sy);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (ctx->cmdclient != NULL)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: cmd-new-session.c,v 1.17 2007-11-16 21:12:31 nicm Exp $ */
 | 
			
		||||
/* $Id: cmd-new-session.c,v 1.18 2007-11-27 19:23:33 nicm Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -100,8 +100,8 @@ cmd_new_session_exec(void *ptr, struct cmd_ctx *ctx)
 | 
			
		||||
{
 | 
			
		||||
	struct cmd_new_session_data	*data = ptr;
 | 
			
		||||
	struct cmd_new_session_data	 std = { NULL, NULL, NULL, 0 };
 | 
			
		||||
	struct client			*c;
 | 
			
		||||
	char				*cmd;
 | 
			
		||||
	struct client			*c = ctx->cmdclient;
 | 
			
		||||
	char				*cmd, *cause;
 | 
			
		||||
	u_int				 sy;
 | 
			
		||||
	
 | 
			
		||||
	if (data == NULL)
 | 
			
		||||
@@ -110,7 +110,6 @@ cmd_new_session_exec(void *ptr, struct cmd_ctx *ctx)
 | 
			
		||||
	if (ctx->flags & CMD_KEY)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	c = ctx->cmdclient;
 | 
			
		||||
	if (!data->flag_detached && !(c->flags & CLIENT_TERMINAL)) {
 | 
			
		||||
		ctx->error(ctx, "not a terminal");
 | 
			
		||||
		return;
 | 
			
		||||
@@ -126,6 +125,12 @@ cmd_new_session_exec(void *ptr, struct cmd_ctx *ctx)
 | 
			
		||||
		sy = status_lines + 1;
 | 
			
		||||
	sy -= status_lines;
 | 
			
		||||
 | 
			
		||||
	if (!data->flag_detached && tty_open(&c->tty, &cause) != 0) {
 | 
			
		||||
		ctx->error(ctx, "%s", cause);
 | 
			
		||||
		xfree(cause);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cmd = data->cmd;
 | 
			
		||||
	if (cmd == NULL)
 | 
			
		||||
		cmd = default_command;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: cmd-scroll-mode.c,v 1.3 2007-11-22 18:09:43 nicm Exp $ */
 | 
			
		||||
/* $Id: cmd-scroll-mode.c,v 1.4 2007-11-27 19:23:33 nicm Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -47,7 +47,7 @@ cmd_scroll_mode_exec(unused void *ptr, struct cmd_ctx *ctx)
 | 
			
		||||
	if (w->mode == NULL && ctx->flags & CMD_KEY) {
 | 
			
		||||
		w->mode = &window_scroll_mode;
 | 
			
		||||
		w->mode->init(w);
 | 
			
		||||
		server_redraw_window_all(w);
 | 
			
		||||
		server_redraw_window(w);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (ctx->cmdclient != NULL)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										10
									
								
								input-keys.c
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								input-keys.c
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: input-keys.c,v 1.3 2007-11-21 13:11:41 nicm Exp $ */
 | 
			
		||||
/* $Id: input-keys.c,v 1.4 2007-11-27 19:23:33 nicm Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -55,13 +55,13 @@ struct {
 | 
			
		||||
 | 
			
		||||
/* Translate a key code from client into an output key sequence. */
 | 
			
		||||
void
 | 
			
		||||
input_key(struct buffer *b, int key)
 | 
			
		||||
input_key(struct window *w, int key)
 | 
			
		||||
{
 | 
			
		||||
	u_int	i;
 | 
			
		||||
 | 
			
		||||
	log_debug2("writing key %d", key);
 | 
			
		||||
	if (key != KEYC_NONE && key >= 0) {
 | 
			
		||||
		input_store8(b, key);
 | 
			
		||||
		buffer_write8(w->out, (uint8_t) key);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -69,8 +69,8 @@ input_key(struct buffer *b, int key)
 | 
			
		||||
		if (input_keys[i].key == key) {
 | 
			
		||||
			log_debug2(
 | 
			
		||||
			    "found key %d: \"%s\"", key, input_keys[i].data);
 | 
			
		||||
			buffer_write(
 | 
			
		||||
			    b, input_keys[i].data, strlen(input_keys[i].data));
 | 
			
		||||
			buffer_write(w->out,
 | 
			
		||||
			    input_keys[i].data, strlen(input_keys[i].data));
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										217
									
								
								input.c
									
									
									
									
									
								
							
							
						
						
									
										217
									
								
								input.c
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: input.c,v 1.38 2007-11-24 23:29:49 nicm Exp $ */
 | 
			
		||||
/* $Id: input.c,v 1.39 2007-11-27 19:23:33 nicm Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -36,7 +36,9 @@
 | 
			
		||||
 | 
			
		||||
int	 input_get_argument(struct input_ctx *, u_int, uint16_t *, uint16_t);
 | 
			
		||||
int	 input_new_argument(struct input_ctx *);
 | 
			
		||||
int	 input_add_argument(struct input_ctx *, u_char ch);
 | 
			
		||||
int	 input_add_argument(struct input_ctx *, u_char);
 | 
			
		||||
 | 
			
		||||
void	 input_write(struct input_ctx *, int, ...);
 | 
			
		||||
 | 
			
		||||
void	*input_state_first(u_char, struct input_ctx *);
 | 
			
		||||
void	*input_state_escape(u_char, struct input_ctx *);
 | 
			
		||||
@@ -131,6 +133,19 @@ input_get_argument(struct input_ctx *ictx, u_int i, uint16_t *n, uint16_t d)
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
input_write(struct input_ctx *ictx, int cmd, ...)
 | 
			
		||||
{
 | 
			
		||||
	va_list	ap;
 | 
			
		||||
 | 
			
		||||
	if (ictx->w->screen.mode & (MODE_HIDDEN|MODE_BACKGROUND))
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	va_start(ap, cmd);
 | 
			
		||||
	tty_vwrite_window(ictx->w, cmd, ap);
 | 
			
		||||
	va_end(ap);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
input_init(struct window *w)
 | 
			
		||||
{
 | 
			
		||||
@@ -146,7 +161,7 @@ input_free(struct window *w)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
input_parse(struct window *w, struct buffer *b)
 | 
			
		||||
input_parse(struct window *w)
 | 
			
		||||
{
 | 
			
		||||
	struct input_ctx	*ictx = &w->ictx;
 | 
			
		||||
	u_char			 ch;
 | 
			
		||||
@@ -159,7 +174,6 @@ input_parse(struct window *w, struct buffer *b)
 | 
			
		||||
	ictx->off = 0;
 | 
			
		||||
 | 
			
		||||
	ictx->w = w;
 | 
			
		||||
	ictx->b = b;
 | 
			
		||||
 | 
			
		||||
	log_debug2("entry; buffer=%zu", ictx->len);
 | 
			
		||||
 | 
			
		||||
@@ -264,8 +278,7 @@ input_state_title_next(u_char ch, struct input_ctx *ictx)
 | 
			
		||||
		switch (ictx->title_type) {
 | 
			
		||||
		case 0:
 | 
			
		||||
			strlcpy(s->title, ictx->title_buf, sizeof s->title);
 | 
			
		||||
			input_store_one(ictx->b, CODE_TITLE, ictx->title_len);
 | 
			
		||||
			buffer_write(ictx->b, ictx->title_buf, ictx->title_len);
 | 
			
		||||
			input_write(ictx, TTY_TITLE, s->title);
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		return (input_state_first);
 | 
			
		||||
@@ -373,10 +386,8 @@ input_handle_character(u_char ch, struct input_ctx *ictx)
 | 
			
		||||
	log_debug2("-- ch %zu: %hhu (%c)", ictx->off, ch, ch);
 | 
			
		||||
	
 | 
			
		||||
	if (s->cx == screen_size_x(s)) {
 | 
			
		||||
		if (!screen_hidden(s)) {
 | 
			
		||||
			input_store8(ictx->b, '\r');
 | 
			
		||||
			input_store8(ictx->b, '\n');
 | 
			
		||||
		}
 | 
			
		||||
		input_write(ictx, TTY_CHARACTER, '\r');
 | 
			
		||||
		input_write(ictx, TTY_CHARACTER, '\n');
 | 
			
		||||
 | 
			
		||||
		s->cx = 0;
 | 
			
		||||
		screen_display_cursor_down(s);
 | 
			
		||||
@@ -384,8 +395,7 @@ input_handle_character(u_char ch, struct input_ctx *ictx)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	screen_display_cursor_set(s, ch);
 | 
			
		||||
	if (!screen_hidden(s))
 | 
			
		||||
		input_store8(ictx->b, ch);
 | 
			
		||||
	input_write(ictx, TTY_CHARACTER, ch);
 | 
			
		||||
 | 
			
		||||
	s->cx++;
 | 
			
		||||
}
 | 
			
		||||
@@ -399,7 +409,7 @@ input_handle_c0_control(u_char ch, struct input_ctx *ictx)
 | 
			
		||||
 | 
			
		||||
	switch (ch) {
 | 
			
		||||
	case '\0':	/* NUL */
 | 
			
		||||
		break;
 | 
			
		||||
		return;
 | 
			
		||||
	case '\n':	/* LF */
 | 
			
		||||
 		screen_display_cursor_down(s);
 | 
			
		||||
		break;
 | 
			
		||||
@@ -419,28 +429,21 @@ input_handle_c0_control(u_char ch, struct input_ctx *ictx)
 | 
			
		||||
			s->cx = 0;
 | 
			
		||||
			screen_display_cursor_down(s);
 | 
			
		||||
		}
 | 
			
		||||
		if (screen_hidden(s))
 | 
			
		||||
			return;
 | 
			
		||||
		input_store_two(ictx->b, CODE_CURSORMOVE, s->cy + 1, s->cx + 1);
 | 
			
		||||
		input_write(ictx, TTY_CURSORMOVE, s->cy, s->cx);
 | 
			
		||||
		return;
 | 
			
		||||
	case '\016':	/* SO */
 | 
			
		||||
		s->attr |= ATTR_DRAWING;
 | 
			
		||||
		if (screen_hidden(s))
 | 
			
		||||
			return;
 | 
			
		||||
		input_store_two(ictx->b, CODE_ATTRIBUTES, s->attr, s->colr);
 | 
			
		||||
		input_write(ictx, TTY_ATTRIBUTES, s->attr, s->colr);
 | 
			
		||||
		return;
 | 
			
		||||
	case '\017':	/* SI */
 | 
			
		||||
		s->attr &= ~ATTR_DRAWING;
 | 
			
		||||
		if (screen_hidden(s))
 | 
			
		||||
			return;
 | 
			
		||||
		input_store_two(ictx->b, CODE_ATTRIBUTES, s->attr, s->colr);
 | 
			
		||||
		input_write(ictx, TTY_ATTRIBUTES, s->attr, s->colr);
 | 
			
		||||
		return;
 | 
			
		||||
	default:
 | 
			
		||||
		log_debug("unknown c0: %hhu", ch);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	if (!screen_hidden(s))
 | 
			
		||||
		input_store8(ictx->b, ch);
 | 
			
		||||
	input_write(ictx, TTY_CHARACTER, ch);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -453,8 +456,7 @@ input_handle_c1_control(u_char ch, struct input_ctx *ictx)
 | 
			
		||||
	switch (ch) {
 | 
			
		||||
	case 'M':	/* RI */
 | 
			
		||||
		screen_display_cursor_up(s);
 | 
			
		||||
		if (!screen_hidden(s))
 | 
			
		||||
			input_store_zero(ictx->b, CODE_REVERSEINDEX);
 | 
			
		||||
		input_write(ictx, TTY_REVERSEINDEX);
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		log_debug("unknown c1: %hhu", ch);
 | 
			
		||||
@@ -471,12 +473,10 @@ input_handle_private_two(u_char ch, struct input_ctx *ictx)
 | 
			
		||||
 | 
			
		||||
	switch (ch) {
 | 
			
		||||
	case '=':	/* DECKPAM */
 | 
			
		||||
		if (!screen_hidden(s))
 | 
			
		||||
			input_store_zero(ictx->b, CODE_KKEYPADON);
 | 
			
		||||
		input_write(ictx, TTY_KKEYPADON);
 | 
			
		||||
		break;
 | 
			
		||||
	case '>':	/* DECKPNM*/
 | 
			
		||||
		if (!screen_hidden(s))
 | 
			
		||||
			input_store_zero(ictx->b, CODE_KKEYPADOFF);
 | 
			
		||||
		input_write(ictx, TTY_KKEYPADOFF);
 | 
			
		||||
		break;
 | 
			
		||||
	case '7':	/* DECSC */
 | 
			
		||||
		s->saved_cx = s->cx;
 | 
			
		||||
@@ -492,10 +492,8 @@ input_handle_private_two(u_char ch, struct input_ctx *ictx)
 | 
			
		||||
		s->cy = s->saved_cy;
 | 
			
		||||
		s->attr = s->saved_attr;
 | 
			
		||||
		s->colr = s->saved_colr;
 | 
			
		||||
		if (screen_hidden(s))
 | 
			
		||||
			break;
 | 
			
		||||
		input_store_two(ictx->b, CODE_ATTRIBUTES, s->attr, s->colr);
 | 
			
		||||
		input_store_two(ictx->b, CODE_CURSORMOVE, s->cy + 1, s->cx + 1);
 | 
			
		||||
		input_write(ictx, TTY_ATTRIBUTES, s->attr, s->colr);
 | 
			
		||||
		input_write(ictx, TTY_CURSORMOVE, s->cy, s->cx);
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		log_debug("unknown p2: %hhu", ch);
 | 
			
		||||
@@ -583,8 +581,7 @@ input_handle_sequence_cuu(struct input_ctx *ictx)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	s->cy -= n;
 | 
			
		||||
	if (!screen_hidden(s))
 | 
			
		||||
		input_store_one(ictx->b, CODE_CURSORUP, n);
 | 
			
		||||
	input_write(ictx, TTY_CURSORUP, n);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -606,8 +603,7 @@ input_handle_sequence_cud(struct input_ctx *ictx)
 | 
			
		||||
	input_limit(n, 1, screen_last_y(s) - s->cy);
 | 
			
		||||
 | 
			
		||||
	s->cy += n;
 | 
			
		||||
	if (!screen_hidden(s))
 | 
			
		||||
		input_store_one(ictx->b, CODE_CURSORDOWN, n);
 | 
			
		||||
	input_write(ictx, TTY_CURSORDOWN, n);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -629,8 +625,7 @@ input_handle_sequence_cuf(struct input_ctx *ictx)
 | 
			
		||||
	input_limit(n, 1, screen_last_x(s) - s->cx);
 | 
			
		||||
 | 
			
		||||
	s->cx += n;
 | 
			
		||||
	if (!screen_hidden(s))
 | 
			
		||||
		input_store_one(ictx->b, CODE_CURSORRIGHT, n);
 | 
			
		||||
	input_write(ictx, TTY_CURSORRIGHT, n);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -653,8 +648,7 @@ input_handle_sequence_cub(struct input_ctx *ictx)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	s->cx -= n;
 | 
			
		||||
	if (!screen_hidden(s))
 | 
			
		||||
		input_store_one(ictx->b, CODE_CURSORLEFT, n);
 | 
			
		||||
	input_write(ictx, TTY_CURSORLEFT, n);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -676,8 +670,7 @@ input_handle_sequence_dch(struct input_ctx *ictx)
 | 
			
		||||
	input_limit(n, 1, screen_last_x(s) - s->cx);
 | 
			
		||||
 | 
			
		||||
	screen_display_delete_characters(s, s->cx, s->cy, n);
 | 
			
		||||
	if (!screen_hidden(s))
 | 
			
		||||
		input_store_one(ictx->b, CODE_DELETECHARACTER, n);
 | 
			
		||||
	input_write(ictx, TTY_DELETECHARACTER, n);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -702,8 +695,7 @@ input_handle_sequence_dl(struct input_ctx *ictx)
 | 
			
		||||
		screen_display_delete_lines(s, s->cy, n);
 | 
			
		||||
	else
 | 
			
		||||
		screen_display_delete_lines_region(s, s->cy, n);
 | 
			
		||||
	if (!screen_hidden(s)) 
 | 
			
		||||
		input_store_one(ictx->b, CODE_DELETELINE, n);
 | 
			
		||||
	input_write(ictx, TTY_DELETELINE, n);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -725,8 +717,7 @@ input_handle_sequence_ich(struct input_ctx *ictx)
 | 
			
		||||
	input_limit(n, 1, screen_last_x(s) - s->cx);
 | 
			
		||||
 | 
			
		||||
	screen_display_insert_characters(s, s->cx, s->cy, n);
 | 
			
		||||
	if (!screen_hidden(s))
 | 
			
		||||
		input_store_one(ictx->b, CODE_INSERTCHARACTER, n);
 | 
			
		||||
	input_write(ictx, TTY_INSERTCHARACTER, n);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -751,8 +742,7 @@ input_handle_sequence_il(struct input_ctx *ictx)
 | 
			
		||||
		screen_display_insert_lines(s, s->cy, n);
 | 
			
		||||
	else
 | 
			
		||||
		screen_display_insert_lines_region(s, s->cy, n);
 | 
			
		||||
	if (!screen_hidden(s))
 | 
			
		||||
		input_store_one(ictx->b, CODE_INSERTLINE, n);
 | 
			
		||||
	input_write(ictx, TTY_INSERTLINE, n);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -774,8 +764,7 @@ input_handle_sequence_vpa(struct input_ctx *ictx)
 | 
			
		||||
	input_limit(n, 1, screen_size_y(s));
 | 
			
		||||
 | 
			
		||||
	s->cy = n - 1;
 | 
			
		||||
	if (!screen_hidden(s))
 | 
			
		||||
		input_store_two(ictx->b, CODE_CURSORMOVE, n, s->cx + 1);
 | 
			
		||||
	input_write(ictx, TTY_CURSORMOVE, s->cy, s->cx);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -797,8 +786,7 @@ input_handle_sequence_hpa(struct input_ctx *ictx)
 | 
			
		||||
	input_limit(n, 1, screen_size_x(s));
 | 
			
		||||
 | 
			
		||||
	s->cx = n - 1;
 | 
			
		||||
	if (!screen_hidden(s))
 | 
			
		||||
		input_store_two(ictx->b, CODE_CURSORMOVE, s->cy + 1, n);
 | 
			
		||||
	input_write(ictx, TTY_CURSORMOVE, s->cy, s->cx);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -822,8 +810,7 @@ input_handle_sequence_cup(struct input_ctx *ictx)
 | 
			
		||||
 | 
			
		||||
	s->cx = m - 1;
 | 
			
		||||
	s->cy = n - 1;
 | 
			
		||||
	if (!screen_hidden(s))
 | 
			
		||||
		input_store_two(ictx->b, CODE_CURSORMOVE, n, m);
 | 
			
		||||
	input_write(ictx, TTY_CURSORMOVE, s->cy, s->cx);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -849,28 +836,21 @@ input_handle_sequence_ed(struct input_ctx *ictx)
 | 
			
		||||
		screen_display_fill_cursor_eos(
 | 
			
		||||
		    s, SCREEN_DEFDATA, s->attr, s->colr);
 | 
			
		||||
 | 
			
		||||
		if (screen_hidden(s))
 | 
			
		||||
			break;
 | 
			
		||||
		input_store_zero(ictx->b, CODE_CLEARLINE);
 | 
			
		||||
		for (i = s->cy + 1; i < screen_size_y(s); i++) {
 | 
			
		||||
			input_store_two(ictx->b, CODE_CURSORMOVE, i + 1, 1);
 | 
			
		||||
			input_store_zero(ictx->b, CODE_CLEARLINE);
 | 
			
		||||
		for (i = s->cy; i < screen_size_y(s); i++) {
 | 
			
		||||
			input_write(ictx, TTY_CURSORMOVE, i, 0);
 | 
			
		||||
			input_write(ictx, TTY_CLEARENDOFLINE);
 | 
			
		||||
		}
 | 
			
		||||
		input_store_two(
 | 
			
		||||
		    ictx->b, CODE_CURSORMOVE, s->cy + 1, s->cx + 1);
 | 
			
		||||
		input_write(ictx, TTY_CURSORMOVE, s->cy, s->cx);
 | 
			
		||||
		break;
 | 
			
		||||
	case 2:
 | 
			
		||||
		screen_display_fill_lines(
 | 
			
		||||
		    s, 0, screen_size_y(s), SCREEN_DEFDATA, s->attr, s->colr);
 | 
			
		||||
 | 
			
		||||
		if (screen_hidden(s))
 | 
			
		||||
			break;
 | 
			
		||||
		for (i = 0; i < screen_size_y(s); i++) {
 | 
			
		||||
			input_store_two(ictx->b, CODE_CURSORMOVE, i + 1, 1);
 | 
			
		||||
			input_store_zero(ictx->b, CODE_CLEARLINE);
 | 
			
		||||
			input_write(ictx, TTY_CURSORMOVE, i, 0);
 | 
			
		||||
			input_write(ictx, TTY_CLEARENDOFLINE);
 | 
			
		||||
		}
 | 
			
		||||
		input_store_two(
 | 
			
		||||
		    ictx->b, CODE_CURSORMOVE, s->cy + 1, s->cx + 1);
 | 
			
		||||
		input_write(ictx, TTY_CURSORMOVE, s->cy, s->cx);
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -896,23 +876,17 @@ input_handle_sequence_el(struct input_ctx *ictx)
 | 
			
		||||
	case 0:
 | 
			
		||||
		screen_display_fill_cursor_eol(
 | 
			
		||||
		    s, SCREEN_DEFDATA, s->attr, s->colr);
 | 
			
		||||
 | 
			
		||||
		if (!screen_hidden(s))
 | 
			
		||||
			input_store_zero(ictx->b, CODE_CLEARENDOFLINE);
 | 
			
		||||
		input_write(ictx, TTY_CLEARENDOFLINE);
 | 
			
		||||
		break;
 | 
			
		||||
	case 1:
 | 
			
		||||
		screen_display_fill_cursor_bol(
 | 
			
		||||
		    s, SCREEN_DEFDATA, s->attr, s->colr);
 | 
			
		||||
 | 
			
		||||
		if (!screen_hidden(s))
 | 
			
		||||
			input_store_zero(ictx->b, CODE_CLEARSTARTOFLINE);
 | 
			
		||||
		input_write(ictx, TTY_CLEARSTARTOFLINE);
 | 
			
		||||
		break;
 | 
			
		||||
	case 2:
 | 
			
		||||
		screen_display_fill_line(
 | 
			
		||||
		    s, s->cy, SCREEN_DEFDATA, s->attr, s->colr);
 | 
			
		||||
 | 
			
		||||
		if (!screen_hidden(s))
 | 
			
		||||
			input_store_zero(ictx->b, CODE_CLEARLINE);
 | 
			
		||||
		input_write(ictx, TTY_CLEARLINE);
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -932,13 +906,11 @@ input_handle_sequence_sm(struct input_ctx *ictx)
 | 
			
		||||
		switch (n) {
 | 
			
		||||
		case 1:		/* GATM */
 | 
			
		||||
			s->mode |= MODE_KCURSOR;
 | 
			
		||||
			if (!screen_hidden(s))
 | 
			
		||||
				input_store_zero(ictx->b, CODE_KCURSORON);
 | 
			
		||||
			input_write(ictx, TTY_KCURSORON);
 | 
			
		||||
			break;
 | 
			
		||||
		case 25:	/* TCEM */
 | 
			
		||||
			s->mode |= MODE_CURSOR;
 | 
			
		||||
			if (!screen_hidden(s))
 | 
			
		||||
				input_store_zero(ictx->b, CODE_CURSORON);
 | 
			
		||||
			input_write(ictx, TTY_CURSORON);
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			log_debug("unknown SM [%hhu]: %u", ictx->private, n);
 | 
			
		||||
@@ -948,8 +920,7 @@ input_handle_sequence_sm(struct input_ctx *ictx)
 | 
			
		||||
		switch (n) {
 | 
			
		||||
		case 4:		/* IRM */
 | 
			
		||||
			s->mode |= MODE_INSERT;
 | 
			
		||||
			if (!screen_hidden(s))
 | 
			
		||||
				input_store_zero(ictx->b, CODE_INSERTON);
 | 
			
		||||
			input_write(ictx, TTY_INSERTON);
 | 
			
		||||
			break;
 | 
			
		||||
		case 34:
 | 
			
		||||
			/* Cursor high visibility not supported. */
 | 
			
		||||
@@ -976,13 +947,11 @@ input_handle_sequence_rm(struct input_ctx *ictx)
 | 
			
		||||
		switch (n) {
 | 
			
		||||
		case 1:		/* GATM */
 | 
			
		||||
			s->mode &= ~MODE_KCURSOR;
 | 
			
		||||
			if (!screen_hidden(s))
 | 
			
		||||
				input_store_zero(ictx->b, CODE_KCURSOROFF);
 | 
			
		||||
			input_write(ictx, TTY_KCURSOROFF);
 | 
			
		||||
			break;
 | 
			
		||||
		case 25:	/* TCEM */
 | 
			
		||||
			s->mode &= ~MODE_CURSOR;
 | 
			
		||||
			if (!screen_hidden(s))
 | 
			
		||||
				input_store_zero(ictx->b, CODE_CURSOROFF);
 | 
			
		||||
			input_write(ictx, TTY_CURSOROFF);
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			log_debug("unknown RM [%hhu]: %u", ictx->private, n);
 | 
			
		||||
@@ -992,8 +961,7 @@ input_handle_sequence_rm(struct input_ctx *ictx)
 | 
			
		||||
		switch (n) {
 | 
			
		||||
		case 4:		/* IRM */
 | 
			
		||||
			s->mode &= ~MODE_INSERT;
 | 
			
		||||
			if (!screen_hidden(s))
 | 
			
		||||
				input_store_zero(ictx->b, CODE_INSERTOFF);
 | 
			
		||||
			input_write(ictx, TTY_INSERTOFF);
 | 
			
		||||
			break;
 | 
			
		||||
		case 34:
 | 
			
		||||
			/* Cursor high visibility not supported. */
 | 
			
		||||
@@ -1067,8 +1035,7 @@ input_handle_sequence_decstbm(struct input_ctx *ictx)
 | 
			
		||||
 | 
			
		||||
	s->rupper = n - 1;
 | 
			
		||||
	s->rlower = m - 1;
 | 
			
		||||
	if (!screen_hidden(s))
 | 
			
		||||
		input_store_two(ictx->b, CODE_SCROLLREGION, n, m);
 | 
			
		||||
	input_write(ictx, TTY_SCROLLREGION, s->rupper, s->rlower);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -1152,67 +1119,5 @@ input_handle_sequence_sgr(struct input_ctx *ictx)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if (!screen_hidden(s))
 | 
			
		||||
		input_store_two(ictx->b, CODE_ATTRIBUTES, s->attr, s->colr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
input_store_zero(struct buffer *b, u_char code)
 | 
			
		||||
{
 | 
			
		||||
	input_store8(b, '\e');
 | 
			
		||||
	input_store8(b, code);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
input_store_one(struct buffer *b, u_char code, uint16_t ua)
 | 
			
		||||
{
 | 
			
		||||
	input_store8(b, '\e');
 | 
			
		||||
	input_store8(b, code);
 | 
			
		||||
	input_store16(b, ua);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
input_store_two(struct buffer *b, u_char code, uint16_t ua, uint16_t ub)
 | 
			
		||||
{
 | 
			
		||||
	input_store8(b, '\e');
 | 
			
		||||
	input_store8(b, code);
 | 
			
		||||
	input_store16(b, ua);
 | 
			
		||||
	input_store16(b, ub);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
input_store8(struct buffer *b, uint8_t n)
 | 
			
		||||
{
 | 
			
		||||
	buffer_ensure(b, 1);
 | 
			
		||||
	BUFFER_IN(b)[0] = n;
 | 
			
		||||
	buffer_add(b, 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
input_store16(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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t
 | 
			
		||||
input_extract8(struct buffer *b)
 | 
			
		||||
{
 | 
			
		||||
	uint8_t	n;
 | 
			
		||||
 | 
			
		||||
	n = BUFFER_OUT(b)[0];
 | 
			
		||||
	buffer_remove(b, 1);
 | 
			
		||||
	return (n);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint16_t
 | 
			
		||||
input_extract16(struct buffer *b)
 | 
			
		||||
{
 | 
			
		||||
	uint16_t	n;
 | 
			
		||||
 | 
			
		||||
	n = BUFFER_OUT(b)[0] | (BUFFER_OUT(b)[1] << 8);
 | 
			
		||||
	buffer_remove(b, 2);
 | 
			
		||||
	return (n);
 | 
			
		||||
	input_write(ictx, TTY_ATTRIBUTES, s->attr, s->colr);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: key-bindings.c,v 1.21 2007-11-23 17:52:54 nicm Exp $ */
 | 
			
		||||
/* $Id: key-bindings.c,v 1.22 2007-11-27 19:23:33 nicm Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -204,5 +204,5 @@ key_bindings_dispatch(int key, struct client *c)
 | 
			
		||||
	cmd_exec(bd->cmd, &ctx);
 | 
			
		||||
	
 | 
			
		||||
	if (c->session->curw->window->mode == &window_more_mode)
 | 
			
		||||
		server_redraw_window_all(c->session->curw->window);
 | 
			
		||||
		server_redraw_window(c->session->curw->window);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										793
									
								
								local.c
									
									
									
									
									
								
							
							
						
						
									
										793
									
								
								local.c
									
									
									
									
									
								
							@@ -1,793 +0,0 @@
 | 
			
		||||
/* $Id: local.c,v 1.23 2007-11-26 20:36:30 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 <sys/ioctl.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
 | 
			
		||||
#include <curses.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#define TTYDEFCHARS
 | 
			
		||||
/* glibc requires unistd.h before termios.h for TTYDEFCHARS. */
 | 
			
		||||
#include <unistd.h>	
 | 
			
		||||
#include <termios.h>
 | 
			
		||||
#include <term.h>
 | 
			
		||||
 | 
			
		||||
#include "tmux.h"
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Functions to translate input and write output to the local client terminal.
 | 
			
		||||
 * This file should probably be called tty or terminal.c.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
int	local_cmp(const void *, const void *);
 | 
			
		||||
int	local_putc(int);
 | 
			
		||||
void	local_putp(const char *);
 | 
			
		||||
void	local_attributes(u_char, u_char);
 | 
			
		||||
u_char	local_translate_acs(u_char);
 | 
			
		||||
 | 
			
		||||
/* Local key types and key codes. */
 | 
			
		||||
struct local_key {
 | 
			
		||||
	const char	*name;
 | 
			
		||||
	char		*string;
 | 
			
		||||
	size_t		 size;
 | 
			
		||||
	int	 	 code;
 | 
			
		||||
};
 | 
			
		||||
struct local_key local_keys[] = {
 | 
			
		||||
	{ "ka1",   NULL, 0, KEYC_A1 },
 | 
			
		||||
	{ "ka3",   NULL, 0, KEYC_A3 },
 | 
			
		||||
	{ "kb2",   NULL, 0, KEYC_B2 },
 | 
			
		||||
	{ "kbeg",  NULL, 0, KEYC_BEG },
 | 
			
		||||
	{ "kcbt",  NULL, 0, KEYC_BTAB },
 | 
			
		||||
	{ "kc1",   NULL, 0, KEYC_C1 },
 | 
			
		||||
	{ "kc3",   NULL, 0, KEYC_C3 },
 | 
			
		||||
	{ "kcan",  NULL, 0, KEYC_CANCEL },
 | 
			
		||||
	{ "ktbc",  NULL, 0, KEYC_CATAB },
 | 
			
		||||
	{ "kclr",  NULL, 0, KEYC_CLEAR },
 | 
			
		||||
	{ "kclo",  NULL, 0, KEYC_CLOSE },
 | 
			
		||||
	{ "kcmd",  NULL, 0, KEYC_COMMAND },
 | 
			
		||||
	{ "kcpy",  NULL, 0, KEYC_COPY },
 | 
			
		||||
	{ "kcrt",  NULL, 0, KEYC_CREATE },
 | 
			
		||||
	{ "kctab", NULL, 0, KEYC_CTAB },
 | 
			
		||||
	{ "kdch1", NULL, 0, KEYC_DC },
 | 
			
		||||
	{ "kdl1",  NULL, 0, KEYC_DL },
 | 
			
		||||
	{ "kcud1", NULL, 0, KEYC_DOWN },
 | 
			
		||||
	{ "krmir", NULL, 0, KEYC_EIC },
 | 
			
		||||
	{ "kend",  NULL, 0, KEYC_END },
 | 
			
		||||
	{ "kent",  NULL, 0, KEYC_ENTER },
 | 
			
		||||
	{ "kel",   NULL, 0, KEYC_EOL },
 | 
			
		||||
	{ "ked",   NULL, 0, KEYC_EOS },
 | 
			
		||||
	{ "kext",  NULL, 0, KEYC_EXIT },
 | 
			
		||||
	{ "kf0",   NULL, 0, KEYC_F0 },
 | 
			
		||||
	{ "kf1",   NULL, 0, KEYC_F1 },
 | 
			
		||||
	{ "kf10",  NULL, 0, KEYC_F10 },
 | 
			
		||||
	{ "kf11",  NULL, 0, KEYC_F11 },
 | 
			
		||||
	{ "kf12",  NULL, 0, KEYC_F12 },
 | 
			
		||||
	{ "kf13",  NULL, 0, KEYC_F13 },
 | 
			
		||||
	{ "kf14",  NULL, 0, KEYC_F14 },
 | 
			
		||||
	{ "kf15",  NULL, 0, KEYC_F15 },
 | 
			
		||||
	{ "kf16",  NULL, 0, KEYC_F16 },
 | 
			
		||||
	{ "kf17",  NULL, 0, KEYC_F17 },
 | 
			
		||||
	{ "kf18",  NULL, 0, KEYC_F18 },
 | 
			
		||||
	{ "kf19",  NULL, 0, KEYC_F19 },
 | 
			
		||||
	{ "kf2",   NULL, 0, KEYC_F2 },
 | 
			
		||||
	{ "kf20",  NULL, 0, KEYC_F20 },
 | 
			
		||||
	{ "kf21",  NULL, 0, KEYC_F21 },
 | 
			
		||||
	{ "kf22",  NULL, 0, KEYC_F22 },
 | 
			
		||||
	{ "kf23",  NULL, 0, KEYC_F23 },
 | 
			
		||||
	{ "kf24",  NULL, 0, KEYC_F24 },
 | 
			
		||||
	{ "kf25",  NULL, 0, KEYC_F25 },
 | 
			
		||||
	{ "kf26",  NULL, 0, KEYC_F26 },
 | 
			
		||||
	{ "kf27",  NULL, 0, KEYC_F27 },
 | 
			
		||||
	{ "kf28",  NULL, 0, KEYC_F28 },
 | 
			
		||||
	{ "kf29",  NULL, 0, KEYC_F29 },
 | 
			
		||||
	{ "kf3",   NULL, 0, KEYC_F3 },
 | 
			
		||||
	{ "kf30",  NULL, 0, KEYC_F30 },
 | 
			
		||||
	{ "kf31",  NULL, 0, KEYC_F31 },
 | 
			
		||||
	{ "kf32",  NULL, 0, KEYC_F32 },
 | 
			
		||||
	{ "kf33",  NULL, 0, KEYC_F33 },
 | 
			
		||||
	{ "kf34",  NULL, 0, KEYC_F34 },
 | 
			
		||||
	{ "kf35",  NULL, 0, KEYC_F35 },
 | 
			
		||||
	{ "kf36",  NULL, 0, KEYC_F36 },
 | 
			
		||||
	{ "kf37",  NULL, 0, KEYC_F37 },
 | 
			
		||||
	{ "kf38",  NULL, 0, KEYC_F38 },
 | 
			
		||||
	{ "kf39",  NULL, 0, KEYC_F39 },
 | 
			
		||||
	{ "kf4",   NULL, 0, KEYC_F4 },
 | 
			
		||||
	{ "kf40",  NULL, 0, KEYC_F40 },
 | 
			
		||||
	{ "kf41",  NULL, 0, KEYC_F41 },
 | 
			
		||||
	{ "kf42",  NULL, 0, KEYC_F42 },
 | 
			
		||||
	{ "kf43",  NULL, 0, KEYC_F43 },
 | 
			
		||||
	{ "kf44",  NULL, 0, KEYC_F44 },
 | 
			
		||||
	{ "kf45",  NULL, 0, KEYC_F45 },
 | 
			
		||||
	{ "kf46",  NULL, 0, KEYC_F46 },
 | 
			
		||||
	{ "kf47",  NULL, 0, KEYC_F47 },
 | 
			
		||||
	{ "kf48",  NULL, 0, KEYC_F48 },
 | 
			
		||||
	{ "kf49",  NULL, 0, KEYC_F49 },
 | 
			
		||||
	{ "kf5",   NULL, 0, KEYC_F5 },
 | 
			
		||||
	{ "kf50",  NULL, 0, KEYC_F50 },
 | 
			
		||||
	{ "kf51",  NULL, 0, KEYC_F51 },
 | 
			
		||||
	{ "kf52",  NULL, 0, KEYC_F52 },
 | 
			
		||||
	{ "kf53",  NULL, 0, KEYC_F53 },
 | 
			
		||||
	{ "kf54",  NULL, 0, KEYC_F54 },
 | 
			
		||||
	{ "kf55",  NULL, 0, KEYC_F55 },
 | 
			
		||||
	{ "kf56",  NULL, 0, KEYC_F56 },
 | 
			
		||||
	{ "kf57",  NULL, 0, KEYC_F57 },
 | 
			
		||||
	{ "kf58",  NULL, 0, KEYC_F58 },
 | 
			
		||||
	{ "kf59",  NULL, 0, KEYC_F59 },
 | 
			
		||||
	{ "kf6",   NULL, 0, KEYC_F6 },
 | 
			
		||||
	{ "kf60",  NULL, 0, KEYC_F60 },
 | 
			
		||||
	{ "kf61",  NULL, 0, KEYC_F61 },
 | 
			
		||||
	{ "kf62",  NULL, 0, KEYC_F62 },
 | 
			
		||||
	{ "kf63",  NULL, 0, KEYC_F63 },
 | 
			
		||||
	{ "kf7",   NULL, 0, KEYC_F7 },
 | 
			
		||||
	{ "kf8",   NULL, 0, KEYC_F8 },
 | 
			
		||||
	{ "kf9",   NULL, 0, KEYC_F9 },
 | 
			
		||||
	{ "kfnd",  NULL, 0, KEYC_FIND },
 | 
			
		||||
	{ "khlp",  NULL, 0, KEYC_HELP },
 | 
			
		||||
	{ "khome", NULL, 0, KEYC_HOME },
 | 
			
		||||
	{ "kich1", NULL, 0, KEYC_IC },
 | 
			
		||||
	{ "kil1",  NULL, 0, KEYC_IL },
 | 
			
		||||
	{ "kcub1", NULL, 0, KEYC_LEFT },
 | 
			
		||||
	{ "kll",   NULL, 0, KEYC_LL },
 | 
			
		||||
	{ "kmrk",  NULL, 0, KEYC_MARK },
 | 
			
		||||
	{ "kmsg",  NULL, 0, KEYC_MESSAGE },
 | 
			
		||||
	{ "kmov",  NULL, 0, KEYC_MOVE },
 | 
			
		||||
	{ "knxt",  NULL, 0, KEYC_NEXT },
 | 
			
		||||
	{ "knp",   NULL, 0, KEYC_NPAGE },
 | 
			
		||||
	{ "kopn",  NULL, 0, KEYC_OPEN },
 | 
			
		||||
	{ "kopt",  NULL, 0, KEYC_OPTIONS },
 | 
			
		||||
	{ "kpp",   NULL, 0, KEYC_PPAGE },
 | 
			
		||||
	{ "kprv",  NULL, 0, KEYC_PREVIOUS },
 | 
			
		||||
	{ "kprt",  NULL, 0, KEYC_PRINT },
 | 
			
		||||
	{ "krdo",  NULL, 0, KEYC_REDO },
 | 
			
		||||
	{ "kref",  NULL, 0, KEYC_REFERENCE },
 | 
			
		||||
	{ "krfr",  NULL, 0, KEYC_REFRESH },
 | 
			
		||||
	{ "krpl",  NULL, 0, KEYC_REPLACE },
 | 
			
		||||
	{ "krst",  NULL, 0, KEYC_RESTART },
 | 
			
		||||
	{ "kres",  NULL, 0, KEYC_RESUME },
 | 
			
		||||
	{ "kcuf1", NULL, 0, KEYC_RIGHT },
 | 
			
		||||
	{ "ksav",  NULL, 0, KEYC_SAVE },
 | 
			
		||||
	{ "kBEG",  NULL, 0, KEYC_SBEG },
 | 
			
		||||
	{ "kCAN",  NULL, 0, KEYC_SCANCEL },
 | 
			
		||||
	{ "kCMD",  NULL, 0, KEYC_SCOMMAND },
 | 
			
		||||
	{ "kCPY",  NULL, 0, KEYC_SCOPY },
 | 
			
		||||
	{ "kCRT",  NULL, 0, KEYC_SCREATE },
 | 
			
		||||
	{ "kDC",   NULL, 0, KEYC_SDC },
 | 
			
		||||
	{ "kDL",   NULL, 0, KEYC_SDL },
 | 
			
		||||
	{ "kslt",  NULL, 0, KEYC_SELECT },
 | 
			
		||||
	{ "kEND",  NULL, 0, KEYC_SEND },
 | 
			
		||||
	{ "kEOL",  NULL, 0, KEYC_SEOL },
 | 
			
		||||
	{ "kEXT",  NULL, 0, KEYC_SEXIT },
 | 
			
		||||
	{ "kind",  NULL, 0, KEYC_SF },
 | 
			
		||||
	{ "kFND",  NULL, 0, KEYC_SFIND },
 | 
			
		||||
	{ "kHLP",  NULL, 0, KEYC_SHELP },
 | 
			
		||||
	{ "kHOM",  NULL, 0, KEYC_SHOME },
 | 
			
		||||
	{ "kIC",   NULL, 0, KEYC_SIC },
 | 
			
		||||
	{ "kLFT",  NULL, 0, KEYC_SLEFT },
 | 
			
		||||
	{ "kMSG",  NULL, 0, KEYC_SMESSAGE },
 | 
			
		||||
	{ "kMOV",  NULL, 0, KEYC_SMOVE },
 | 
			
		||||
	{ "kNXT",  NULL, 0, KEYC_SNEXT },
 | 
			
		||||
	{ "kOPT",  NULL, 0, KEYC_SOPTIONS },
 | 
			
		||||
	{ "kPRV",  NULL, 0, KEYC_SPREVIOUS },
 | 
			
		||||
	{ "kPRT",  NULL, 0, KEYC_SPRINT },
 | 
			
		||||
	{ "kri",   NULL, 0, KEYC_SR },
 | 
			
		||||
	{ "kRDO",  NULL, 0, KEYC_SREDO },
 | 
			
		||||
	{ "kRPL",  NULL, 0, KEYC_SREPLACE },
 | 
			
		||||
	{ "kRIT",  NULL, 0, KEYC_SRIGHT },
 | 
			
		||||
	{ "kRES",  NULL, 0, KEYC_SRSUME },
 | 
			
		||||
	{ "kSAV",  NULL, 0, KEYC_SSAVE },
 | 
			
		||||
	{ "kSPD",  NULL, 0, KEYC_SSUSPEND },
 | 
			
		||||
	{ "khts",  NULL, 0, KEYC_STAB },
 | 
			
		||||
	{ "kUND",  NULL, 0, KEYC_SUNDO },
 | 
			
		||||
	{ "kspd",  NULL, 0, KEYC_SUSPEND },
 | 
			
		||||
	{ "kund",  NULL, 0, KEYC_UNDO },
 | 
			
		||||
	{ "kcuu1", NULL, 0, KEYC_UP },
 | 
			
		||||
	{ "pmous", NULL, 0, KEYC_MOUSE },
 | 
			
		||||
	{ NULL,    NULL, 0, KEYC_NONE }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* tty file descriptor and local terminal buffers. */
 | 
			
		||||
int		 local_fd = -1;
 | 
			
		||||
int		 local_log = -1;
 | 
			
		||||
struct buffer	*local_in;
 | 
			
		||||
struct buffer	*local_out;
 | 
			
		||||
struct termios	 local_tio;
 | 
			
		||||
u_char		 local_attr;
 | 
			
		||||
u_char		 local_colr;
 | 
			
		||||
 | 
			
		||||
/* Initialise local terminal. */
 | 
			
		||||
int
 | 
			
		||||
local_init(struct buffer **in, struct buffer **out)
 | 
			
		||||
{
 | 
			
		||||
	char		       *tty, *path;
 | 
			
		||||
	const char	       *name;
 | 
			
		||||
	int		  	mode, error;
 | 
			
		||||
	struct termios	  	tio;
 | 
			
		||||
	struct local_key       *lk;
 | 
			
		||||
	u_int			i, j;
 | 
			
		||||
	static const char *const reqd[] = {
 | 
			
		||||
		"carriage_return",
 | 
			
		||||
		"change_scroll_region",
 | 
			
		||||
		"clear_screen",
 | 
			
		||||
		"clr_bol",
 | 
			
		||||
		"clr_eol",
 | 
			
		||||
		"cursor_address",
 | 
			
		||||
		"cursor_left",
 | 
			
		||||
		"cursor_down",
 | 
			
		||||
		"parm_dch",
 | 
			
		||||
		"parm_delete_line",
 | 
			
		||||
		"parm_down_cursor",
 | 
			
		||||
		"parm_ich",
 | 
			
		||||
		"parm_insert_line",
 | 
			
		||||
		"parm_left_cursor",
 | 
			
		||||
		"parm_right_cursor",
 | 
			
		||||
		"parm_up_cursor",
 | 
			
		||||
		"scroll_reverse",
 | 
			
		||||
		NULL
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	if ((tty = ttyname(STDIN_FILENO)) == NULL)
 | 
			
		||||
		fatal("ttyname failed");
 | 
			
		||||
	if ((local_fd = open(tty, O_RDWR)) == -1)
 | 
			
		||||
		fatal("open failed");
 | 
			
		||||
	if ((mode = fcntl(local_fd, F_GETFL)) == -1)
 | 
			
		||||
		fatal("fcntl failed");
 | 
			
		||||
	if (fcntl(local_fd, F_SETFL, mode|O_NONBLOCK) == -1)
 | 
			
		||||
		fatal("fcntl failed");
 | 
			
		||||
 | 
			
		||||
	if ((name = getenv("TERM")) == NULL || *name == '\0')
 | 
			
		||||
		name = "unknown";
 | 
			
		||||
	if (newterm(name, stdout, stdin) == NULL) {
 | 
			
		||||
		log_warnx("error opening terminal: %s", name);
 | 
			
		||||
		return (-1);
 | 
			
		||||
	}
 | 
			
		||||
	for (i = 0; reqd[i] != NULL; i++) {
 | 
			
		||||
		error = 0;
 | 
			
		||||
 | 
			
		||||
		for (j = 0; strfnames[j] != NULL; j++) {
 | 
			
		||||
			if (strcmp(strfnames[j], reqd[i]) == 0) {
 | 
			
		||||
				if (strcodes[j] == NULL)
 | 
			
		||||
					error = -1;
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (error != -1) {
 | 
			
		||||
			for (j = 0; numfnames[j] != NULL; j++) {
 | 
			
		||||
				if (strcmp(numfnames[j], reqd[i]) == 0) {
 | 
			
		||||
					if (numcodes[j] == NULL)
 | 
			
		||||
						error = -1;
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (error != -1) {
 | 
			
		||||
			for (j = 0; boolfnames[j] != NULL; j++) {
 | 
			
		||||
				if (strcmp(boolfnames[j], reqd[i]) == 0) {
 | 
			
		||||
					if (boolcodes[j] == NULL)
 | 
			
		||||
						error = -1;
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (error == -1) {
 | 
			
		||||
			log_warnx("required capability missing: %s", reqd[i]);
 | 
			
		||||
			return (-1);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	*in = local_in = buffer_create(BUFSIZ);
 | 
			
		||||
	*out = local_out = buffer_create(BUFSIZ);
 | 
			
		||||
 | 
			
		||||
	if (tcgetattr(local_fd, &local_tio) != 0)
 | 
			
		||||
		fatal("tcgetattr failed");
 | 
			
		||||
	memset(&tio, 0, sizeof tio);
 | 
			
		||||
	tio.c_iflag = TTYDEF_IFLAG & ~(IXON|IXOFF|ICRNL|INLCR);
 | 
			
		||||
	tio.c_oflag = TTYDEF_OFLAG & ~(OPOST|ONLCR|OCRNL|ONLRET);
 | 
			
		||||
	tio.c_lflag = 
 | 
			
		||||
	    TTYDEF_LFLAG & ~(IEXTEN|ICANON|ECHO|ECHOE|ECHOKE|ECHOCTL|ISIG);
 | 
			
		||||
	tio.c_cflag = TTYDEF_CFLAG;
 | 
			
		||||
	memcpy(&tio.c_cc, ttydefchars, sizeof tio.c_cc);
 | 
			
		||||
	cfsetspeed(&tio, TTYDEF_SPEED);
 | 
			
		||||
	if (tcsetattr(local_fd, TCSANOW, &tio) != 0)
 | 
			
		||||
		fatal("tcsetattr failed");
 | 
			
		||||
 | 
			
		||||
	if (enter_ca_mode != NULL)
 | 
			
		||||
		local_putp(enter_ca_mode);
 | 
			
		||||
	if (keypad_xmit != NULL)
 | 
			
		||||
		local_putp(keypad_xmit);
 | 
			
		||||
	if (ena_acs != NULL)
 | 
			
		||||
		local_putp(ena_acs);
 | 
			
		||||
	local_putp(clear_screen);
 | 
			
		||||
 | 
			
		||||
	for (lk = local_keys; lk->name != NULL; lk++) {
 | 
			
		||||
		lk->string = tigetstr(lk->name);
 | 
			
		||||
		if (lk->string == (char *) -1 || lk->string == (char *) 0)
 | 
			
		||||
			lk->string = NULL;
 | 
			
		||||
		else {
 | 
			
		||||
			lk->size = strlen(lk->string);
 | 
			
		||||
			log_debug("string for %s (%d): \"%s\", length %zu",
 | 
			
		||||
			    lk->name, lk->code, lk->string, lk->size);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	qsort(local_keys, sizeof local_keys /
 | 
			
		||||
	    sizeof local_keys[0], sizeof local_keys[0], local_cmp);
 | 
			
		||||
 | 
			
		||||
	local_attr = 0;
 | 
			
		||||
	local_colr = 0x88;
 | 
			
		||||
 | 
			
		||||
	if (debug_level > 2) {
 | 
			
		||||
		xasprintf(
 | 
			
		||||
		    &path, "%s-output-%ld.log", __progname,(long) getpid());
 | 
			
		||||
		local_log = open(
 | 
			
		||||
		    path, O_RDWR|O_APPEND|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR);
 | 
			
		||||
		xfree(path);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return (local_fd);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Compare keys. */
 | 
			
		||||
int
 | 
			
		||||
local_cmp(const void *ptr1, const void *ptr2)
 | 
			
		||||
{
 | 
			
		||||
	const struct local_key *lk1 = ptr1, *lk2 = ptr2;
 | 
			
		||||
 | 
			
		||||
	if (lk1->string == NULL && lk2->string == NULL)
 | 
			
		||||
		return (0);
 | 
			
		||||
	if (lk1->string == NULL)
 | 
			
		||||
		return (1);
 | 
			
		||||
	if (lk2->string == NULL)
 | 
			
		||||
		return (-1);
 | 
			
		||||
	return (lk2->size - lk1->size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Tidy up and reset local terminal. */
 | 
			
		||||
void
 | 
			
		||||
local_done(void)
 | 
			
		||||
{
 | 
			
		||||
	struct winsize	ws;
 | 
			
		||||
 | 
			
		||||
	buffer_destroy(local_in);
 | 
			
		||||
	buffer_destroy(local_out);
 | 
			
		||||
 | 
			
		||||
	if (tcsetattr(local_fd, TCSANOW, &local_tio) != 0)
 | 
			
		||||
		fatal("tcsetattr failed");
 | 
			
		||||
	close(local_fd);
 | 
			
		||||
 | 
			
		||||
	if (local_log != -1)
 | 
			
		||||
		close(local_log);
 | 
			
		||||
	
 | 
			
		||||
	if (change_scroll_region != NULL) {
 | 
			
		||||
		if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) == -1)
 | 
			
		||||
			fatal("ioctl(TIOCGWINSZ)");
 | 
			
		||||
		putp(tparm(change_scroll_region, 0, ws.ws_row - 1));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	endwin();
 | 
			
		||||
	if (keypad_local != NULL)
 | 
			
		||||
		putp(keypad_local);	/* not local_putp */
 | 
			
		||||
	if (exit_ca_mode != NULL)
 | 
			
		||||
		putp(exit_ca_mode);
 | 
			
		||||
	putp(clear_screen);
 | 
			
		||||
	if (cursor_normal != NULL)
 | 
			
		||||
		putp(cursor_normal);
 | 
			
		||||
	if (exit_attribute_mode != NULL)
 | 
			
		||||
		putp(exit_attribute_mode);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Put a character. Used as parameter to tputs. */
 | 
			
		||||
int
 | 
			
		||||
local_putc(int c)
 | 
			
		||||
{
 | 
			
		||||
	u_char	ch = c;
 | 
			
		||||
 | 
			
		||||
	if (c < 0 || c > (int) UCHAR_MAX)
 | 
			
		||||
		fatalx("invalid character");
 | 
			
		||||
 | 
			
		||||
	if (local_log != -1)
 | 
			
		||||
		write(local_log, &ch, 1);
 | 
			
		||||
	if (acs_chars != NULL && local_attr & ATTR_DRAWING) {
 | 
			
		||||
		ch = local_translate_acs(ch);
 | 
			
		||||
		if (ch == '\0')
 | 
			
		||||
			ch = '?';
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	buffer_write(local_out, &ch, 1);
 | 
			
		||||
	return (c);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Put terminfo string. */
 | 
			
		||||
void
 | 
			
		||||
local_putp(const char *s)
 | 
			
		||||
{
 | 
			
		||||
	if (s == NULL)
 | 
			
		||||
		fatalx("null pointer");
 | 
			
		||||
 | 
			
		||||
	tputs(s, 1, local_putc);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Return waiting keys if any. */
 | 
			
		||||
int
 | 
			
		||||
local_key(void)
 | 
			
		||||
{
 | 
			
		||||
	struct local_key	*lk;
 | 
			
		||||
	u_int			 i;
 | 
			
		||||
	size_t			 size;
 | 
			
		||||
 | 
			
		||||
	size = BUFFER_USED(local_in);
 | 
			
		||||
	if (size == 0)
 | 
			
		||||
		return (KEYC_NONE);
 | 
			
		||||
 | 
			
		||||
	i = 0;
 | 
			
		||||
	lk = local_keys;
 | 
			
		||||
	while (lk->string != NULL) {
 | 
			
		||||
		if (strncmp(BUFFER_OUT(local_in), lk->string, size) == 0) {
 | 
			
		||||
			if (size < lk->size)
 | 
			
		||||
				return (KEYC_NONE);
 | 
			
		||||
			log_debug("got key: "
 | 
			
		||||
			    "%s %d \"%s\"", lk->name, lk->code, lk->string);
 | 
			
		||||
			buffer_remove(local_in, lk->size);
 | 
			
		||||
			return (lk->code);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		i++;
 | 
			
		||||
		lk = local_keys + i;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return (input_extract8(local_in));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Display output data. */
 | 
			
		||||
void
 | 
			
		||||
local_output(struct buffer *b, size_t size)
 | 
			
		||||
{
 | 
			
		||||
	u_char		 ch;
 | 
			
		||||
	uint16_t	 ua, ub;
 | 
			
		||||
 | 
			
		||||
	while (size != 0) {
 | 
			
		||||
		if (size < 1)
 | 
			
		||||
			break;
 | 
			
		||||
		size--;
 | 
			
		||||
		ch = input_extract8(b);
 | 
			
		||||
		if (ch != '\e') {
 | 
			
		||||
			switch (ch) {
 | 
			
		||||
			case '\n':	/* LF */
 | 
			
		||||
				local_putp(cursor_down);
 | 
			
		||||
				break;
 | 
			
		||||
			case '\r':	/* CR */
 | 
			
		||||
				local_putp(carriage_return);
 | 
			
		||||
				break;
 | 
			
		||||
			case '\007':	/* BEL */
 | 
			
		||||
				if (bell != NULL)
 | 
			
		||||
					local_putp(bell);
 | 
			
		||||
				break;
 | 
			
		||||
			case '\010':	/* BS */
 | 
			
		||||
				local_putp(cursor_left);
 | 
			
		||||
				break;
 | 
			
		||||
			default:
 | 
			
		||||
				local_putc(ch);
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (size < 1)
 | 
			
		||||
			fatalx("underflow");
 | 
			
		||||
		size--;
 | 
			
		||||
		ch = input_extract8(b);
 | 
			
		||||
 | 
			
		||||
		log_debug("received code %hhu", ch);
 | 
			
		||||
		switch (ch) {
 | 
			
		||||
		case CODE_CURSORUP:
 | 
			
		||||
			if (size < 2)
 | 
			
		||||
				fatalx("CODE_CURSORUP underflow");
 | 
			
		||||
			size -= 2;
 | 
			
		||||
			ua = input_extract16(b);
 | 
			
		||||
			local_putp(tparm(parm_up_cursor, ua));
 | 
			
		||||
			break;
 | 
			
		||||
		case CODE_CURSORDOWN:
 | 
			
		||||
			if (size < 2)
 | 
			
		||||
				fatalx("CODE_CURSORDOWN underflow");
 | 
			
		||||
			size -= 2;
 | 
			
		||||
			ua = input_extract16(b);
 | 
			
		||||
			local_putp(tparm(parm_down_cursor, ua));
 | 
			
		||||
			break;
 | 
			
		||||
		case CODE_CURSORRIGHT:
 | 
			
		||||
			if (size < 2)
 | 
			
		||||
				fatalx("CODE_CURSORRIGHT underflow");
 | 
			
		||||
			size -= 2;
 | 
			
		||||
			ua = input_extract16(b);
 | 
			
		||||
			local_putp(tparm(parm_right_cursor, ua));
 | 
			
		||||
			break;
 | 
			
		||||
		case CODE_CURSORLEFT:
 | 
			
		||||
			if (size < 2)
 | 
			
		||||
				fatalx("CODE_CURSORLEFT underflow");
 | 
			
		||||
			size -= 2;
 | 
			
		||||
			ua = input_extract16(b);
 | 
			
		||||
			local_putp(tparm(parm_left_cursor, ua));
 | 
			
		||||
			break;
 | 
			
		||||
		case CODE_CURSORMOVE:
 | 
			
		||||
			if (size < 4)
 | 
			
		||||
				fatalx("CODE_CURSORMOVE underflow");
 | 
			
		||||
			size -= 4;
 | 
			
		||||
			ua = input_extract16(b);
 | 
			
		||||
			ub = input_extract16(b);
 | 
			
		||||
			local_putp(tparm(cursor_address, ua - 1, ub - 1));
 | 
			
		||||
			break;
 | 
			
		||||
		case CODE_CLEARENDOFLINE:
 | 
			
		||||
			local_putp(clr_eol);
 | 
			
		||||
			break;
 | 
			
		||||
		case CODE_CLEARSTARTOFLINE:
 | 
			
		||||
			local_putp(clr_bol);
 | 
			
		||||
			break;
 | 
			
		||||
		case CODE_CLEARLINE:
 | 
			
		||||
			local_putp(clr_eol);	/* XXX */
 | 
			
		||||
			break;
 | 
			
		||||
		case CODE_INSERTLINE:
 | 
			
		||||
			if (size < 2)
 | 
			
		||||
				fatalx("CODE_INSERTLINE underflow");
 | 
			
		||||
			size -= 2;
 | 
			
		||||
			ua = input_extract16(b);
 | 
			
		||||
			local_putp(tparm(parm_insert_line, ua));
 | 
			
		||||
			break;
 | 
			
		||||
		case CODE_DELETELINE:
 | 
			
		||||
			if (size < 2)
 | 
			
		||||
				fatalx("CODE_DELETELINE underflow");
 | 
			
		||||
			size -= 2;
 | 
			
		||||
			ua = input_extract16(b);
 | 
			
		||||
			local_putp(tparm(parm_delete_line, ua));
 | 
			
		||||
			break;
 | 
			
		||||
		case CODE_INSERTCHARACTER:
 | 
			
		||||
			if (size < 2)
 | 
			
		||||
				fatalx("CODE_INSERTCHARACTER underflow");
 | 
			
		||||
			size -= 2;
 | 
			
		||||
			ua = input_extract16(b);
 | 
			
		||||
			local_putp(tparm(parm_ich, ua));
 | 
			
		||||
			break;
 | 
			
		||||
		case CODE_DELETECHARACTER:
 | 
			
		||||
			if (size < 2)
 | 
			
		||||
				fatalx("CODE_DELETECHARACTER underflow");
 | 
			
		||||
			size -= 2;
 | 
			
		||||
			ua = input_extract16(b);
 | 
			
		||||
			local_putp(tparm(parm_dch, ua));
 | 
			
		||||
			break;
 | 
			
		||||
		case CODE_CURSORON:
 | 
			
		||||
			if (cursor_normal != NULL)
 | 
			
		||||
				local_putp(cursor_normal);
 | 
			
		||||
			break;
 | 
			
		||||
		case CODE_CURSOROFF:
 | 
			
		||||
			if (cursor_invisible != NULL)
 | 
			
		||||
				local_putp(cursor_invisible);
 | 
			
		||||
			break;
 | 
			
		||||
		case CODE_REVERSEINDEX:
 | 
			
		||||
			local_putp(scroll_reverse);
 | 
			
		||||
			break;
 | 
			
		||||
		case CODE_SCROLLREGION:
 | 
			
		||||
			if (size < 4)
 | 
			
		||||
				fatalx("CODE_SCROLLREGION underflow");
 | 
			
		||||
			size -= 4;
 | 
			
		||||
			ua = input_extract16(b);
 | 
			
		||||
			ub = input_extract16(b);
 | 
			
		||||
			local_putp(tparm(change_scroll_region, ua - 1, ub - 1));
 | 
			
		||||
			break;
 | 
			
		||||
		case CODE_INSERTON:
 | 
			
		||||
			if (enter_insert_mode != NULL)
 | 
			
		||||
				local_putp(enter_insert_mode);
 | 
			
		||||
			break;
 | 
			
		||||
		case CODE_INSERTOFF:
 | 
			
		||||
			if (exit_insert_mode != NULL)
 | 
			
		||||
				local_putp(exit_insert_mode);
 | 
			
		||||
			break;
 | 
			
		||||
		case CODE_KCURSOROFF:
 | 
			
		||||
			/*
 | 
			
		||||
			t = tigetstr("CE");
 | 
			
		||||
			if (t != (char *) 0 && t != (char *) -1)
 | 
			
		||||
				local_putp(t);
 | 
			
		||||
			*/
 | 
			
		||||
			break;
 | 
			
		||||
		case CODE_KCURSORON:
 | 
			
		||||
			/*
 | 
			
		||||
			t = tigetstr("CS");
 | 
			
		||||
			if (t != (char *) 0 && t != (char *) -1)
 | 
			
		||||
				local_putp(t);
 | 
			
		||||
			*/
 | 
			
		||||
			break;
 | 
			
		||||
		case CODE_KKEYPADOFF:
 | 
			
		||||
			/*
 | 
			
		||||
			  if (keypad_local != NULL)
 | 
			
		||||
			  local_putp(keypad_local);
 | 
			
		||||
			*/
 | 
			
		||||
			break;
 | 
			
		||||
		case CODE_KKEYPADON:
 | 
			
		||||
			/*
 | 
			
		||||
			  if (keypad_xmit != NULL)
 | 
			
		||||
			  local_putp(keypad_xmit);
 | 
			
		||||
			*/
 | 
			
		||||
			break;
 | 
			
		||||
		case CODE_TITLE:
 | 
			
		||||
			if (size < 2)
 | 
			
		||||
				fatalx("CODE_TITLE underflow");
 | 
			
		||||
			size -= 2;
 | 
			
		||||
			ua = input_extract16(b);
 | 
			
		||||
 | 
			
		||||
			if (size < ua)
 | 
			
		||||
				fatalx("CODE_TITLE underflow");
 | 
			
		||||
			size -= ua;
 | 
			
		||||
			buffer_remove(b, ua);
 | 
			
		||||
			break;
 | 
			
		||||
		case CODE_ATTRIBUTES:
 | 
			
		||||
			if (size < 4)
 | 
			
		||||
				fatalx("CODE_ATTRIBUTES underflow");
 | 
			
		||||
			size -= 4;
 | 
			
		||||
			ua = input_extract16(b);
 | 
			
		||||
			ub = input_extract16(b);
 | 
			
		||||
 | 
			
		||||
			local_attributes(ua, ub);
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
local_attributes(u_char attr, u_char colr)
 | 
			
		||||
{
 | 
			
		||||
	u_char	fg, bg;
 | 
			
		||||
 | 
			
		||||
	if (attr == local_attr && colr == local_colr)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	/* If any bits are being cleared, reset everything. */
 | 
			
		||||
	if (local_attr & ~attr) {
 | 
			
		||||
		if ((local_attr & ATTR_DRAWING) &&
 | 
			
		||||
		    exit_alt_charset_mode != NULL)
 | 
			
		||||
			local_putp(exit_alt_charset_mode);
 | 
			
		||||
		local_putp(exit_attribute_mode);
 | 
			
		||||
		local_colr = 0x88;
 | 
			
		||||
		local_attr = 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Filter out bits already set. */
 | 
			
		||||
	attr &= ~local_attr;
 | 
			
		||||
	local_attr |= attr;
 | 
			
		||||
 | 
			
		||||
	if ((attr & ATTR_BRIGHT) && enter_bold_mode != NULL)
 | 
			
		||||
		local_putp(enter_bold_mode);
 | 
			
		||||
	if ((attr & ATTR_DIM) && enter_dim_mode != NULL)
 | 
			
		||||
		local_putp(enter_dim_mode);
 | 
			
		||||
	if ((attr & ATTR_ITALICS) && enter_standout_mode != NULL)
 | 
			
		||||
		local_putp(enter_standout_mode);
 | 
			
		||||
	if ((attr & ATTR_UNDERSCORE) && enter_underline_mode != NULL)
 | 
			
		||||
		local_putp(enter_underline_mode);
 | 
			
		||||
	if ((attr & ATTR_BLINK) && enter_blink_mode != NULL)
 | 
			
		||||
		local_putp(enter_blink_mode);
 | 
			
		||||
	if ((attr & ATTR_REVERSE) && enter_reverse_mode != NULL)
 | 
			
		||||
		local_putp(enter_reverse_mode);
 | 
			
		||||
	if ((attr & ATTR_HIDDEN) && enter_secure_mode != NULL)
 | 
			
		||||
		local_putp(enter_secure_mode);
 | 
			
		||||
	if ((attr & ATTR_DRAWING) && enter_alt_charset_mode != NULL)
 | 
			
		||||
		local_putp(enter_alt_charset_mode);
 | 
			
		||||
 | 
			
		||||
	fg = (colr >> 4) & 0xf;
 | 
			
		||||
	if (fg != ((local_colr >> 4) & 0xf)) {
 | 
			
		||||
		if (tigetflag("AX") == TRUE) {
 | 
			
		||||
			if (fg == 7)
 | 
			
		||||
				fg = 8;
 | 
			
		||||
		} else {
 | 
			
		||||
			if (fg == 8)
 | 
			
		||||
				fg = 7;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		if (fg == 8)
 | 
			
		||||
			local_putp("\e[39m");
 | 
			
		||||
		else if (set_a_foreground != NULL)
 | 
			
		||||
			local_putp(tparm(set_a_foreground, fg));
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	bg = colr & 0xf;
 | 
			
		||||
	if (bg != (local_colr & 0xf)) {
 | 
			
		||||
		if (tigetflag("AX") == TRUE) {
 | 
			
		||||
			if (bg == 0)
 | 
			
		||||
				bg = 8;
 | 
			
		||||
		} else {
 | 
			
		||||
			if (bg == 8)
 | 
			
		||||
				bg = 0;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (bg == 8)
 | 
			
		||||
			local_putp("\e[49m");
 | 
			
		||||
		else if (set_a_background != NULL)
 | 
			
		||||
			local_putp(tparm(set_a_background, bg));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	local_colr = colr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
u_char
 | 
			
		||||
local_translate_acs(u_char ch)
 | 
			
		||||
{
 | 
			
		||||
	switch (ch) {
 | 
			
		||||
	case '~':
 | 
			
		||||
		return (ACS_BULLET);
 | 
			
		||||
	case '}':
 | 
			
		||||
		return (ACS_STERLING);
 | 
			
		||||
	case '|':
 | 
			
		||||
		return (ACS_NEQUAL);
 | 
			
		||||
	case '{':
 | 
			
		||||
		return (ACS_PI);
 | 
			
		||||
	case 'z':
 | 
			
		||||
		return (ACS_GEQUAL);
 | 
			
		||||
	case 'y':
 | 
			
		||||
		return (ACS_LEQUAL);
 | 
			
		||||
	case 'x':
 | 
			
		||||
		return (ACS_VLINE);
 | 
			
		||||
	case 'w':
 | 
			
		||||
		return (ACS_TTEE);
 | 
			
		||||
	case 'v':
 | 
			
		||||
		return (ACS_BTEE);
 | 
			
		||||
	case 'u':
 | 
			
		||||
		return (ACS_RTEE);
 | 
			
		||||
	case 't':
 | 
			
		||||
		return (ACS_LTEE);
 | 
			
		||||
	case 's':
 | 
			
		||||
		return (ACS_S9);
 | 
			
		||||
	case 'r':
 | 
			
		||||
		return (ACS_S7);
 | 
			
		||||
	case 'q':
 | 
			
		||||
		return (ACS_HLINE);
 | 
			
		||||
	case 'p':
 | 
			
		||||
		return (ACS_S3);
 | 
			
		||||
	case 'o':
 | 
			
		||||
		return (ACS_S1);
 | 
			
		||||
	case 'n':
 | 
			
		||||
		return (ACS_PLUS);
 | 
			
		||||
	case 'm':
 | 
			
		||||
		return (ACS_LLCORNER);
 | 
			
		||||
	case 'l':
 | 
			
		||||
		return (ACS_ULCORNER);
 | 
			
		||||
	case 'k':
 | 
			
		||||
		return (ACS_URCORNER);
 | 
			
		||||
	case 'j':
 | 
			
		||||
		return (ACS_LRCORNER);
 | 
			
		||||
	case 'i':
 | 
			
		||||
		return (ACS_LANTERN);
 | 
			
		||||
	case 'h':
 | 
			
		||||
		return (ACS_BOARD);
 | 
			
		||||
	case 'g':
 | 
			
		||||
		return (ACS_PLMINUS);
 | 
			
		||||
	case 'f':
 | 
			
		||||
		return (ACS_DEGREE);
 | 
			
		||||
	case 'a':
 | 
			
		||||
		return (ACS_CKBOARD);
 | 
			
		||||
	case '`':
 | 
			
		||||
		return (ACS_DIAMOND);
 | 
			
		||||
	case '0':
 | 
			
		||||
		return (ACS_BLOCK);
 | 
			
		||||
	case '.':
 | 
			
		||||
		return (ACS_DARROW);
 | 
			
		||||
	case '-':
 | 
			
		||||
		return (ACS_UARROW);
 | 
			
		||||
	case ',':
 | 
			
		||||
		return (ACS_LARROW);
 | 
			
		||||
	case '+':
 | 
			
		||||
		return (ACS_RARROW);
 | 
			
		||||
	}
 | 
			
		||||
	return (ch);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										6
									
								
								resize.c
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								resize.c
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: resize.c,v 1.6 2007-11-21 13:11:41 nicm Exp $ */
 | 
			
		||||
/* $Id: resize.c,v 1.7 2007-11-27 19:23:33 nicm Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -117,8 +117,8 @@ recalculate_sizes(void)
 | 
			
		||||
		log_debug("window size %u,%u (was %u,%u)", ssx, ssy,
 | 
			
		||||
		    screen_size_x(&w->screen), screen_size_y(&w->screen));
 | 
			
		||||
 | 
			
		||||
		server_clear_window_cur(w);
 | 
			
		||||
		window_resize(w, ssx, ssy);
 | 
			
		||||
		server_redraw_window_cur(w);
 | 
			
		||||
		server_clear_window(w);
 | 
			
		||||
		server_redraw_window(w);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										153
									
								
								screen.c
									
									
									
									
									
								
							
							
						
						
									
										153
									
								
								screen.c
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: screen.c,v 1.49 2007-11-26 22:06:11 nicm Exp $ */
 | 
			
		||||
/* $Id: screen.c,v 1.50 2007-11-27 19:23:34 nicm Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -267,13 +267,45 @@ screen_destroy(struct screen *s)
 | 
			
		||||
	xfree(s->grid_size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Initialise redrawing a window. */
 | 
			
		||||
void
 | 
			
		||||
screen_draw_start_window(
 | 
			
		||||
    struct screen_draw_ctx *ctx, struct window *w, u_int ox, u_int oy)
 | 
			
		||||
{
 | 
			
		||||
	struct screen	*t = &w->screen;
 | 
			
		||||
 | 
			
		||||
	screen_draw_start(ctx, t, tty_write_window, w, ox, oy);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Initialise redrawing a client. */
 | 
			
		||||
void
 | 
			
		||||
screen_draw_start_client(
 | 
			
		||||
    struct screen_draw_ctx *ctx, struct client *c, u_int ox, u_int oy)
 | 
			
		||||
{
 | 
			
		||||
	struct screen	*t = &c->session->curw->window->screen;
 | 
			
		||||
 | 
			
		||||
	screen_draw_start(ctx, t, tty_write_client, c, ox, oy);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Initialise redrawing a session. */
 | 
			
		||||
void
 | 
			
		||||
screen_draw_start_session(
 | 
			
		||||
    struct screen_draw_ctx *ctx, struct session *s, u_int ox, u_int oy)
 | 
			
		||||
{
 | 
			
		||||
	struct screen	*t = &s->curw->window->screen;
 | 
			
		||||
 | 
			
		||||
	screen_draw_start(ctx, t, tty_write_session, s, ox, oy);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Initialise drawing. */
 | 
			
		||||
void
 | 
			
		||||
screen_draw_start(struct screen_draw_ctx *ctx,
 | 
			
		||||
    struct screen *s, struct buffer *b, u_int ox, u_int oy)
 | 
			
		||||
screen_draw_start(struct screen_draw_ctx *ctx, struct screen *s,
 | 
			
		||||
    void (*write)(void *, int, ...), void *data, u_int ox, u_int oy)
 | 
			
		||||
{
 | 
			
		||||
	ctx->write = write;
 | 
			
		||||
	ctx->data = data;
 | 
			
		||||
 | 
			
		||||
	ctx->s = s;
 | 
			
		||||
	ctx->b = b;
 | 
			
		||||
 | 
			
		||||
	ctx->ox = ox;
 | 
			
		||||
	ctx->oy = oy;
 | 
			
		||||
@@ -287,8 +319,8 @@ screen_draw_start(struct screen_draw_ctx *ctx,
 | 
			
		||||
	ctx->attr = s->attr;
 | 
			
		||||
	ctx->colr = s->colr;
 | 
			
		||||
 | 
			
		||||
	input_store_two(b, CODE_SCROLLREGION, 1, screen_size_y(s));
 | 
			
		||||
	input_store_zero(b, CODE_CURSOROFF);
 | 
			
		||||
	ctx->write(ctx->data, TTY_SCROLLREGION, 0, screen_last_y(s));
 | 
			
		||||
	ctx->write(ctx->data, TTY_CURSOROFF);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Set selection. */
 | 
			
		||||
@@ -356,44 +388,112 @@ void
 | 
			
		||||
screen_draw_stop(struct screen_draw_ctx *ctx)
 | 
			
		||||
{
 | 
			
		||||
	struct screen	*s = ctx->s;
 | 
			
		||||
	struct buffer	*b = ctx->b;
 | 
			
		||||
 | 
			
		||||
	input_store_two(b, CODE_SCROLLREGION, s->rupper + 1, s->rlower + 1);
 | 
			
		||||
	ctx->write(ctx->data, TTY_SCROLLREGION, s->rupper, s->rlower);
 | 
			
		||||
 | 
			
		||||
	if (ctx->cx != s->cx || ctx->cy != s->cy)
 | 
			
		||||
		input_store_two(b, CODE_CURSORMOVE, s->cy + 1, s->cx + 1);
 | 
			
		||||
		ctx->write(ctx->data, TTY_CURSORMOVE, s->cy, s->cx);
 | 
			
		||||
 | 
			
		||||
	if (ctx->attr != s->attr || ctx->colr != s->colr)
 | 
			
		||||
		input_store_two(b, CODE_ATTRIBUTES, s->attr, s->colr);
 | 
			
		||||
		ctx->write(ctx->data, TTY_ATTRIBUTES, s->attr, s->colr);
 | 
			
		||||
 | 
			
		||||
	if (s->mode & MODE_BACKGROUND) {
 | 
			
		||||
		if (s->mode & MODE_BGCURSOR)
 | 
			
		||||
			input_store_zero(b, CODE_CURSORON);
 | 
			
		||||
			ctx->write(ctx->data, TTY_CURSORON);
 | 
			
		||||
	} else {
 | 
			
		||||
		if (s->mode & MODE_CURSOR)
 | 
			
		||||
			input_store_zero(b, CODE_CURSORON);
 | 
			
		||||
			ctx->write(ctx->data, TTY_CURSORON);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Insert lines. */
 | 
			
		||||
void
 | 
			
		||||
screen_draw_insert_lines(struct screen_draw_ctx *ctx, u_int ny)
 | 
			
		||||
{
 | 
			
		||||
	ctx->write(ctx->data, TTY_INSERTLINE, ny);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Delete lines. */
 | 
			
		||||
void
 | 
			
		||||
screen_draw_delete_lines(struct screen_draw_ctx *ctx, u_int ny)
 | 
			
		||||
{
 | 
			
		||||
	ctx->write(ctx->data, TTY_DELETELINE, ny);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Insert characters. */
 | 
			
		||||
void
 | 
			
		||||
screen_draw_insert_characters(struct screen_draw_ctx *ctx, u_int nx)
 | 
			
		||||
{
 | 
			
		||||
	ctx->write(ctx->data, TTY_INSERTCHARACTER, nx);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Delete characters. */
 | 
			
		||||
void
 | 
			
		||||
screen_draw_delete_characters(struct screen_draw_ctx *ctx, u_int nx)
 | 
			
		||||
{
 | 
			
		||||
	ctx->write(ctx->data, TTY_DELETECHARACTER, nx);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Clear end of line. */
 | 
			
		||||
void
 | 
			
		||||
screen_draw_clear_line_to(struct screen_draw_ctx *ctx, u_int px)
 | 
			
		||||
{
 | 
			
		||||
	while (ctx->cx <= px) {
 | 
			
		||||
		ctx->write(ctx->data, TTY_CHARACTER, SCREEN_DEFDATA);
 | 
			
		||||
		ctx->cx++;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Clear screen. */
 | 
			
		||||
void
 | 
			
		||||
screen_draw_clear_screen(struct screen_draw_ctx *ctx)
 | 
			
		||||
{
 | 
			
		||||
	u_int	i;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < screen_size_y(ctx->s); i++) {
 | 
			
		||||
		screen_draw_move_cursor(ctx, 0, i);
 | 
			
		||||
		screen_draw_clear_line_to(ctx, screen_size_x(ctx->s));
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Write string. */
 | 
			
		||||
void printflike2
 | 
			
		||||
screen_draw_write_string(struct screen_draw_ctx *ctx, const char *fmt, ...)
 | 
			
		||||
{
 | 
			
		||||
	struct screen	*s = ctx->s;
 | 
			
		||||
	va_list		 ap;
 | 
			
		||||
	char   		*msg, *ptr;
 | 
			
		||||
 | 
			
		||||
	va_start(ap, fmt);
 | 
			
		||||
	xvasprintf(&msg, fmt, ap);
 | 
			
		||||
	va_end(ap);
 | 
			
		||||
 | 
			
		||||
	for (ptr = msg; *ptr != '\0'; ptr++) {
 | 
			
		||||
		if (ctx->cx > screen_last_x(s))
 | 
			
		||||
			break;
 | 
			
		||||
		ctx->write(ctx->data, TTY_CHARACTER, *ptr);
 | 
			
		||||
		ctx->cx++;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	xfree(msg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Move cursor. */
 | 
			
		||||
void
 | 
			
		||||
screen_draw_move(struct screen_draw_ctx *ctx, u_int px, u_int py)
 | 
			
		||||
screen_draw_move_cursor(struct screen_draw_ctx *ctx, u_int px, u_int py)
 | 
			
		||||
{
 | 
			
		||||
	if (px == ctx->cx && py == ctx->cy)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	/* XXX disabled while things outside can move the cursor (eg
 | 
			
		||||
	   window-more.c writes characters)
 | 
			
		||||
	if (px == 0 && py == ctx->cy)
 | 
			
		||||
		input_store8(ctx->b, '\r');
 | 
			
		||||
		ctx->write(ctx->data, TTY_CHARACTER, '\r');
 | 
			
		||||
	else if (px == ctx->cx && py == ctx->cy + 1)
 | 
			
		||||
		input_store8(ctx->b, '\n');
 | 
			
		||||
		ctx->write(ctx->data, TTY_CHARACTER, '\n');
 | 
			
		||||
	else if (px == 0 && py == ctx->cy + 1) {
 | 
			
		||||
		input_store8(ctx->b, '\r');
 | 
			
		||||
		input_store8(ctx->b, '\n');
 | 
			
		||||
		ctx->write(ctx->data, TTY_CHARACTER, '\r');
 | 
			
		||||
		ctx->write(ctx->data, TTY_CHARACTER, '\n');
 | 
			
		||||
	} else
 | 
			
		||||
	*/
 | 
			
		||||
	input_store_two(ctx->b, CODE_CURSORMOVE, py + 1, px + 1);
 | 
			
		||||
		ctx->write(ctx->data, TTY_CURSORMOVE, py, px);
 | 
			
		||||
 | 
			
		||||
	ctx->cx = px;
 | 
			
		||||
	ctx->cy = py;
 | 
			
		||||
@@ -405,7 +505,7 @@ screen_draw_set_attributes(
 | 
			
		||||
    struct screen_draw_ctx *ctx, u_char attr, u_char colr)
 | 
			
		||||
{
 | 
			
		||||
	if (attr != ctx->attr || colr != ctx->colr) {
 | 
			
		||||
		input_store_two(ctx->b, CODE_ATTRIBUTES, attr, colr);
 | 
			
		||||
		ctx->write(ctx->data, TTY_ATTRIBUTES, attr, colr);
 | 
			
		||||
		ctx->attr = attr;
 | 
			
		||||
		ctx->colr = colr;
 | 
			
		||||
	}
 | 
			
		||||
@@ -415,14 +515,13 @@ screen_draw_set_attributes(
 | 
			
		||||
void
 | 
			
		||||
screen_draw_cell(struct screen_draw_ctx *ctx, u_int px, u_int py)
 | 
			
		||||
{
 | 
			
		||||
	struct buffer	*b = ctx->b;
 | 
			
		||||
	u_char	 data, attr, colr;
 | 
			
		||||
 | 
			
		||||
	screen_draw_move(ctx, px, py);
 | 
			
		||||
	screen_draw_move_cursor(ctx, px, py);
 | 
			
		||||
 | 
			
		||||
	screen_draw_get_cell(ctx, px, py, &data, &attr, &colr);
 | 
			
		||||
	screen_draw_set_attributes(ctx, attr, colr);
 | 
			
		||||
	input_store8(b, data);
 | 
			
		||||
	ctx->write(ctx->data, TTY_CHARACTER, data);
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Don't try to wrap as it will cause problems when screen is smaller
 | 
			
		||||
@@ -465,8 +564,8 @@ screen_draw_line(struct screen_draw_ctx *ctx, u_int py)
 | 
			
		||||
               screen_draw_cells(ctx, 0, py, screen_size_x(ctx->s));
 | 
			
		||||
       else {
 | 
			
		||||
               screen_draw_cells(ctx, 0, py, cx);
 | 
			
		||||
               screen_draw_move(ctx, cx, py);
 | 
			
		||||
               input_store_zero(ctx->b, CODE_CLEARENDOFLINE);
 | 
			
		||||
               screen_draw_move_cursor(ctx, cx, py);
 | 
			
		||||
               ctx->write(ctx->data, TTY_CLEARENDOFLINE);
 | 
			
		||||
       }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										276
									
								
								server-fn.c
									
									
									
									
									
								
							
							
						
						
									
										276
									
								
								server-fn.c
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: server-fn.c,v 1.34 2007-11-24 18:32:52 nicm Exp $ */
 | 
			
		||||
/* $Id: server-fn.c,v 1.35 2007-11-27 19:23:34 nicm Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -105,7 +105,7 @@ server_write_session(
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
server_write_window_cur(
 | 
			
		||||
server_write_window(
 | 
			
		||||
    struct window *w, enum hdrtype type, const void *buf, size_t len)
 | 
			
		||||
{
 | 
			
		||||
	struct client	*c;
 | 
			
		||||
@@ -120,262 +120,144 @@ server_write_window_cur(
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
server_write_window_all(
 | 
			
		||||
    struct window *w, enum hdrtype type, const void *buf, size_t len)
 | 
			
		||||
{
 | 
			
		||||
	struct client	*c;
 | 
			
		||||
	u_int		 i;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
 | 
			
		||||
		c = ARRAY_ITEM(&clients, i);
 | 
			
		||||
		if (c == NULL || c->session == NULL)
 | 
			
		||||
			continue;
 | 
			
		||||
		if (session_has(c->session, w))
 | 
			
		||||
			server_write_client(c, type, buf, len);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
server_status_client(struct client *c)
 | 
			
		||||
{
 | 
			
		||||
	struct hdr	hdr;
 | 
			
		||||
	size_t		size;
 | 
			
		||||
 | 
			
		||||
	if (status_lines == 0 || c->sy <= status_lines)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	buffer_ensure(c->out, sizeof hdr);
 | 
			
		||||
	buffer_add(c->out, sizeof hdr);
 | 
			
		||||
	size = BUFFER_USED(c->out);
 | 
			
		||||
 | 
			
		||||
	status_write(c);
 | 
			
		||||
 | 
			
		||||
	size = BUFFER_USED(c->out) - size;
 | 
			
		||||
	hdr.type = MSG_DATA;
 | 
			
		||||
	hdr.size = size;
 | 
			
		||||
	memcpy(BUFFER_IN(c->out) - size - sizeof hdr, &hdr, sizeof hdr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
server_clear_client(struct client *c)
 | 
			
		||||
{
 | 
			
		||||
	struct screen	*s = &c->session->curw->window->screen;
 | 
			
		||||
	struct hdr	 hdr;
 | 
			
		||||
	size_t		 size;
 | 
			
		||||
	u_int		 i;
 | 
			
		||||
	struct screen_draw_ctx	ctx;
 | 
			
		||||
 | 
			
		||||
	buffer_ensure(c->out, sizeof hdr);
 | 
			
		||||
	buffer_add(c->out, sizeof hdr);
 | 
			
		||||
	size = BUFFER_USED(c->out);
 | 
			
		||||
	screen_draw_start_client(&ctx, c, 0, 0);
 | 
			
		||||
	screen_draw_clear_screen(&ctx);
 | 
			
		||||
	screen_draw_stop(&ctx);
 | 
			
		||||
 | 
			
		||||
	input_store_zero(c->out, CODE_CURSOROFF);
 | 
			
		||||
	for (i = 0; i < screen_size_y(s); i++) {
 | 
			
		||||
		input_store_two(c->out, CODE_CURSORMOVE, i + 1, 1);
 | 
			
		||||
		input_store_zero(c->out, CODE_CLEARLINE);
 | 
			
		||||
	}
 | 
			
		||||
	input_store_two(c->out, CODE_CURSORMOVE, s->cy + 1, s->cx + 1);
 | 
			
		||||
	if (s->mode & MODE_BACKGROUND) {
 | 
			
		||||
		if (s->mode & MODE_BGCURSOR)
 | 
			
		||||
			input_store_zero(c->out, CODE_CURSORON);
 | 
			
		||||
	} else {
 | 
			
		||||
		if (s->mode & MODE_CURSOR)
 | 
			
		||||
			input_store_zero(c->out, CODE_CURSORON);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	size = BUFFER_USED(c->out) - size;
 | 
			
		||||
	hdr.type = MSG_DATA;
 | 
			
		||||
	hdr.size = size;
 | 
			
		||||
	memcpy(BUFFER_IN(c->out) - size - sizeof hdr,  &hdr, sizeof hdr);
 | 
			
		||||
	status_write_client(c);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
server_redraw_client(struct client *c)
 | 
			
		||||
{
 | 
			
		||||
	struct screen_draw_ctx	ctx;
 | 
			
		||||
	struct window	       *w = c->session->curw->window;
 | 
			
		||||
	struct hdr	 hdr;
 | 
			
		||||
	size_t		 size;
 | 
			
		||||
 | 
			
		||||
	buffer_ensure(c->out, sizeof hdr);
 | 
			
		||||
	buffer_add(c->out, sizeof hdr);
 | 
			
		||||
	size = BUFFER_USED(c->out);
 | 
			
		||||
	screen_draw_start_client(&ctx, c, 0, 0);
 | 
			
		||||
	window_draw(w, &ctx, 0, screen_size_y(&w->screen));
 | 
			
		||||
	screen_draw_stop(&ctx);
 | 
			
		||||
 | 
			
		||||
	window_draw(w, c->out, 0, screen_size_y(&w->screen));
 | 
			
		||||
	status_write_client(c);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
	size = BUFFER_USED(c->out) - size;
 | 
			
		||||
	log_debug("redrawing window, %zu bytes", size);
 | 
			
		||||
	if (size != 0) {
 | 
			
		||||
		hdr.type = MSG_DATA;
 | 
			
		||||
		hdr.size = size;
 | 
			
		||||
		memcpy(BUFFER_IN(c->out) - size - sizeof hdr, &hdr, sizeof hdr);
 | 
			
		||||
	} else
 | 
			
		||||
		buffer_reverse_add(c->out, sizeof hdr);
 | 
			
		||||
void
 | 
			
		||||
server_status_client(struct client *c)
 | 
			
		||||
{
 | 
			
		||||
	status_write_client(c);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
	server_status_client(c);
 | 
			
		||||
void
 | 
			
		||||
server_clear_session(struct session *s)
 | 
			
		||||
{
 | 
			
		||||
	struct screen_draw_ctx	ctx;
 | 
			
		||||
 | 
			
		||||
	screen_draw_start_session(&ctx, s, 0, 0);
 | 
			
		||||
	screen_draw_clear_screen(&ctx);
 | 
			
		||||
	screen_draw_stop(&ctx);
 | 
			
		||||
 | 
			
		||||
	status_write_session(s);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
server_redraw_session(struct session *s)
 | 
			
		||||
{
 | 
			
		||||
	struct client	*c;
 | 
			
		||||
	u_int		 i;
 | 
			
		||||
	struct screen_draw_ctx	ctx;
 | 
			
		||||
	struct window	       *w = s->curw->window;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
 | 
			
		||||
		c = ARRAY_ITEM(&clients, i);
 | 
			
		||||
		if (c != NULL && c->session == s)
 | 
			
		||||
			server_redraw_client(c);
 | 
			
		||||
	}
 | 
			
		||||
	screen_draw_start_session(&ctx, s, 0, 0);
 | 
			
		||||
	window_draw(w, &ctx, 0, screen_size_y(&w->screen));
 | 
			
		||||
	screen_draw_stop(&ctx);
 | 
			
		||||
 | 
			
		||||
	status_write_session(s);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
server_status_session(struct session *s)
 | 
			
		||||
{
 | 
			
		||||
	struct client	*c;
 | 
			
		||||
	u_int		 i;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
 | 
			
		||||
		c = ARRAY_ITEM(&clients, i);
 | 
			
		||||
		if (c != NULL && c->session == s)
 | 
			
		||||
			server_status_client(c);
 | 
			
		||||
	}
 | 
			
		||||
	status_write_session(s);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
server_clear_window_cur(struct window *w)
 | 
			
		||||
server_clear_window(struct window *w)
 | 
			
		||||
{
 | 
			
		||||
	struct client	*c;
 | 
			
		||||
	u_int		 i;
 | 
			
		||||
	struct screen_draw_ctx	ctx;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
 | 
			
		||||
		c = ARRAY_ITEM(&clients, i);
 | 
			
		||||
		if (c != NULL &&
 | 
			
		||||
		    c->session != NULL && c->session->curw->window == w)
 | 
			
		||||
			server_clear_client(c);
 | 
			
		||||
	}
 | 
			
		||||
	screen_draw_start_window(&ctx, w, 0, 0);
 | 
			
		||||
	screen_draw_clear_screen(&ctx);
 | 
			
		||||
	screen_draw_stop(&ctx);
 | 
			
		||||
 | 
			
		||||
	status_write_window(w);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
server_clear_window_all(struct window *w)
 | 
			
		||||
server_redraw_window(struct window *w)
 | 
			
		||||
{
 | 
			
		||||
	struct client	*c;
 | 
			
		||||
	u_int		 i;
 | 
			
		||||
	struct screen_draw_ctx	ctx;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
 | 
			
		||||
		c = ARRAY_ITEM(&clients, i);
 | 
			
		||||
		if (c == NULL || c->session == NULL)
 | 
			
		||||
			continue;
 | 
			
		||||
		if (session_has(c->session, w))
 | 
			
		||||
			server_redraw_client(c);
 | 
			
		||||
	}
 | 
			
		||||
	screen_draw_start_window(&ctx, w, 0, 0);
 | 
			
		||||
	window_draw(w, &ctx, 0, screen_size_y(&w->screen));
 | 
			
		||||
	screen_draw_stop(&ctx);
 | 
			
		||||
 | 
			
		||||
	status_write_window(w);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
server_redraw_window_cur(struct window *w)
 | 
			
		||||
server_status_window(struct window *w)
 | 
			
		||||
{
 | 
			
		||||
	struct client	*c;
 | 
			
		||||
	struct session	*s;
 | 
			
		||||
	u_int		 i;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
 | 
			
		||||
		c = ARRAY_ITEM(&clients, i);
 | 
			
		||||
		if (c != NULL &&
 | 
			
		||||
		    c->session != NULL && c->session->curw->window == w)
 | 
			
		||||
			server_redraw_client(c);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
	/*
 | 
			
		||||
	 * This is slightly different. We want to redraw the status line of any
 | 
			
		||||
	 * clients containing this window rather than any where it is the
 | 
			
		||||
	 * current window.
 | 
			
		||||
	 */
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
server_redraw_window_all(struct window *w)
 | 
			
		||||
{
 | 
			
		||||
	struct client	*c;
 | 
			
		||||
	u_int		 i;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
 | 
			
		||||
		c = ARRAY_ITEM(&clients, i);
 | 
			
		||||
		if (c == NULL || c->session == NULL)
 | 
			
		||||
			continue;
 | 
			
		||||
		if (session_has(c->session, w))
 | 
			
		||||
			server_redraw_client(c);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
server_status_window_cur(struct window *w)
 | 
			
		||||
{
 | 
			
		||||
	struct client	*c;
 | 
			
		||||
	u_int		 i;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
 | 
			
		||||
		c = ARRAY_ITEM(&clients, i);
 | 
			
		||||
		if (c != NULL &&
 | 
			
		||||
		    c->session != NULL && c->session->curw->window == w)
 | 
			
		||||
			server_status_client(c);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
server_status_window_all(struct window *w)
 | 
			
		||||
{
 | 
			
		||||
	struct client	*c;
 | 
			
		||||
	u_int		 i;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
 | 
			
		||||
		c = ARRAY_ITEM(&clients, i);
 | 
			
		||||
		if (c == NULL || c->session == NULL)
 | 
			
		||||
			continue;
 | 
			
		||||
		if (session_has(c->session, w))
 | 
			
		||||
			server_status_client(c);
 | 
			
		||||
	for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
 | 
			
		||||
		s = ARRAY_ITEM(&sessions, i);
 | 
			
		||||
		if (s != NULL && session_has(s, w))
 | 
			
		||||
			server_status_session(s);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void printflike2
 | 
			
		||||
server_write_message(struct client *c, const char *fmt, ...)
 | 
			
		||||
{
 | 
			
		||||
	struct window	       *w = c->session->curw->window;
 | 
			
		||||
	struct screen_draw_ctx	ctx;
 | 
			
		||||
	struct hdr		hdr;
 | 
			
		||||
	va_list			ap;
 | 
			
		||||
	char		       *msg;
 | 
			
		||||
	size_t			size;
 | 
			
		||||
	u_int			i;
 | 
			
		||||
 | 
			
		||||
	buffer_ensure(c->out, sizeof hdr);
 | 
			
		||||
	buffer_add(c->out, sizeof hdr);
 | 
			
		||||
	size = BUFFER_USED(c->out);
 | 
			
		||||
 | 
			
		||||
	screen_draw_start(&ctx, &w->screen, c->out, 0, 0);
 | 
			
		||||
	screen_draw_move(&ctx, 0, c->sy - 1);
 | 
			
		||||
	screen_draw_start_client(&ctx, c, 0, 0);
 | 
			
		||||
	screen_draw_move_cursor(&ctx, 0, c->sy - 1);
 | 
			
		||||
	screen_draw_set_attributes(&ctx, ATTR_REVERSE, 0x88);
 | 
			
		||||
 | 
			
		||||
	va_start(ap, fmt);
 | 
			
		||||
	xvasprintf(&msg, fmt, ap);
 | 
			
		||||
	va_end(ap);
 | 
			
		||||
	if (strlen(msg) > c->sx - 1)
 | 
			
		||||
	
 | 
			
		||||
	size = strlen(msg);
 | 
			
		||||
	if (size < c->sx - 1) {
 | 
			
		||||
		msg = xrealloc(msg, 1, c->sx);
 | 
			
		||||
		msg[c->sx - 1] = '\0';
 | 
			
		||||
	buffer_write(c->out, msg, strlen(msg));
 | 
			
		||||
	for (i = strlen(msg); i < c->sx; i++)
 | 
			
		||||
		input_store8(c->out, ' ');
 | 
			
		||||
		memset(msg + size, SCREEN_DEFDATA, (c->sx - 1) - size);
 | 
			
		||||
	}
 | 
			
		||||
	screen_draw_write_string(&ctx, "%s", msg);
 | 
			
		||||
	xfree(msg);
 | 
			
		||||
 | 
			
		||||
	size = BUFFER_USED(c->out) - size;
 | 
			
		||||
  	hdr.type = MSG_DATA;
 | 
			
		||||
	hdr.size = size;
 | 
			
		||||
	memcpy(BUFFER_IN(c->out) - size - sizeof hdr, &hdr, sizeof hdr);
 | 
			
		||||
 | 
			
		||||
	hdr.type = MSG_PAUSE;
 | 
			
		||||
	hdr.size = 0;
 | 
			
		||||
	buffer_write(c->out, &hdr, sizeof hdr);
 | 
			
		||||
 | 
			
		||||
	buffer_ensure(c->out, sizeof hdr);
 | 
			
		||||
	buffer_add(c->out, sizeof hdr);
 | 
			
		||||
	size = BUFFER_USED(c->out);
 | 
			
		||||
	buffer_flush(c->tty.fd, c->tty.in, c->tty.out);
 | 
			
		||||
	usleep(750000);	
 | 
			
		||||
 | 
			
		||||
	if (status_lines == 0) {
 | 
			
		||||
		window_draw(c->session->curw->window, &ctx, c->sy - 1, 1);
 | 
			
		||||
		screen_draw_stop(&ctx);
 | 
			
		||||
	if (status_lines == 0)
 | 
			
		||||
		window_draw(w, c->out, c->sy - 1, 1);
 | 
			
		||||
	else
 | 
			
		||||
		status_write(c);
 | 
			
		||||
	
 | 
			
		||||
	size = BUFFER_USED(c->out) - size;
 | 
			
		||||
	hdr.type = MSG_DATA;
 | 
			
		||||
	hdr.size = size;
 | 
			
		||||
	memcpy(BUFFER_IN(c->out) - size - sizeof hdr, &hdr, sizeof hdr);
 | 
			
		||||
	} else {
 | 
			
		||||
		screen_draw_stop(&ctx);
 | 
			
		||||
		status_write_client(c);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										44
									
								
								server-msg.c
									
									
									
									
									
								
							
							
						
						
									
										44
									
								
								server-msg.c
									
									
									
									
									
								
							@@ -1,4 +1,5 @@
 | 
			
		||||
/* $Id: server-msg.c,v 1.37 2007-11-24 20:08:49 nicm Exp $ */
 | 
			
		||||
 | 
			
		||||
/* $Id: server-msg.c,v 1.38 2007-11-27 19:23:34 nicm Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -18,6 +19,7 @@
 | 
			
		||||
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
@@ -26,7 +28,6 @@
 | 
			
		||||
 | 
			
		||||
int	server_msg_fn_command(struct hdr *, struct client *);
 | 
			
		||||
int	server_msg_fn_identify(struct hdr *, struct client *);
 | 
			
		||||
int	server_msg_fn_keys(struct hdr *, struct client *);
 | 
			
		||||
int	server_msg_fn_resize(struct hdr *, struct client *);
 | 
			
		||||
 | 
			
		||||
void printflike2 server_msg_fn_command_error(
 | 
			
		||||
@@ -43,7 +44,6 @@ const struct server_msg server_msg_table[] = {
 | 
			
		||||
	{ MSG_IDENTIFY, server_msg_fn_identify },
 | 
			
		||||
	{ MSG_COMMAND, server_msg_fn_command },
 | 
			
		||||
	{ MSG_RESIZE, server_msg_fn_resize },
 | 
			
		||||
	{ MSG_KEYS, server_msg_fn_keys },
 | 
			
		||||
};
 | 
			
		||||
#define NSERVERMSG (sizeof server_msg_table / sizeof server_msg_table[0])
 | 
			
		||||
 | 
			
		||||
@@ -152,7 +152,7 @@ server_msg_fn_command(struct hdr *hdr, struct client *c)
 | 
			
		||||
		for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
 | 
			
		||||
			/* XXX fnmatch, multi clients etc */
 | 
			
		||||
			c = ARRAY_ITEM(&clients, i);
 | 
			
		||||
			if (c != NULL && strcmp(client, c->tty) == 0)
 | 
			
		||||
			if (c != NULL && strcmp(client, c->tty.path) == 0)
 | 
			
		||||
				ctx.client = c;
 | 
			
		||||
		}
 | 
			
		||||
		if (ctx.client == NULL) {
 | 
			
		||||
@@ -192,10 +192,12 @@ int
 | 
			
		||||
server_msg_fn_identify(struct hdr *hdr, struct client *c)
 | 
			
		||||
{
 | 
			
		||||
	struct msg_identify_data	data;
 | 
			
		||||
        char			       *term;
 | 
			
		||||
 | 
			
		||||
	if (hdr->size < sizeof data)
 | 
			
		||||
		fatalx("bad MSG_IDENTIFY size");
 | 
			
		||||
	buffer_read(c->in, &data, sizeof data);
 | 
			
		||||
	term = cmd_recv_string(c->in);
 | 
			
		||||
 | 
			
		||||
	log_debug("identify msg from client: %u,%u", data.sx, data.sy);
 | 
			
		||||
 | 
			
		||||
@@ -203,7 +205,8 @@ server_msg_fn_identify(struct hdr *hdr, struct client *c)
 | 
			
		||||
	c->sy = data.sy;
 | 
			
		||||
 | 
			
		||||
	data.tty[(sizeof data.tty) - 1] = '\0';
 | 
			
		||||
	c->tty = xstrdup(data.tty);
 | 
			
		||||
	tty_init(&c->tty, data.tty, xstrdup(term));
 | 
			
		||||
	xfree(term);
 | 
			
		||||
 | 
			
		||||
	c->flags |= CLIENT_TERMINAL;
 | 
			
		||||
 | 
			
		||||
@@ -235,34 +238,3 @@ server_msg_fn_resize(struct hdr *hdr, struct client *c)
 | 
			
		||||
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
server_msg_fn_keys(struct hdr *hdr, struct client *c)
 | 
			
		||||
{
 | 
			
		||||
	struct window	*w = c->session->curw->window;
 | 
			
		||||
	int		 key;
 | 
			
		||||
	size_t		 size;
 | 
			
		||||
 | 
			
		||||
	if (hdr->size & 0x1)
 | 
			
		||||
		fatalx("bad MSG_KEYS size");
 | 
			
		||||
 | 
			
		||||
	size = hdr->size;
 | 
			
		||||
	while (size != 0) {
 | 
			
		||||
		key = (int16_t) input_extract16(c->in);
 | 
			
		||||
		size -= 2;
 | 
			
		||||
 | 
			
		||||
		if (c->flags & CLIENT_PREFIX) {
 | 
			
		||||
			key_bindings_dispatch(key, c);
 | 
			
		||||
			c->flags &= ~CLIENT_PREFIX;
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (key == prefix_key) {
 | 
			
		||||
			c->flags |= CLIENT_PREFIX;
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
		window_key(w, key);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										77
									
								
								server.c
									
									
									
									
									
								
							
							
						
						
									
										77
									
								
								server.c
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: server.c,v 1.39 2007-11-21 13:11:41 nicm Exp $ */
 | 
			
		||||
/* $Id: server.c,v 1.40 2007-11-27 19:23:34 nicm Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -49,6 +49,7 @@ void		 server_handle_windows(struct pollfd **);
 | 
			
		||||
void		 server_fill_clients(struct pollfd **);
 | 
			
		||||
void		 server_handle_clients(struct pollfd **);
 | 
			
		||||
struct client	*server_accept_client(int);
 | 
			
		||||
void		 server_handle_client(struct client *);
 | 
			
		||||
void		 server_handle_window(struct window *);
 | 
			
		||||
void		 server_lost_client(struct client *);
 | 
			
		||||
void	 	 server_lost_window(struct window *);
 | 
			
		||||
@@ -139,7 +140,7 @@ server_main(const char *srv_path, int srv_fd)
 | 
			
		||||
	pfds = NULL;
 | 
			
		||||
	while (!sigterm) {
 | 
			
		||||
		/* Initialise pollfd array. */
 | 
			
		||||
		nfds = 1 + ARRAY_LENGTH(&windows) + ARRAY_LENGTH(&clients);
 | 
			
		||||
		nfds = 1 + ARRAY_LENGTH(&windows) + ARRAY_LENGTH(&clients) * 2;
 | 
			
		||||
		pfds = xrealloc(pfds, nfds, sizeof *pfds);
 | 
			
		||||
		pfd = pfds;
 | 
			
		||||
 | 
			
		||||
@@ -246,7 +247,9 @@ server_fill_clients(struct pollfd **pfd)
 | 
			
		||||
	u_int		 i;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
 | 
			
		||||
		if ((c = ARRAY_ITEM(&clients, i)) == NULL)
 | 
			
		||||
		c = ARRAY_ITEM(&clients, i);
 | 
			
		||||
 | 
			
		||||
		if (c == NULL)
 | 
			
		||||
			(*pfd)->fd = -1;
 | 
			
		||||
		else {
 | 
			
		||||
			(*pfd)->fd = c->fd;
 | 
			
		||||
@@ -255,6 +258,16 @@ server_fill_clients(struct pollfd **pfd)
 | 
			
		||||
				(*pfd)->events |= POLLOUT;
 | 
			
		||||
		}
 | 
			
		||||
		(*pfd)++;
 | 
			
		||||
 | 
			
		||||
		if (c == NULL || c->tty.fd == -1)
 | 
			
		||||
			(*pfd)->fd = -1;
 | 
			
		||||
		else {
 | 
			
		||||
			(*pfd)->fd = c->tty.fd;
 | 
			
		||||
			(*pfd)->events = POLLIN;
 | 
			
		||||
			if (BUFFER_USED(c->tty.out) > 0)
 | 
			
		||||
				(*pfd)->events |= POLLOUT;
 | 
			
		||||
		}
 | 
			
		||||
		(*pfd)++;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -266,11 +279,23 @@ server_handle_clients(struct pollfd **pfd)
 | 
			
		||||
	u_int		 i;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
 | 
			
		||||
		if ((c = ARRAY_ITEM(&clients, i)) != NULL) {
 | 
			
		||||
			if (buffer_poll(*pfd, c->in, c->out) != 0)
 | 
			
		||||
		c = ARRAY_ITEM(&clients, i);
 | 
			
		||||
 | 
			
		||||
		if (c != NULL) {
 | 
			
		||||
			if (buffer_poll(*pfd, c->in, c->out) != 0) {
 | 
			
		||||
				server_lost_client(c);
 | 
			
		||||
				(*pfd) += 2;
 | 
			
		||||
				continue;
 | 
			
		||||
			} else
 | 
			
		||||
				server_msg_dispatch(c);
 | 
			
		||||
		}
 | 
			
		||||
		(*pfd)++;
 | 
			
		||||
 | 
			
		||||
		if (c != NULL && c->tty.fd != -1) {
 | 
			
		||||
			if (buffer_poll(*pfd, c->tty.in, c->tty.out) != 0)
 | 
			
		||||
				server_lost_client(c);
 | 
			
		||||
			else
 | 
			
		||||
				server_msg_dispatch(c);
 | 
			
		||||
				server_handle_client(c);
 | 
			
		||||
		}
 | 
			
		||||
		(*pfd)++;
 | 
			
		||||
	}
 | 
			
		||||
@@ -302,6 +327,8 @@ server_accept_client(int srv_fd)
 | 
			
		||||
	c->in = buffer_create(BUFSIZ);
 | 
			
		||||
	c->out = buffer_create(BUFSIZ);
 | 
			
		||||
 | 
			
		||||
	c->tty.fd = -1;
 | 
			
		||||
 | 
			
		||||
	c->session = NULL;
 | 
			
		||||
	c->sx = 80;
 | 
			
		||||
	c->sy = 25;
 | 
			
		||||
@@ -316,6 +343,25 @@ server_accept_client(int srv_fd)
 | 
			
		||||
	return (c);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Input data from client. */
 | 
			
		||||
void
 | 
			
		||||
server_handle_client(struct client *c)
 | 
			
		||||
{
 | 
			
		||||
	struct window	*w = c->session->curw->window;
 | 
			
		||||
	int		 key;
 | 
			
		||||
 | 
			
		||||
	while (tty_keys_next(&c->tty, &key) == 0) {
 | 
			
		||||
		if (c->flags & CLIENT_PREFIX) {
 | 
			
		||||
			key_bindings_dispatch(key, c);
 | 
			
		||||
			c->flags &= ~CLIENT_PREFIX;
 | 
			
		||||
			continue;
 | 
			
		||||
		} else if (key == prefix_key)
 | 
			
		||||
			c->flags |= CLIENT_PREFIX;
 | 
			
		||||
		else
 | 
			
		||||
			window_key(w, key);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Lost a client. */
 | 
			
		||||
void
 | 
			
		||||
server_lost_client(struct client *c)
 | 
			
		||||
@@ -327,8 +373,8 @@ server_lost_client(struct client *c)
 | 
			
		||||
			ARRAY_SET(&clients, i, NULL);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	if (c->tty != NULL)
 | 
			
		||||
		xfree(c->tty);
 | 
			
		||||
	tty_free(&c->tty);
 | 
			
		||||
 | 
			
		||||
	close(c->fd);
 | 
			
		||||
	buffer_destroy(c->in);
 | 
			
		||||
	buffer_destroy(c->out);
 | 
			
		||||
@@ -341,17 +387,10 @@ server_lost_client(struct client *c)
 | 
			
		||||
void
 | 
			
		||||
server_handle_window(struct window *w)
 | 
			
		||||
{
 | 
			
		||||
	struct buffer	*b;
 | 
			
		||||
	struct session	*s;
 | 
			
		||||
	u_int		 i;
 | 
			
		||||
 | 
			
		||||
	b = buffer_create(BUFSIZ);
 | 
			
		||||
	window_parse(w, b);
 | 
			
		||||
	if (BUFFER_USED(b) != 0) {
 | 
			
		||||
		server_write_window_cur(
 | 
			
		||||
		    w, MSG_DATA, BUFFER_OUT(b), BUFFER_USED(b));
 | 
			
		||||
	}
 | 
			
		||||
	buffer_destroy(b);
 | 
			
		||||
	window_parse(w);
 | 
			
		||||
 | 
			
		||||
	if (!(w->flags & WINDOW_BELL))
 | 
			
		||||
		return;
 | 
			
		||||
@@ -364,17 +403,17 @@ server_handle_window(struct window *w)
 | 
			
		||||
 | 
			
		||||
	switch (bell_action) {
 | 
			
		||||
	case BELL_ANY:
 | 
			
		||||
		server_write_window_all(w, MSG_DATA, "\007", 1);
 | 
			
		||||
		tty_write_window(w, TTY_CHARACTER, '\007');
 | 
			
		||||
		break;
 | 
			
		||||
	case BELL_CURRENT:
 | 
			
		||||
		for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
 | 
			
		||||
			s = ARRAY_ITEM(&sessions, i);
 | 
			
		||||
			if (s != NULL && s->curw->window == w)
 | 
			
		||||
				server_write_session(s, MSG_DATA, "\007", 1);
 | 
			
		||||
				tty_write_session(s, TTY_CHARACTER, '\007');
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
	server_status_window_all(w);
 | 
			
		||||
	server_status_window(w);
 | 
			
		||||
 | 
			
		||||
	w->flags &= ~WINDOW_BELL;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										81
									
								
								status.c
									
									
									
									
									
								
							
							
						
						
									
										81
									
								
								status.c
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: status.c,v 1.13 2007-11-22 18:09:43 nicm Exp $ */
 | 
			
		||||
/* $Id: status.c,v 1.14 2007-11-27 19:23:34 nicm Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -25,19 +25,19 @@
 | 
			
		||||
void printflike3 status_print(struct buffer *, size_t *, const char *, ...);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
status_write(struct client *c)
 | 
			
		||||
status_write_client(struct client *c)
 | 
			
		||||
{
 | 
			
		||||
	struct screen	*s = &c->session->curw->window->screen;
 | 
			
		||||
	struct buffer	*b = c->out;
 | 
			
		||||
	struct screen_draw_ctx	ctx;
 | 
			
		||||
	struct winlink	       *wl;
 | 
			
		||||
	size_t		 size;
 | 
			
		||||
	char			flag;
 | 
			
		||||
 | 
			
		||||
	input_store_zero(b, CODE_CURSOROFF);
 | 
			
		||||
	input_store_two(b, CODE_CURSORMOVE, c->sy - status_lines + 1, 1);
 | 
			
		||||
	input_store_two(b, CODE_ATTRIBUTES, 0, status_colour);
 | 
			
		||||
	if (status_lines == 0 || c->sy <= status_lines)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	screen_draw_start_client(&ctx, c, 0, 0);
 | 
			
		||||
	screen_draw_move_cursor(&ctx, 0, c->sy - status_lines);
 | 
			
		||||
	screen_draw_set_attributes(&ctx, 0, status_colour);
 | 
			
		||||
 | 
			
		||||
	size = c->sx;
 | 
			
		||||
	RB_FOREACH(wl, winlinks, &c->session->windows) {
 | 
			
		||||
		flag = ' ';
 | 
			
		||||
		if (wl == c->session->lastw)
 | 
			
		||||
@@ -46,45 +46,50 @@ status_write(struct client *c)
 | 
			
		||||
			flag = '*';
 | 
			
		||||
		if (session_hasbell(c->session, wl))
 | 
			
		||||
			flag = '!';
 | 
			
		||||
		status_print(
 | 
			
		||||
		    b, &size, "%d:%s%c ", wl->idx, wl->window->name, flag);
 | 
			
		||||
		screen_draw_write_string(
 | 
			
		||||
		    &ctx, "%d:%s%c ", wl->idx, wl->window->name, flag);
 | 
			
		||||
 | 
			
		||||
		if (size == 0)
 | 
			
		||||
		if (ctx.cx >= screen_last_x(ctx.s))
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
	while (size-- > 0)
 | 
			
		||||
		input_store8(b, ' ');
 | 
			
		||||
	screen_draw_clear_line_to(&ctx, screen_last_x(ctx.s));
 | 
			
		||||
 | 
			
		||||
	input_store_two(b, CODE_ATTRIBUTES, s->attr, s->colr);
 | 
			
		||||
	input_store_two(b, CODE_CURSORMOVE, s->cy + 1, s->cx + 1);
 | 
			
		||||
	if (s->mode & MODE_BACKGROUND) {
 | 
			
		||||
		if (s->mode & MODE_BGCURSOR)
 | 
			
		||||
			input_store_zero(c->out, CODE_CURSORON);
 | 
			
		||||
	} else {
 | 
			
		||||
		if (s->mode & MODE_CURSOR)
 | 
			
		||||
			input_store_zero(c->out, CODE_CURSORON);
 | 
			
		||||
	}
 | 
			
		||||
	screen_draw_stop(&ctx);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void printflike3
 | 
			
		||||
status_print(struct buffer *b, size_t *size, const char *fmt, ...)
 | 
			
		||||
void
 | 
			
		||||
status_write_window(struct window *w)
 | 
			
		||||
{
 | 
			
		||||
	va_list	ap;
 | 
			
		||||
	char   *msg, *ptr;
 | 
			
		||||
	int	n;
 | 
			
		||||
	struct client	*c;
 | 
			
		||||
	u_int		 i;
 | 
			
		||||
 | 
			
		||||
	va_start(ap, fmt);
 | 
			
		||||
	n = xvasprintf(&msg, fmt, ap);
 | 
			
		||||
	va_end(ap);
 | 
			
		||||
	if (w->screen.mode & MODE_HIDDEN)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	if ((size_t) n > *size) {
 | 
			
		||||
		msg[*size] = '\0';
 | 
			
		||||
		n = *size;
 | 
			
		||||
	for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
 | 
			
		||||
		c = ARRAY_ITEM(&clients, i);
 | 
			
		||||
		if (c == NULL || c->session == NULL)
 | 
			
		||||
			continue;
 | 
			
		||||
		if (c->session->curw->window != w)
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		status_write_client(c);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
	for (ptr = msg; *ptr != '\0'; ptr++)
 | 
			
		||||
		input_store8(b, *ptr);
 | 
			
		||||
	(*size) -= n;
 | 
			
		||||
void
 | 
			
		||||
status_write_session(struct session *s)
 | 
			
		||||
{
 | 
			
		||||
	struct client	*c;
 | 
			
		||||
	u_int		 i;
 | 
			
		||||
 | 
			
		||||
	xfree(msg);
 | 
			
		||||
	if (s->flags & SESSION_UNATTACHED)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
 | 
			
		||||
		c = ARRAY_ITEM(&clients, i);
 | 
			
		||||
		if (c == NULL || c->session != s)
 | 
			
		||||
			continue;
 | 
			
		||||
		status_write_client(c);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										208
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										208
									
								
								tmux.h
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: tmux.h,v 1.100 2007-11-24 23:29:49 nicm Exp $ */
 | 
			
		||||
/* $Id: tmux.h,v 1.101 2007-11-27 19:23:34 nicm Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -41,6 +41,7 @@
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <term.h>
 | 
			
		||||
 | 
			
		||||
#include "array.h"
 | 
			
		||||
 | 
			
		||||
@@ -255,34 +256,32 @@ struct buffer {
 | 
			
		||||
#define KEYC_UP -149
 | 
			
		||||
#define KEYC_MOUSE -150
 | 
			
		||||
 | 
			
		||||
/* Translated escape codes. */
 | 
			
		||||
#define CODE_CURSORUP 0
 | 
			
		||||
#define CODE_CURSORDOWN 1
 | 
			
		||||
#define CODE_CURSORRIGHT 2
 | 
			
		||||
#define CODE_CURSORLEFT 3
 | 
			
		||||
#define CODE_INSERTCHARACTER 4
 | 
			
		||||
#define CODE_DELETECHARACTER 5
 | 
			
		||||
#define CODE_INSERTLINE 6
 | 
			
		||||
#define CODE_DELETELINE 7
 | 
			
		||||
#define CODE_CLEARLINE 8
 | 
			
		||||
/* 9 unused */
 | 
			
		||||
/* 10 unused */
 | 
			
		||||
#define CODE_CLEARENDOFLINE 11
 | 
			
		||||
#define CODE_CLEARSTARTOFLINE 12
 | 
			
		||||
#define CODE_CURSORMOVE 13
 | 
			
		||||
#define CODE_ATTRIBUTES 14
 | 
			
		||||
#define CODE_CURSOROFF 15
 | 
			
		||||
#define CODE_CURSORON 16
 | 
			
		||||
#define CODE_REVERSEINDEX 17
 | 
			
		||||
/* 18 unused */
 | 
			
		||||
#define CODE_SCROLLREGION 19
 | 
			
		||||
#define CODE_INSERTON 20
 | 
			
		||||
#define CODE_INSERTOFF 21
 | 
			
		||||
#define CODE_KCURSOROFF 22
 | 
			
		||||
#define CODE_KCURSORON 23
 | 
			
		||||
#define CODE_KKEYPADOFF 24
 | 
			
		||||
#define CODE_KKEYPADON 25
 | 
			
		||||
#define CODE_TITLE 26
 | 
			
		||||
/* Output codes. */
 | 
			
		||||
#define TTY_CHARACTER 0
 | 
			
		||||
#define TTY_CURSORUP 1
 | 
			
		||||
#define TTY_CURSORDOWN 2
 | 
			
		||||
#define TTY_CURSORRIGHT 3
 | 
			
		||||
#define TTY_CURSORLEFT 4
 | 
			
		||||
#define TTY_INSERTCHARACTER 5
 | 
			
		||||
#define TTY_DELETECHARACTER 6
 | 
			
		||||
#define TTY_INSERTLINE 7
 | 
			
		||||
#define TTY_DELETELINE 8
 | 
			
		||||
#define TTY_CLEARLINE 9
 | 
			
		||||
#define TTY_CLEARENDOFLINE 10
 | 
			
		||||
#define TTY_CLEARSTARTOFLINE 11
 | 
			
		||||
#define TTY_CURSORMOVE 12
 | 
			
		||||
#define TTY_ATTRIBUTES 13
 | 
			
		||||
#define TTY_CURSOROFF 14
 | 
			
		||||
#define TTY_CURSORON 15
 | 
			
		||||
#define TTY_REVERSEINDEX 16
 | 
			
		||||
#define TTY_SCROLLREGION 17
 | 
			
		||||
#define TTY_INSERTON 18
 | 
			
		||||
#define TTY_INSERTOFF 19
 | 
			
		||||
#define TTY_KCURSOROFF 20
 | 
			
		||||
#define TTY_KCURSORON 21
 | 
			
		||||
#define TTY_KKEYPADOFF 22
 | 
			
		||||
#define TTY_KKEYPADON 23
 | 
			
		||||
#define TTY_TITLE 24
 | 
			
		||||
 | 
			
		||||
/* Message codes. */
 | 
			
		||||
enum hdrtype {
 | 
			
		||||
@@ -294,9 +293,6 @@ enum hdrtype {
 | 
			
		||||
	MSG_READY,
 | 
			
		||||
	MSG_DETACH,
 | 
			
		||||
	MSG_RESIZE,
 | 
			
		||||
	MSG_DATA,
 | 
			
		||||
	MSG_KEYS,
 | 
			
		||||
	MSG_PAUSE,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Message header structure. */
 | 
			
		||||
@@ -317,6 +313,8 @@ struct msg_identify_data {
 | 
			
		||||
 | 
			
		||||
	u_int		sx;
 | 
			
		||||
	u_int		sy;
 | 
			
		||||
 | 
			
		||||
	size_t		termlen;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct msg_resize_data {
 | 
			
		||||
@@ -394,8 +392,10 @@ struct screen_draw_sel {
 | 
			
		||||
 | 
			
		||||
/* Screen redraw context. */
 | 
			
		||||
struct screen_draw_ctx {
 | 
			
		||||
	void		*data;
 | 
			
		||||
	void		 (*write)(void *, int, ...);
 | 
			
		||||
 | 
			
		||||
	struct screen	*s;
 | 
			
		||||
	struct buffer	*b;
 | 
			
		||||
 | 
			
		||||
	u_int		 cx;
 | 
			
		||||
	u_int		 cy;
 | 
			
		||||
@@ -423,8 +423,6 @@ struct screen_draw_ctx {
 | 
			
		||||
#define screen_in_y(s, y) ((y) < screen_size_y(s))
 | 
			
		||||
#define screen_in_region(s, y) ((y) >= (s)->rupper && (y) <= (s)->rlower)
 | 
			
		||||
 | 
			
		||||
#define screen_hidden(s) ((s)->mode & (MODE_HIDDEN|MODE_BACKGROUND))
 | 
			
		||||
 | 
			
		||||
/* Screen default contents. */
 | 
			
		||||
#define SCREEN_DEFDATA ' '
 | 
			
		||||
#define SCREEN_DEFATTR 0
 | 
			
		||||
@@ -439,7 +437,6 @@ struct input_arg {
 | 
			
		||||
/* Input parser context. */
 | 
			
		||||
struct input_ctx {
 | 
			
		||||
	struct window	*w;
 | 
			
		||||
	struct buffer	*b;
 | 
			
		||||
 | 
			
		||||
	u_char		*buf;
 | 
			
		||||
	size_t		 len;
 | 
			
		||||
@@ -462,7 +459,8 @@ struct input_ctx {
 | 
			
		||||
struct window_mode {
 | 
			
		||||
	void	(*init)(struct window *);
 | 
			
		||||
	void	(*resize)(struct window *, u_int, u_int);
 | 
			
		||||
	void	(*draw)(struct window *, struct buffer *, u_int, u_int);
 | 
			
		||||
	void	(*draw)(
 | 
			
		||||
	    	    struct window *, struct screen_draw_ctx *, u_int, u_int);
 | 
			
		||||
	void	(*key)(struct window *, int);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@@ -516,19 +514,49 @@ struct session {
 | 
			
		||||
};
 | 
			
		||||
ARRAY_DECL(sessions, struct session *);
 | 
			
		||||
 | 
			
		||||
/* Client connection. */
 | 
			
		||||
struct client {
 | 
			
		||||
	char		*tty;
 | 
			
		||||
/* TTY information. */
 | 
			
		||||
struct tty_key {
 | 
			
		||||
	int	 	 code;
 | 
			
		||||
	char		*string;
 | 
			
		||||
 | 
			
		||||
	RB_ENTRY(tty_key) entry;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct tty {
 | 
			
		||||
	char		*path;
 | 
			
		||||
 | 
			
		||||
	char		*term;
 | 
			
		||||
	TERMINAL        *termp;
 | 
			
		||||
 | 
			
		||||
	int		 fd;
 | 
			
		||||
	struct buffer	*in;
 | 
			
		||||
	struct buffer	*out;
 | 
			
		||||
 | 
			
		||||
	struct termios   tio;
 | 
			
		||||
 | 
			
		||||
	u_int		 attr;
 | 
			
		||||
	u_int		 colr;
 | 
			
		||||
 | 
			
		||||
	u_char		 acs[UCHAR_MAX + 1];
 | 
			
		||||
 | 
			
		||||
	size_t		 ksize;	/* maximum key size */
 | 
			
		||||
	RB_HEAD(tty_keys, tty_key) ktree;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Client connection. */
 | 
			
		||||
struct client {
 | 
			
		||||
	int		 fd;
 | 
			
		||||
	struct buffer	*in;
 | 
			
		||||
	struct buffer	*out;
 | 
			
		||||
 | 
			
		||||
	struct tty 	 tty;
 | 
			
		||||
 | 
			
		||||
	u_int		 sx;
 | 
			
		||||
	u_int		 sy;
 | 
			
		||||
 | 
			
		||||
#define CLIENT_TERMINAL 0x1
 | 
			
		||||
#define CLIENT_PREFIX 0x2
 | 
			
		||||
#define CLIENT_ATTACHED 0x4
 | 
			
		||||
	int		 flags;
 | 
			
		||||
 | 
			
		||||
	struct session	*session;
 | 
			
		||||
@@ -541,13 +569,8 @@ struct client_ctx {
 | 
			
		||||
	struct buffer	*srv_in;
 | 
			
		||||
	struct buffer	*srv_out;
 | 
			
		||||
 | 
			
		||||
	int		 loc_fd;
 | 
			
		||||
	struct buffer	*loc_in;
 | 
			
		||||
	struct buffer	*loc_out;
 | 
			
		||||
 | 
			
		||||
#define CCTX_PAUSE 0x1
 | 
			
		||||
#define CCTX_DETACH 0x2
 | 
			
		||||
#define CCTX_EXIT 0x4
 | 
			
		||||
#define CCTX_DETACH 0x1
 | 
			
		||||
#define CCTX_EXIT 0x2
 | 
			
		||||
	int 		 flags;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@@ -629,6 +652,28 @@ void		 logfile(const char *);
 | 
			
		||||
void		 siginit(void);
 | 
			
		||||
void		 sigreset(void);
 | 
			
		||||
 | 
			
		||||
/* tty.c */
 | 
			
		||||
void		 tty_init(struct tty *, char *, char *);
 | 
			
		||||
int		 tty_open(struct tty *, char **);
 | 
			
		||||
void		 tty_close(struct tty *);
 | 
			
		||||
void		 tty_free(struct tty *);
 | 
			
		||||
void		 tty_vwrite(struct tty *, int, va_list);
 | 
			
		||||
 | 
			
		||||
/* tty-keys.c */
 | 
			
		||||
int		 tty_keys_cmp(struct tty_key *, struct tty_key *);
 | 
			
		||||
RB_PROTOTYPE(tty_keys, tty_key, entry, tty_keys_cmp);
 | 
			
		||||
void		 tty_keys_init(struct tty *);
 | 
			
		||||
void		 tty_keys_free(struct tty *);
 | 
			
		||||
int		 tty_keys_next(struct tty *, int *);
 | 
			
		||||
 | 
			
		||||
/* tty-write.c */
 | 
			
		||||
void		 tty_write_client(void *, int, ...);
 | 
			
		||||
void		 tty_vwrite_client(void *, int, va_list);
 | 
			
		||||
void		 tty_write_window(void *, int, ...);
 | 
			
		||||
void		 tty_vwrite_window(void *, int, va_list);
 | 
			
		||||
void		 tty_write_session(void *, int, ...);
 | 
			
		||||
void		 tty_vwrite_session(void *, int, va_list);
 | 
			
		||||
 | 
			
		||||
/* cmd.c */
 | 
			
		||||
struct cmd	*cmd_parse(int, char **, char **);
 | 
			
		||||
void		 cmd_exec(struct cmd *, struct cmd_ctx *);
 | 
			
		||||
@@ -708,25 +753,23 @@ void	 server_write_client(
 | 
			
		||||
             struct client *, enum hdrtype, const void *, size_t);
 | 
			
		||||
void	 server_write_session(
 | 
			
		||||
             struct session *, enum hdrtype, const void *, size_t);
 | 
			
		||||
void	 server_write_window_cur(
 | 
			
		||||
void	 server_write_window(
 | 
			
		||||
             struct window *, enum hdrtype, const void *, size_t);
 | 
			
		||||
void	 server_write_window_all(
 | 
			
		||||
             struct window *, enum hdrtype, const void *, size_t);
 | 
			
		||||
void	 server_status_client(struct client *);
 | 
			
		||||
void	 server_clear_client(struct client *);
 | 
			
		||||
void	 server_redraw_client(struct client *);
 | 
			
		||||
void	 server_status_session(struct session *);
 | 
			
		||||
void	 server_status_client(struct client *);
 | 
			
		||||
void	 server_clear_session(struct session *);
 | 
			
		||||
void	 server_redraw_session(struct session *);
 | 
			
		||||
void	 server_status_window_cur(struct window *);
 | 
			
		||||
void	 server_status_window_all(struct window *);
 | 
			
		||||
void	 server_clear_window_cur(struct window *);
 | 
			
		||||
void	 server_clear_window_all(struct window *);
 | 
			
		||||
void	 server_redraw_window_cur(struct window *);
 | 
			
		||||
void	 server_redraw_window_all(struct window *);
 | 
			
		||||
void	 server_status_session(struct session *);
 | 
			
		||||
void	 server_clear_window(struct window *);
 | 
			
		||||
void	 server_redraw_window(struct window *);
 | 
			
		||||
void	 server_status_window(struct window *);
 | 
			
		||||
void printflike2 server_write_message(struct client *, const char *, ...);
 | 
			
		||||
 | 
			
		||||
/* status.c */
 | 
			
		||||
void	 status_write(struct client *c);
 | 
			
		||||
void	 status_write_client(struct client *);
 | 
			
		||||
void	 status_write_session(struct session *);
 | 
			
		||||
void	 status_write_window(struct window *);
 | 
			
		||||
 | 
			
		||||
/* resize.c */
 | 
			
		||||
void	 recalculate_sizes(void);
 | 
			
		||||
@@ -734,17 +777,10 @@ void	 recalculate_sizes(void);
 | 
			
		||||
/* input.c */
 | 
			
		||||
void	 input_init(struct window *);
 | 
			
		||||
void	 input_free(struct window *);
 | 
			
		||||
void	 input_parse(struct window *, struct buffer *);
 | 
			
		||||
uint8_t  input_extract8(struct buffer *);
 | 
			
		||||
uint16_t input_extract16(struct buffer *);
 | 
			
		||||
void	 input_store8(struct buffer *, uint8_t);
 | 
			
		||||
void	 input_store16(struct buffer *, uint16_t);
 | 
			
		||||
void	 input_store_zero(struct buffer *, u_char);
 | 
			
		||||
void	 input_store_one(struct buffer *, u_char, uint16_t);
 | 
			
		||||
void	 input_store_two(struct buffer *, u_char, uint16_t, uint16_t);
 | 
			
		||||
void	 input_parse(struct window *);
 | 
			
		||||
 | 
			
		||||
/* input-key.c */
 | 
			
		||||
void	 input_key(struct buffer *, int);
 | 
			
		||||
void	 input_key(struct window *, int);
 | 
			
		||||
 | 
			
		||||
/* screen-display.c */
 | 
			
		||||
void	 screen_display_make_lines(struct screen *, u_int, u_int);
 | 
			
		||||
@@ -788,15 +824,29 @@ void	 screen_reduce_line(struct screen *, u_int, u_int);
 | 
			
		||||
void	 screen_get_cell(
 | 
			
		||||
    	     struct screen *, u_int, u_int, u_char *, u_char *, u_char *);
 | 
			
		||||
void	 screen_set_cell(struct screen *, u_int, u_int, u_char, u_char, u_char);
 | 
			
		||||
void	 screen_draw_start(struct screen_draw_ctx *,
 | 
			
		||||
    	     struct screen *, struct buffer *, u_int, u_int);
 | 
			
		||||
void	 screen_draw_start_window(
 | 
			
		||||
    	     struct screen_draw_ctx *, struct window *, u_int, u_int);
 | 
			
		||||
void	 screen_draw_start_client(
 | 
			
		||||
    	     struct screen_draw_ctx *, struct client *, u_int, u_int);
 | 
			
		||||
void	 screen_draw_start_session(
 | 
			
		||||
    	     struct screen_draw_ctx *, struct session *, u_int, u_int);
 | 
			
		||||
void	 screen_draw_start(struct screen_draw_ctx *, struct screen *s,
 | 
			
		||||
	     void (*)(void *, int, ...), void *, u_int, u_int);
 | 
			
		||||
void	 screen_draw_stop(struct screen_draw_ctx *);
 | 
			
		||||
void	 screen_draw_set_selection(
 | 
			
		||||
    	     struct screen_draw_ctx *, int, u_int, u_int, u_int, u_int);
 | 
			
		||||
int	 screen_draw_check_selection(struct screen_draw_ctx *, u_int, u_int);
 | 
			
		||||
void	 screen_draw_get_cell(struct screen_draw_ctx *,
 | 
			
		||||
    	     u_int, u_int, u_char *, u_char *, u_char *);
 | 
			
		||||
void	 screen_draw_move(struct screen_draw_ctx *, u_int, u_int);
 | 
			
		||||
void	 screen_draw_insert_characters(struct screen_draw_ctx *, u_int);
 | 
			
		||||
void	 screen_draw_delete_characters(struct screen_draw_ctx *, u_int);
 | 
			
		||||
void	 screen_draw_insert_lines(struct screen_draw_ctx *, u_int);
 | 
			
		||||
void	 screen_draw_delete_lines(struct screen_draw_ctx *, u_int);
 | 
			
		||||
void	 screen_draw_clear_line_to(struct screen_draw_ctx *, u_int);
 | 
			
		||||
void	 screen_draw_clear_screen(struct screen_draw_ctx *);
 | 
			
		||||
void printflike2 screen_draw_write_string(
 | 
			
		||||
	     struct screen_draw_ctx *, const char *, ...);
 | 
			
		||||
void	 screen_draw_move_cursor(struct screen_draw_ctx *, u_int, u_int);
 | 
			
		||||
void	 screen_draw_set_attributes(struct screen_draw_ctx *, u_char, u_char);
 | 
			
		||||
void	 screen_draw_cell(struct screen_draw_ctx *, u_int, u_int);
 | 
			
		||||
void	 screen_draw_cells(struct screen_draw_ctx *, u_int, u_int, u_int);
 | 
			
		||||
@@ -812,12 +862,6 @@ void	 screen_fill_lines(
 | 
			
		||||
void	 screen_fill_cells(
 | 
			
		||||
    	     struct screen *, u_int, u_int, u_int, u_char, u_char, u_char);
 | 
			
		||||
 | 
			
		||||
/* local.c */
 | 
			
		||||
int	 local_init(struct buffer **, struct buffer **);
 | 
			
		||||
void	 local_done(void);
 | 
			
		||||
int	 local_key(void);
 | 
			
		||||
void	 local_output(struct buffer *, size_t);
 | 
			
		||||
 | 
			
		||||
/* window.c */
 | 
			
		||||
extern struct windows windows;
 | 
			
		||||
int		 window_cmp(struct window *, struct window *);
 | 
			
		||||
@@ -835,8 +879,9 @@ struct window	*window_create(
 | 
			
		||||
    		     const char *, const char *, const char **, u_int, u_int);
 | 
			
		||||
void		 window_destroy(struct window *);
 | 
			
		||||
int		 window_resize(struct window *, u_int, u_int);
 | 
			
		||||
void		 window_parse(struct window *, struct buffer *);
 | 
			
		||||
void		 window_draw(struct window *, struct buffer *, u_int, u_int);
 | 
			
		||||
void		 window_parse(struct window *);
 | 
			
		||||
void		 window_draw(
 | 
			
		||||
    		     struct window *, struct screen_draw_ctx *, u_int, u_int);
 | 
			
		||||
void		 window_key(struct window *, int);
 | 
			
		||||
 | 
			
		||||
/* window-copy.c */
 | 
			
		||||
@@ -881,9 +926,14 @@ void		 buffer_insert_range(struct buffer *, size_t, size_t);
 | 
			
		||||
void		 buffer_delete_range(struct buffer *, size_t, size_t);
 | 
			
		||||
void		 buffer_write(struct buffer *, const void *, size_t);
 | 
			
		||||
void		 buffer_read(struct buffer *, void *, size_t);
 | 
			
		||||
void	 	 buffer_write8(struct buffer *, uint8_t);
 | 
			
		||||
void	 	 buffer_write16(struct buffer *, uint16_t);
 | 
			
		||||
uint8_t		 buffer_read8(struct buffer *);
 | 
			
		||||
uint16_t 	 buffer_read16(struct buffer *);
 | 
			
		||||
 | 
			
		||||
/* buffer-poll.c */
 | 
			
		||||
int		 buffer_poll(struct pollfd *, struct buffer *, struct buffer *);
 | 
			
		||||
void		 buffer_flush(int, struct buffer *n, struct buffer *);
 | 
			
		||||
 | 
			
		||||
/* log.c */
 | 
			
		||||
void		 log_open(FILE *, int, int);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										273
									
								
								tty-keys.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										273
									
								
								tty-keys.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,273 @@
 | 
			
		||||
/* $Id: tty-keys.c,v 1.1 2007-11-27 19:23:34 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 <string.h>
 | 
			
		||||
 | 
			
		||||
#include "tmux.h"
 | 
			
		||||
 | 
			
		||||
struct {
 | 
			
		||||
	const char	*name;
 | 
			
		||||
	int	 	 code;
 | 
			
		||||
} tty_keys[] = {
 | 
			
		||||
	{ "kBEG",  KEYC_SBEG },
 | 
			
		||||
	{ "kCAN",  KEYC_SCANCEL },
 | 
			
		||||
	{ "kCMD",  KEYC_SCOMMAND },
 | 
			
		||||
	{ "kCPY",  KEYC_SCOPY },
 | 
			
		||||
	{ "kCRT",  KEYC_SCREATE },
 | 
			
		||||
	{ "kDC",   KEYC_SDC },
 | 
			
		||||
	{ "kDL",   KEYC_SDL },
 | 
			
		||||
	{ "kEND",  KEYC_SEND },
 | 
			
		||||
	{ "kEOL",  KEYC_SEOL },
 | 
			
		||||
	{ "kEXT",  KEYC_SEXIT },
 | 
			
		||||
	{ "kFND",  KEYC_SFIND },
 | 
			
		||||
	{ "kHLP",  KEYC_SHELP },
 | 
			
		||||
	{ "kHOM",  KEYC_SHOME },
 | 
			
		||||
	{ "kIC",   KEYC_SIC },
 | 
			
		||||
	{ "kLFT",  KEYC_SLEFT },
 | 
			
		||||
	{ "kMOV",  KEYC_SMOVE },
 | 
			
		||||
	{ "kMSG",  KEYC_SMESSAGE },
 | 
			
		||||
	{ "kNXT",  KEYC_SNEXT },
 | 
			
		||||
	{ "kOPT",  KEYC_SOPTIONS },
 | 
			
		||||
	{ "kPRT",  KEYC_SPRINT },
 | 
			
		||||
	{ "kPRV",  KEYC_SPREVIOUS },
 | 
			
		||||
	{ "kRDO",  KEYC_SREDO },
 | 
			
		||||
	{ "kRES",  KEYC_SRSUME },
 | 
			
		||||
	{ "kRIT",  KEYC_SRIGHT },
 | 
			
		||||
	{ "kRPL",  KEYC_SREPLACE },
 | 
			
		||||
	{ "kSAV",  KEYC_SSAVE },
 | 
			
		||||
	{ "kSPD",  KEYC_SSUSPEND },
 | 
			
		||||
	{ "kUND",  KEYC_SUNDO },
 | 
			
		||||
	{ "ka1",   KEYC_A1 },
 | 
			
		||||
	{ "ka3",   KEYC_A3 },
 | 
			
		||||
	{ "kb2",   KEYC_B2 },
 | 
			
		||||
	{ "kbeg",  KEYC_BEG },
 | 
			
		||||
	{ "kc1",   KEYC_C1 },
 | 
			
		||||
	{ "kc3",   KEYC_C3 },
 | 
			
		||||
	{ "kcan",  KEYC_CANCEL },
 | 
			
		||||
	{ "kcbt",  KEYC_BTAB },
 | 
			
		||||
	{ "kclo",  KEYC_CLOSE },
 | 
			
		||||
	{ "kclr",  KEYC_CLEAR },
 | 
			
		||||
	{ "kcmd",  KEYC_COMMAND },
 | 
			
		||||
	{ "kcpy",  KEYC_COPY },
 | 
			
		||||
	{ "kcrt",  KEYC_CREATE },
 | 
			
		||||
	{ "kctab", KEYC_CTAB },
 | 
			
		||||
	{ "kcub1", KEYC_LEFT },
 | 
			
		||||
	{ "kcud1", KEYC_DOWN },
 | 
			
		||||
	{ "kcuf1", KEYC_RIGHT },
 | 
			
		||||
	{ "kcuu1", KEYC_UP },
 | 
			
		||||
	{ "kdch1", KEYC_DC },
 | 
			
		||||
	{ "kdl1",  KEYC_DL },
 | 
			
		||||
	{ "ked",   KEYC_EOS },
 | 
			
		||||
	{ "kel",   KEYC_EOL },
 | 
			
		||||
	{ "kend",  KEYC_END },
 | 
			
		||||
	{ "kent",  KEYC_ENTER },
 | 
			
		||||
	{ "kext",  KEYC_EXIT },
 | 
			
		||||
	{ "kf0",   KEYC_F0 },
 | 
			
		||||
	{ "kf1",   KEYC_F1 },
 | 
			
		||||
	{ "kf10",  KEYC_F10 },
 | 
			
		||||
	{ "kf11",  KEYC_F11 },
 | 
			
		||||
	{ "kf12",  KEYC_F12 },
 | 
			
		||||
	{ "kf13",  KEYC_F13 },
 | 
			
		||||
	{ "kf14",  KEYC_F14 },
 | 
			
		||||
	{ "kf15",  KEYC_F15 },
 | 
			
		||||
	{ "kf16",  KEYC_F16 },
 | 
			
		||||
	{ "kf17",  KEYC_F17 },
 | 
			
		||||
	{ "kf18",  KEYC_F18 },
 | 
			
		||||
	{ "kf19",  KEYC_F19 },
 | 
			
		||||
	{ "kf2",   KEYC_F2 },
 | 
			
		||||
	{ "kf20",  KEYC_F20 },
 | 
			
		||||
	{ "kf21",  KEYC_F21 },
 | 
			
		||||
	{ "kf22",  KEYC_F22 },
 | 
			
		||||
	{ "kf23",  KEYC_F23 },
 | 
			
		||||
	{ "kf24",  KEYC_F24 },
 | 
			
		||||
	{ "kf25",  KEYC_F25 },
 | 
			
		||||
	{ "kf26",  KEYC_F26 },
 | 
			
		||||
	{ "kf27",  KEYC_F27 },
 | 
			
		||||
	{ "kf28",  KEYC_F28 },
 | 
			
		||||
	{ "kf29",  KEYC_F29 },
 | 
			
		||||
	{ "kf3",   KEYC_F3 },
 | 
			
		||||
	{ "kf30",  KEYC_F30 },
 | 
			
		||||
	{ "kf31",  KEYC_F31 },
 | 
			
		||||
	{ "kf32",  KEYC_F32 },
 | 
			
		||||
	{ "kf33",  KEYC_F33 },
 | 
			
		||||
	{ "kf34",  KEYC_F34 },
 | 
			
		||||
	{ "kf35",  KEYC_F35 },
 | 
			
		||||
	{ "kf36",  KEYC_F36 },
 | 
			
		||||
	{ "kf37",  KEYC_F37 },
 | 
			
		||||
	{ "kf38",  KEYC_F38 },
 | 
			
		||||
	{ "kf39",  KEYC_F39 },
 | 
			
		||||
	{ "kf4",   KEYC_F4 },
 | 
			
		||||
	{ "kf40",  KEYC_F40 },
 | 
			
		||||
	{ "kf41",  KEYC_F41 },
 | 
			
		||||
	{ "kf42",  KEYC_F42 },
 | 
			
		||||
	{ "kf43",  KEYC_F43 },
 | 
			
		||||
	{ "kf44",  KEYC_F44 },
 | 
			
		||||
	{ "kf45",  KEYC_F45 },
 | 
			
		||||
	{ "kf46",  KEYC_F46 },
 | 
			
		||||
	{ "kf47",  KEYC_F47 },
 | 
			
		||||
	{ "kf48",  KEYC_F48 },
 | 
			
		||||
	{ "kf49",  KEYC_F49 },
 | 
			
		||||
	{ "kf5",   KEYC_F5 },
 | 
			
		||||
	{ "kf50",  KEYC_F50 },
 | 
			
		||||
	{ "kf51",  KEYC_F51 },
 | 
			
		||||
	{ "kf52",  KEYC_F52 },
 | 
			
		||||
	{ "kf53",  KEYC_F53 },
 | 
			
		||||
	{ "kf54",  KEYC_F54 },
 | 
			
		||||
	{ "kf55",  KEYC_F55 },
 | 
			
		||||
	{ "kf56",  KEYC_F56 },
 | 
			
		||||
	{ "kf57",  KEYC_F57 },
 | 
			
		||||
	{ "kf58",  KEYC_F58 },
 | 
			
		||||
	{ "kf59",  KEYC_F59 },
 | 
			
		||||
	{ "kf6",   KEYC_F6 },
 | 
			
		||||
	{ "kf60",  KEYC_F60 },
 | 
			
		||||
	{ "kf61",  KEYC_F61 },
 | 
			
		||||
	{ "kf62",  KEYC_F62 },
 | 
			
		||||
	{ "kf63",  KEYC_F63 },
 | 
			
		||||
	{ "kf7",   KEYC_F7 },
 | 
			
		||||
	{ "kf8",   KEYC_F8 },
 | 
			
		||||
	{ "kf9",   KEYC_F9 },
 | 
			
		||||
	{ "kfnd",  KEYC_FIND },
 | 
			
		||||
	{ "khlp",  KEYC_HELP },
 | 
			
		||||
	{ "khome", KEYC_HOME },
 | 
			
		||||
	{ "khts",  KEYC_STAB },
 | 
			
		||||
	{ "kich1", KEYC_IC },
 | 
			
		||||
	{ "kil1",  KEYC_IL },
 | 
			
		||||
	{ "kind",  KEYC_SF },
 | 
			
		||||
	{ "kll",   KEYC_LL },
 | 
			
		||||
	{ "kmov",  KEYC_MOVE },
 | 
			
		||||
	{ "kmrk",  KEYC_MARK },
 | 
			
		||||
	{ "kmsg",  KEYC_MESSAGE },
 | 
			
		||||
	{ "knp",   KEYC_NPAGE },
 | 
			
		||||
	{ "knxt",  KEYC_NEXT },
 | 
			
		||||
	{ "kopn",  KEYC_OPEN },
 | 
			
		||||
	{ "kopt",  KEYC_OPTIONS },
 | 
			
		||||
	{ "kpp",   KEYC_PPAGE },
 | 
			
		||||
	{ "kprt",  KEYC_PRINT },
 | 
			
		||||
	{ "kprv",  KEYC_PREVIOUS },
 | 
			
		||||
	{ "krdo",  KEYC_REDO },
 | 
			
		||||
	{ "kref",  KEYC_REFERENCE },
 | 
			
		||||
	{ "kres",  KEYC_RESUME },
 | 
			
		||||
	{ "krfr",  KEYC_REFRESH },
 | 
			
		||||
	{ "kri",   KEYC_SR },
 | 
			
		||||
	{ "krmir", KEYC_EIC },
 | 
			
		||||
	{ "krpl",  KEYC_REPLACE },
 | 
			
		||||
	{ "krst",  KEYC_RESTART },
 | 
			
		||||
	{ "ksav",  KEYC_SAVE },
 | 
			
		||||
	{ "kslt",  KEYC_SELECT },
 | 
			
		||||
	{ "kspd",  KEYC_SUSPEND },
 | 
			
		||||
	{ "ktbc",  KEYC_CATAB },
 | 
			
		||||
	{ "kund",  KEYC_UNDO },
 | 
			
		||||
	{ "pmous", KEYC_MOUSE },
 | 
			
		||||
};
 | 
			
		||||
#define NTTYKEYS (sizeof tty_keys / sizeof tty_keys[0])
 | 
			
		||||
 | 
			
		||||
RB_GENERATE(tty_keys, tty_key, entry, tty_keys_cmp);
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
tty_keys_cmp(struct tty_key *k1, struct tty_key *k2)
 | 
			
		||||
{
 | 
			
		||||
	return (strcmp(k1->string, k2->string));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
tty_keys_init(struct tty *tty)
 | 
			
		||||
{
 | 
			
		||||
	struct tty_key	*tk;
 | 
			
		||||
	u_int		 i;
 | 
			
		||||
	char		*s;
 | 
			
		||||
 | 
			
		||||
	RB_INIT(&tty->ktree);
 | 
			
		||||
 | 
			
		||||
	tty->ksize = 0;
 | 
			
		||||
	for (i = 0; i < NTTYKEYS; i++) {
 | 
			
		||||
		s = tigetstr(tty_keys[i].name);
 | 
			
		||||
		if (s == (char *) -1 || s == (char *) 0)
 | 
			
		||||
			continue;
 | 
			
		||||
		if (s[0] != '\e' || s[1] == '\0')
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		tk = xmalloc(sizeof *tk);
 | 
			
		||||
		tk->string = xstrdup(s + 1);
 | 
			
		||||
		tk->code = tty_keys[i].code;
 | 
			
		||||
 | 
			
		||||
		if (strlen(tk->string) > tty->ksize)
 | 
			
		||||
			tty->ksize = strlen(tk->string);
 | 
			
		||||
		RB_INSERT(tty_keys, &tty->ktree, tk);
 | 
			
		||||
 | 
			
		||||
		log_debug("found key %d: size now %zu", tk->code, tty->ksize);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
tty_keys_free(struct tty *tty)
 | 
			
		||||
{
 | 
			
		||||
	struct tty_key	*tk, *tl;
 | 
			
		||||
 | 
			
		||||
	for (tk = RB_MIN(tty_keys, &tty->ktree); tk != NULL; tk = tl) {
 | 
			
		||||
		tl = RB_NEXT(tty_keys, &tty->ktree, tk);
 | 
			
		||||
		RB_REMOVE(tty_keys, &tty->ktree, tk);
 | 
			
		||||
		xfree(tk->string);
 | 
			
		||||
		xfree(tk);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
tty_keys_next(struct tty *tty, int *code)
 | 
			
		||||
{
 | 
			
		||||
	struct tty_key	*tk, tl;
 | 
			
		||||
	size_t		 size;
 | 
			
		||||
	char		*s;
 | 
			
		||||
 | 
			
		||||
	if (BUFFER_USED(tty->in) == 0)
 | 
			
		||||
		return (1);
 | 
			
		||||
	log_debug("keys have %zu bytes", BUFFER_USED(tty->in));
 | 
			
		||||
 | 
			
		||||
	if (*BUFFER_OUT(tty->in) != '\e') {
 | 
			
		||||
		*code = buffer_read8(tty->in);
 | 
			
		||||
		return (0);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	tk = NULL;
 | 
			
		||||
	s = xmalloc(tty->ksize + 1);
 | 
			
		||||
	for (size = tty->ksize; size > 0; size--) {
 | 
			
		||||
		if (size >= BUFFER_USED(tty->in))
 | 
			
		||||
			continue;
 | 
			
		||||
		memcpy(s, BUFFER_OUT(tty->in) + 1, size);
 | 
			
		||||
		s[size] = '\0';
 | 
			
		||||
 | 
			
		||||
		tl.string = s;
 | 
			
		||||
		tk = RB_FIND(tty_keys, &tty->ktree, &tl);
 | 
			
		||||
		if (tk != NULL)
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
	xfree(s);
 | 
			
		||||
	if (tk == NULL) {
 | 
			
		||||
		/* 
 | 
			
		||||
		 * XXX Pass through unchanged.
 | 
			
		||||
		 */
 | 
			
		||||
		*code = '\e';
 | 
			
		||||
		buffer_remove(tty->in, 1);
 | 
			
		||||
		return (0);
 | 
			
		||||
	}
 | 
			
		||||
	buffer_remove(tty->in, size + 1);
 | 
			
		||||
 | 
			
		||||
	*code = tk->code;
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										107
									
								
								tty-write.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								tty-write.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,107 @@
 | 
			
		||||
/* $Id: tty-write.c,v 1.1 2007-11-27 19:23:34 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"
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
tty_write_client(void *ptr, int cmd, ...)
 | 
			
		||||
{
 | 
			
		||||
	struct client	*c = ptr;
 | 
			
		||||
 | 
			
		||||
	va_list	ap;
 | 
			
		||||
 | 
			
		||||
	va_start(ap, cmd);
 | 
			
		||||
	tty_vwrite_client(c, cmd, ap);
 | 
			
		||||
	va_end(ap);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
tty_vwrite_client(void *ptr, int cmd, va_list ap)
 | 
			
		||||
{
 | 
			
		||||
	struct client	*c = ptr;
 | 
			
		||||
 | 
			
		||||
	tty_vwrite(&c->tty, cmd, ap);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
tty_write_window(void *ptr, int cmd, ...)
 | 
			
		||||
{
 | 
			
		||||
	va_list	ap;
 | 
			
		||||
 | 
			
		||||
	va_start(ap, cmd);
 | 
			
		||||
	tty_vwrite_window(ptr, cmd, ap);
 | 
			
		||||
	va_end(ap);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
tty_vwrite_window(void *ptr, int cmd, va_list ap)
 | 
			
		||||
{
 | 
			
		||||
	struct window	*w = ptr;
 | 
			
		||||
	struct client	*c;
 | 
			
		||||
	va_list		 aq;
 | 
			
		||||
	u_int		 i;
 | 
			
		||||
 | 
			
		||||
	if (w->screen.mode & MODE_HIDDEN)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
 | 
			
		||||
		c = ARRAY_ITEM(&clients, i);
 | 
			
		||||
		if (c == NULL || c->session == NULL)
 | 
			
		||||
			continue;
 | 
			
		||||
		if (c->session->curw->window != w)
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		va_copy(aq, ap);	
 | 
			
		||||
		tty_vwrite(&c->tty, cmd, aq);
 | 
			
		||||
		va_end(aq);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
tty_write_session(void *ptr, int cmd, ...)
 | 
			
		||||
{
 | 
			
		||||
	va_list	ap;
 | 
			
		||||
 | 
			
		||||
	va_start(ap, cmd);
 | 
			
		||||
	tty_vwrite_session(ptr, cmd, ap);
 | 
			
		||||
	va_end(ap);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
tty_vwrite_session(void *ptr, int cmd, va_list ap)
 | 
			
		||||
{
 | 
			
		||||
	struct session	*s = ptr;
 | 
			
		||||
	struct client	*c;
 | 
			
		||||
	va_list		 aq;
 | 
			
		||||
	u_int		 i;
 | 
			
		||||
 | 
			
		||||
	if (s->flags & SESSION_UNATTACHED)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
 | 
			
		||||
		c = ARRAY_ITEM(&clients, i);
 | 
			
		||||
		if (c == NULL || c->session != s)
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		va_copy(aq, ap);
 | 
			
		||||
		tty_vwrite(&c->tty, cmd, aq);
 | 
			
		||||
		va_end(aq);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										401
									
								
								tty.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										401
									
								
								tty.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,401 @@
 | 
			
		||||
/* $Id: tty.c,v 1.1 2007-11-27 19:23:34 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 <sys/ioctl.h>
 | 
			
		||||
 | 
			
		||||
#include <curses.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#define TTYDEFCHARS
 | 
			
		||||
/* glibc requires unistd.h before termios.h for TTYDEFCHARS. */
 | 
			
		||||
#include <unistd.h>	
 | 
			
		||||
#include <termios.h>
 | 
			
		||||
 | 
			
		||||
#include "tmux.h"
 | 
			
		||||
 | 
			
		||||
void	tty_fill_acs(struct tty *);
 | 
			
		||||
u_char	tty_get_acs(struct tty *, u_char);
 | 
			
		||||
 | 
			
		||||
void	tty_raw(struct tty *, const char *);
 | 
			
		||||
void	tty_puts(struct tty *, const char *);
 | 
			
		||||
void	tty_putc(struct tty *, char);
 | 
			
		||||
 | 
			
		||||
void	tty_attributes(struct tty *, u_char, u_char);
 | 
			
		||||
char	tty_translate(char);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
tty_init(struct tty *tty, char *path, char *term)
 | 
			
		||||
{
 | 
			
		||||
	tty->path = xstrdup(path);
 | 
			
		||||
	tty->term = xstrdup(term);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
tty_open(struct tty *tty, char **cause)
 | 
			
		||||
{
 | 
			
		||||
	struct termios	 tio;
 | 
			
		||||
	int		 error;
 | 
			
		||||
 | 
			
		||||
	tty->fd = open(tty->path, O_RDWR|O_NONBLOCK);
 | 
			
		||||
	if (tty->fd == -1) {
 | 
			
		||||
		xasprintf(cause, "%s: %s", tty->path, strerror(errno));
 | 
			
		||||
		return (-1);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (tty->term == NULL)
 | 
			
		||||
		tty->term = xstrdup("unknown");
 | 
			
		||||
	if (setupterm(tty->term, tty->fd, &error) != OK) {
 | 
			
		||||
		switch (error) {
 | 
			
		||||
		case 0:
 | 
			
		||||
			xasprintf(cause, "can't use hardcopy terminal");
 | 
			
		||||
			break;
 | 
			
		||||
		case 1:
 | 
			
		||||
			xasprintf(cause, "missing or unsuitable terminal");
 | 
			
		||||
			break;
 | 
			
		||||
		case 2:
 | 
			
		||||
			xasprintf(cause, "can't find terminfo database");
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			xasprintf(cause, "unknown error");
 | 
			
		||||
		}
 | 
			
		||||
		return (-1);
 | 
			
		||||
	}
 | 
			
		||||
	tty->termp = cur_term;
 | 
			
		||||
 | 
			
		||||
	tty->in = buffer_create(BUFSIZ);
 | 
			
		||||
	tty->out = buffer_create(BUFSIZ);
 | 
			
		||||
 | 
			
		||||
	tty->attr = SCREEN_DEFATTR;
 | 
			
		||||
	tty->colr = SCREEN_DEFCOLR;
 | 
			
		||||
 | 
			
		||||
	tty_keys_init(tty);
 | 
			
		||||
	
 | 
			
		||||
	tty_fill_acs(tty);
 | 
			
		||||
 | 
			
		||||
	if (tcgetattr(tty->fd, &tty->tio) != 0)
 | 
			
		||||
		fatal("tcgetattr failed");
 | 
			
		||||
	memset(&tio, 0, sizeof tio);
 | 
			
		||||
	tio.c_iflag = TTYDEF_IFLAG & ~(IXON|IXOFF|ICRNL|INLCR);
 | 
			
		||||
	tio.c_oflag = TTYDEF_OFLAG & ~(OPOST|ONLCR|OCRNL|ONLRET);
 | 
			
		||||
	tio.c_lflag = 
 | 
			
		||||
	    TTYDEF_LFLAG & ~(IEXTEN|ICANON|ECHO|ECHOE|ECHOKE|ECHOCTL|ISIG);
 | 
			
		||||
	tio.c_cflag = TTYDEF_CFLAG;
 | 
			
		||||
	memcpy(&tio.c_cc, ttydefchars, sizeof tio.c_cc);
 | 
			
		||||
	cfsetspeed(&tio, TTYDEF_SPEED);
 | 
			
		||||
	if (tcsetattr(tty->fd, TCSANOW, &tio) != 0)
 | 
			
		||||
		fatal("tcsetattr failed");
 | 
			
		||||
 | 
			
		||||
	if (enter_ca_mode != NULL)
 | 
			
		||||
		tty_puts(tty, enter_ca_mode);
 | 
			
		||||
	if (keypad_xmit != NULL)
 | 
			
		||||
		tty_puts(tty, keypad_xmit);
 | 
			
		||||
	if (ena_acs != NULL)
 | 
			
		||||
		tty_puts(tty, ena_acs);
 | 
			
		||||
	tty_puts(tty, clear_screen);
 | 
			
		||||
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
tty_close(struct tty *tty)
 | 
			
		||||
{
 | 
			
		||||
	struct winsize	ws;
 | 
			
		||||
 | 
			
		||||
	if (ioctl(tty->fd, TIOCGWINSZ, &ws) == -1)
 | 
			
		||||
		fatal("ioctl(TIOCGWINSZ)");
 | 
			
		||||
 | 
			
		||||
	if (keypad_local != NULL)
 | 
			
		||||
		tty_raw(tty, keypad_local);
 | 
			
		||||
	if (exit_ca_mode != NULL)
 | 
			
		||||
		tty_raw(tty, exit_ca_mode);
 | 
			
		||||
	tty_raw(tty, clear_screen);
 | 
			
		||||
	if (cursor_normal != NULL)
 | 
			
		||||
		tty_raw(tty, cursor_normal);
 | 
			
		||||
	if (exit_attribute_mode != NULL)
 | 
			
		||||
		tty_raw(tty, exit_attribute_mode);
 | 
			
		||||
	if (change_scroll_region != NULL)
 | 
			
		||||
		tty_raw(tty, tparm(change_scroll_region, 0, ws.ws_row - 1));
 | 
			
		||||
 | 
			
		||||
	if (tcsetattr(tty->fd, TCSANOW, &tty->tio) != 0)
 | 
			
		||||
		fatal("tcsetattr failed");
 | 
			
		||||
	del_curterm(tty->termp);
 | 
			
		||||
 | 
			
		||||
	tty_keys_free(tty);
 | 
			
		||||
 | 
			
		||||
	close(tty->fd);
 | 
			
		||||
	buffer_destroy(tty->in);
 | 
			
		||||
	buffer_destroy(tty->out);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
tty_free(struct tty *tty)
 | 
			
		||||
{
 | 
			
		||||
	if (tty->fd != -1)
 | 
			
		||||
		tty_close(tty);
 | 
			
		||||
 | 
			
		||||
	if (tty->path != NULL)
 | 
			
		||||
		xfree(tty->path);
 | 
			
		||||
	if (tty->term != NULL)
 | 
			
		||||
		xfree(tty->term);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
tty_fill_acs(struct tty *tty)
 | 
			
		||||
{
 | 
			
		||||
	char	*ptr;
 | 
			
		||||
 | 
			
		||||
	memset(tty->acs, 0, sizeof tty->acs);
 | 
			
		||||
	if (acs_chars == NULL || (strlen(acs_chars) % 2) != 0)
 | 
			
		||||
		return;
 | 
			
		||||
	for (ptr = acs_chars; *ptr != '\0'; ptr += 2)
 | 
			
		||||
		tty->acs[(u_char) ptr[0]] = ptr[1];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
u_char
 | 
			
		||||
tty_get_acs(struct tty *tty, u_char ch)
 | 
			
		||||
{
 | 
			
		||||
	if (tty->acs[ch] != '\0')
 | 
			
		||||
		return (tty->acs[ch]);
 | 
			
		||||
	return (ch);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
tty_raw(struct tty *tty, const char *s)
 | 
			
		||||
{
 | 
			
		||||
	write(tty->fd, s, strlen(s));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
tty_puts(struct tty *tty, const char *s)
 | 
			
		||||
{
 | 
			
		||||
	buffer_write(tty->out, s, strlen(s));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
tty_putc(struct tty *tty, char ch)
 | 
			
		||||
{
 | 
			
		||||
	if (tty->attr & ATTR_DRAWING)
 | 
			
		||||
		ch = tty_get_acs(tty, ch);
 | 
			
		||||
	buffer_write8(tty->out, ch);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
tty_vwrite(struct tty *tty, int cmd, va_list ap)
 | 
			
		||||
{
 | 
			
		||||
	char	ch;
 | 
			
		||||
	u_int	ua, ub;
 | 
			
		||||
 | 
			
		||||
	set_curterm(tty->termp);
 | 
			
		||||
 | 
			
		||||
	switch (cmd) {
 | 
			
		||||
	case TTY_CHARACTER:
 | 
			
		||||
		ch = va_arg(ap, int);
 | 
			
		||||
		switch (ch) {
 | 
			
		||||
		case '\n':	/* LF */
 | 
			
		||||
			tty_puts(tty, cursor_down);
 | 
			
		||||
			break;
 | 
			
		||||
		case '\r':	/* CR */
 | 
			
		||||
			tty_puts(tty, carriage_return);
 | 
			
		||||
			break;
 | 
			
		||||
		case '\007':	/* BEL */
 | 
			
		||||
			if (bell != NULL)
 | 
			
		||||
				tty_puts(tty, bell);
 | 
			
		||||
			break;
 | 
			
		||||
		case '\010':	/* BS */
 | 
			
		||||
			tty_puts(tty, cursor_left);
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			tty_putc(tty, ch);
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
	case TTY_CURSORUP:
 | 
			
		||||
		ua = va_arg(ap, u_int);
 | 
			
		||||
		tty_puts(tty, tparm(parm_up_cursor, ua));
 | 
			
		||||
		break;
 | 
			
		||||
	case TTY_CURSORDOWN:
 | 
			
		||||
		ua = va_arg(ap, u_int);
 | 
			
		||||
		tty_puts(tty, tparm(parm_down_cursor, ua));
 | 
			
		||||
		break;
 | 
			
		||||
	case TTY_CURSORRIGHT:
 | 
			
		||||
		ua = va_arg(ap, u_int);
 | 
			
		||||
		tty_puts(tty, tparm(parm_right_cursor, ua));
 | 
			
		||||
		break;
 | 
			
		||||
	case TTY_CURSORLEFT:
 | 
			
		||||
		ua = va_arg(ap, u_int);
 | 
			
		||||
		tty_puts(tty, tparm(parm_left_cursor, ua));
 | 
			
		||||
		break;
 | 
			
		||||
	case TTY_CURSORMOVE:
 | 
			
		||||
		ua = va_arg(ap, u_int);
 | 
			
		||||
		ub = va_arg(ap, u_int);
 | 
			
		||||
		tty_puts(tty, tparm(cursor_address, ua, ub));
 | 
			
		||||
		break;
 | 
			
		||||
	case TTY_CLEARENDOFLINE:
 | 
			
		||||
		tty_puts(tty, clr_eol);
 | 
			
		||||
		break;
 | 
			
		||||
	case TTY_CLEARSTARTOFLINE:
 | 
			
		||||
		tty_puts(tty, clr_bol);
 | 
			
		||||
		break;
 | 
			
		||||
	case TTY_CLEARLINE:
 | 
			
		||||
		tty_puts(tty, clr_eol);	/* XXX */
 | 
			
		||||
		break;
 | 
			
		||||
	case TTY_INSERTLINE:
 | 
			
		||||
		ua = va_arg(ap, u_int);
 | 
			
		||||
		tty_puts(tty, tparm(parm_insert_line, ua));
 | 
			
		||||
		break;
 | 
			
		||||
	case TTY_DELETELINE:
 | 
			
		||||
		ua = va_arg(ap, u_int);
 | 
			
		||||
		tty_puts(tty, tparm(parm_delete_line, ua));
 | 
			
		||||
		break;
 | 
			
		||||
	case TTY_INSERTCHARACTER:
 | 
			
		||||
		ua = va_arg(ap, u_int);
 | 
			
		||||
		tty_puts(tty, tparm(parm_ich, ua));
 | 
			
		||||
		break;
 | 
			
		||||
	case TTY_DELETECHARACTER:
 | 
			
		||||
		ua = va_arg(ap, u_int);
 | 
			
		||||
		tty_puts(tty, tparm(parm_dch, ua));
 | 
			
		||||
		break;
 | 
			
		||||
	case TTY_CURSORON:
 | 
			
		||||
		if (cursor_normal != NULL)
 | 
			
		||||
			tty_puts(tty, cursor_normal);
 | 
			
		||||
		break;
 | 
			
		||||
	case TTY_CURSOROFF:
 | 
			
		||||
		if (cursor_invisible != NULL)
 | 
			
		||||
			tty_puts(tty, cursor_invisible);
 | 
			
		||||
		break;
 | 
			
		||||
	case TTY_REVERSEINDEX:
 | 
			
		||||
		tty_puts(tty, scroll_reverse);
 | 
			
		||||
		break;
 | 
			
		||||
	case TTY_SCROLLREGION:
 | 
			
		||||
		ua = va_arg(ap, u_int);
 | 
			
		||||
		ub = va_arg(ap, u_int);
 | 
			
		||||
		tty_puts(tty, tparm(change_scroll_region, ua, ub));
 | 
			
		||||
		break;
 | 
			
		||||
	case TTY_INSERTON:
 | 
			
		||||
		if (enter_insert_mode != NULL)
 | 
			
		||||
			tty_puts(tty, enter_insert_mode);
 | 
			
		||||
		break;
 | 
			
		||||
	case TTY_INSERTOFF:
 | 
			
		||||
		if (exit_insert_mode != NULL)
 | 
			
		||||
			tty_puts(tty, exit_insert_mode);
 | 
			
		||||
		break;
 | 
			
		||||
#if 0
 | 
			
		||||
	case TTY_KCURSOROFF:
 | 
			
		||||
		t = tigetstr("CE");
 | 
			
		||||
		if (t != (char *) 0 && t != (char *) -1)
 | 
			
		||||
			tty_puts(tty, t);
 | 
			
		||||
		break;
 | 
			
		||||
	case TTY_KCURSORON:
 | 
			
		||||
		t = tigetstr("CS");
 | 
			
		||||
		if (t != (char *) 0 && t != (char *) -1)
 | 
			
		||||
			tty_puts(tty, t);
 | 
			
		||||
		break;
 | 
			
		||||
	case TTY_KKEYPADOFF:
 | 
			
		||||
		if (keypad_local != NULL)
 | 
			
		||||
			tty_puts(tty, keypad_local);
 | 
			
		||||
		break;
 | 
			
		||||
	case TTY_KKEYPADON:
 | 
			
		||||
		if (keypad_xmit != NULL)
 | 
			
		||||
			tty_puts(tty, keypad_xmit);
 | 
			
		||||
#endif
 | 
			
		||||
		break;
 | 
			
		||||
	case TTY_TITLE:
 | 
			
		||||
		break;
 | 
			
		||||
	case TTY_ATTRIBUTES:
 | 
			
		||||
		ua = va_arg(ap, u_int);
 | 
			
		||||
		ub = va_arg(ap, u_int);
 | 
			
		||||
		tty_attributes(tty, ua, ub);
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
tty_attributes(struct tty *tty, u_char attr, u_char colr)
 | 
			
		||||
{
 | 
			
		||||
	u_char	fg, bg;
 | 
			
		||||
 | 
			
		||||
	if (attr == tty->attr && colr == tty->colr)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	/* If any bits are being cleared, reset everything. */
 | 
			
		||||
	if (tty->attr & ~attr) {
 | 
			
		||||
		if ((tty->attr & ATTR_DRAWING) &&
 | 
			
		||||
		    exit_alt_charset_mode != NULL)
 | 
			
		||||
			tty_puts(tty, exit_alt_charset_mode);
 | 
			
		||||
		tty_puts(tty, exit_attribute_mode);
 | 
			
		||||
		tty->colr = 0x88;
 | 
			
		||||
		tty->attr = 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Filter out bits already set. */
 | 
			
		||||
	attr &= ~tty->attr;
 | 
			
		||||
	tty->attr |= attr;
 | 
			
		||||
 | 
			
		||||
	if ((attr & ATTR_BRIGHT) && enter_bold_mode != NULL)
 | 
			
		||||
		tty_puts(tty, enter_bold_mode);
 | 
			
		||||
	if ((attr & ATTR_DIM) && enter_dim_mode != NULL)
 | 
			
		||||
		tty_puts(tty, enter_dim_mode);
 | 
			
		||||
	if ((attr & ATTR_ITALICS) && enter_standout_mode != NULL)
 | 
			
		||||
		tty_puts(tty, enter_standout_mode);
 | 
			
		||||
	if ((attr & ATTR_UNDERSCORE) && enter_underline_mode != NULL)
 | 
			
		||||
		tty_puts(tty, enter_underline_mode);
 | 
			
		||||
	if ((attr & ATTR_BLINK) && enter_blink_mode != NULL)
 | 
			
		||||
		tty_puts(tty, enter_blink_mode);
 | 
			
		||||
	if ((attr & ATTR_REVERSE) && enter_reverse_mode != NULL)
 | 
			
		||||
		tty_puts(tty, enter_reverse_mode);
 | 
			
		||||
	if ((attr & ATTR_HIDDEN) && enter_secure_mode != NULL)
 | 
			
		||||
		tty_puts(tty, enter_secure_mode);
 | 
			
		||||
	if ((attr & ATTR_DRAWING) && enter_alt_charset_mode != NULL)
 | 
			
		||||
		tty_puts(tty, enter_alt_charset_mode);
 | 
			
		||||
 | 
			
		||||
	fg = (colr >> 4) & 0xf;
 | 
			
		||||
	if (fg != ((tty->colr >> 4) & 0xf)) {
 | 
			
		||||
		if (tigetflag("AX") == TRUE) {
 | 
			
		||||
			if (fg == 7)
 | 
			
		||||
				fg = 8;
 | 
			
		||||
		} else {
 | 
			
		||||
			if (fg == 8)
 | 
			
		||||
				fg = 7;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		if (fg == 8)
 | 
			
		||||
			tty_puts(tty, "\e[39m");
 | 
			
		||||
		else if (set_a_foreground != NULL)
 | 
			
		||||
			tty_puts(tty, tparm(set_a_foreground, fg));
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	bg = colr & 0xf;
 | 
			
		||||
	if (bg != (tty->colr & 0xf)) {
 | 
			
		||||
		if (tigetflag("AX") == TRUE) {
 | 
			
		||||
			if (bg == 0)
 | 
			
		||||
				bg = 8;
 | 
			
		||||
		} else {
 | 
			
		||||
			if (bg == 8)
 | 
			
		||||
				bg = 0;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (bg == 8)
 | 
			
		||||
			tty_puts(tty, "\e[49m");
 | 
			
		||||
		else if (set_a_background != NULL)
 | 
			
		||||
			tty_puts(tty, tparm(set_a_background, bg));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	tty->colr = colr;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										221
									
								
								window-copy.c
									
									
									
									
									
								
							
							
						
						
									
										221
									
								
								window-copy.c
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: window-copy.c,v 1.9 2007-11-26 20:57:54 nicm Exp $ */
 | 
			
		||||
/* $Id: window-copy.c,v 1.10 2007-11-27 19:23:34 nicm Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -24,7 +24,8 @@
 | 
			
		||||
 | 
			
		||||
void	window_copy_init(struct window *);
 | 
			
		||||
void	window_copy_resize(struct window *, u_int, u_int);
 | 
			
		||||
void	window_copy_draw(struct window *, struct buffer *, u_int, u_int);
 | 
			
		||||
void	window_copy_draw(
 | 
			
		||||
    	    struct window *, struct screen_draw_ctx *, u_int, u_int);
 | 
			
		||||
void	window_copy_key(struct window *, int);
 | 
			
		||||
 | 
			
		||||
void	window_copy_draw_position(struct window *, struct screen_draw_ctx *);
 | 
			
		||||
@@ -103,37 +104,32 @@ window_copy_draw_position(struct window *w, struct screen_draw_ctx *ctx)
 | 
			
		||||
	
 | 
			
		||||
	screen_draw_cells(ctx, 0, 0, screen_size_x(ctx->s) - len);
 | 
			
		||||
	
 | 
			
		||||
	screen_draw_move(ctx, screen_size_x(ctx->s) - len, 0);
 | 
			
		||||
	screen_draw_move_cursor(ctx, screen_size_x(ctx->s) - len, 0);
 | 
			
		||||
	screen_draw_set_attributes(ctx, 0, status_colour);
 | 
			
		||||
	buffer_write(ctx->b, ptr, len);
 | 
			
		||||
	screen_draw_write_string(ctx, "%s", ptr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
window_copy_draw(struct window *w, struct buffer *b, u_int py, u_int ny)
 | 
			
		||||
window_copy_draw(
 | 
			
		||||
    struct window *w, struct screen_draw_ctx *ctx, u_int py, u_int ny)
 | 
			
		||||
{
 | 
			
		||||
	struct window_copy_mode_data	*data = w->modedata;
 | 
			
		||||
	struct screen			*s = &w->screen;
 | 
			
		||||
	struct screen_draw_ctx		 ctx;
 | 
			
		||||
 | 
			
		||||
	if (s->hsize != data->size) {
 | 
			
		||||
		data->oy += s->hsize - data->size;
 | 
			
		||||
		data->size = s->hsize;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	screen_draw_start(&ctx, s, b, data->ox, data->oy);
 | 
			
		||||
	screen_draw_set_selection(&ctx, data->selflag, data->selx, data->sely,
 | 
			
		||||
	    data->cx + data->ox, data->size + data->cy - data->oy);
 | 
			
		||||
	if (py != 0)
 | 
			
		||||
		screen_draw_lines(&ctx, py, ny);
 | 
			
		||||
	else if (ny > 1)
 | 
			
		||||
		screen_draw_lines(&ctx, py + 1, ny - 1);
 | 
			
		||||
		screen_draw_lines(ctx, py, ny);
 | 
			
		||||
	else {
 | 
			
		||||
		if (ny > 1)
 | 
			
		||||
			screen_draw_lines(ctx, py + 1, ny - 1);
 | 
			
		||||
		window_copy_draw_position(w, ctx);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (py == 0)
 | 
			
		||||
		window_copy_draw_position(w, &ctx);
 | 
			
		||||
 | 
			
		||||
	screen_draw_stop(&ctx);
 | 
			
		||||
 | 
			
		||||
	input_store_two(b, CODE_CURSORMOVE, data->cy + 1, data->cx  + 1);
 | 
			
		||||
	window_copy_move_cursor(w);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -205,7 +201,7 @@ window_copy_key(struct window *w, int key)
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	if (data->oy != oy) {
 | 
			
		||||
		server_redraw_window_all(w);
 | 
			
		||||
		server_redraw_window(w);
 | 
			
		||||
		window_copy_move_cursor(w);
 | 
			
		||||
	}
 | 
			
		||||
	return;
 | 
			
		||||
@@ -217,7 +213,7 @@ done:
 | 
			
		||||
	w->screen.mode &= ~MODE_BACKGROUND;
 | 
			
		||||
	
 | 
			
		||||
	recalculate_sizes();
 | 
			
		||||
	server_redraw_window_all(w);
 | 
			
		||||
	server_redraw_window(w);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -322,30 +318,8 @@ void
 | 
			
		||||
window_copy_move_cursor(struct window *w)
 | 
			
		||||
{
 | 
			
		||||
	struct window_copy_mode_data	*data = w->modedata;
 | 
			
		||||
	struct client			*c;
 | 
			
		||||
	u_int		 		 i;
 | 
			
		||||
	struct hdr			 hdr;
 | 
			
		||||
	size_t				 size;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
 | 
			
		||||
		c = ARRAY_ITEM(&clients, i);
 | 
			
		||||
		if (c == NULL || c->session == NULL)
 | 
			
		||||
			continue;
 | 
			
		||||
		if (!session_has(c->session, w))
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		buffer_ensure(c->out, sizeof hdr);
 | 
			
		||||
		buffer_add(c->out, sizeof hdr);
 | 
			
		||||
		size = BUFFER_USED(c->out);
 | 
			
		||||
 | 
			
		||||
		input_store_two(
 | 
			
		||||
		    c->out, CODE_CURSORMOVE, data->cy + 1, data->cx + 1);
 | 
			
		||||
 | 
			
		||||
		size = BUFFER_USED(c->out) - size;
 | 
			
		||||
		hdr.type = MSG_DATA;
 | 
			
		||||
		hdr.size = size;
 | 
			
		||||
		memcpy(BUFFER_IN(c->out) - size - sizeof hdr, &hdr, sizeof hdr);
 | 
			
		||||
	}
 | 
			
		||||
	tty_write_window(w, TTY_CURSORMOVE, data->cy, data->cx);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -467,44 +441,20 @@ window_copy_cursor_down(struct window *w)
 | 
			
		||||
void
 | 
			
		||||
window_copy_draw_lines(struct window *w, u_int py, u_int ny)
 | 
			
		||||
{
 | 
			
		||||
	struct client		*c;
 | 
			
		||||
	struct buffer		*b;
 | 
			
		||||
	u_int		 	 i;
 | 
			
		||||
	struct hdr		 hdr;
 | 
			
		||||
	size_t			 size;
 | 
			
		||||
	struct window_copy_mode_data	*data = w->modedata;
 | 
			
		||||
	struct screen_draw_ctx		 ctx;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
 | 
			
		||||
		c = ARRAY_ITEM(&clients, i);
 | 
			
		||||
		if (c == NULL || c->session == NULL)
 | 
			
		||||
			continue;
 | 
			
		||||
		if (!session_has(c->session, w))
 | 
			
		||||
			continue;
 | 
			
		||||
		b = c->out;
 | 
			
		||||
 | 
			
		||||
		buffer_ensure(b, sizeof hdr);
 | 
			
		||||
		buffer_add(b, sizeof hdr);
 | 
			
		||||
		size = BUFFER_USED(b);
 | 
			
		||||
		
 | 
			
		||||
		window_copy_draw(w, b, py, ny);
 | 
			
		||||
 | 
			
		||||
		size = BUFFER_USED(b) - size;
 | 
			
		||||
		hdr.type = MSG_DATA;
 | 
			
		||||
		hdr.size = size;
 | 
			
		||||
		memcpy(BUFFER_IN(b) - size - sizeof hdr, &hdr, sizeof hdr);
 | 
			
		||||
	}	
 | 
			
		||||
	screen_draw_start_window(&ctx, w, data->ox, data->oy);
 | 
			
		||||
	window_copy_draw(w, &ctx, py, ny);
 | 
			
		||||
	screen_draw_stop(&ctx);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
window_copy_scroll_left(struct window *w, u_int nx)
 | 
			
		||||
{
 | 
			
		||||
	struct window_copy_mode_data	*data = w->modedata;
 | 
			
		||||
	struct screen			*s = &w->screen;
 | 
			
		||||
	struct screen_draw_ctx		 ctx;
 | 
			
		||||
	struct client			*c;
 | 
			
		||||
	struct buffer			*b;
 | 
			
		||||
	u_int		 		 i, j;
 | 
			
		||||
	struct hdr			 hdr;
 | 
			
		||||
	size_t				 size;
 | 
			
		||||
	u_int				 i;
 | 
			
		||||
 | 
			
		||||
	if (data->ox > SHRT_MAX - nx)
 | 
			
		||||
		nx = SHRT_MAX - data->ox;
 | 
			
		||||
@@ -512,49 +462,26 @@ window_copy_scroll_left(struct window *w, u_int nx)
 | 
			
		||||
		return;
 | 
			
		||||
	data->ox += nx;
 | 
			
		||||
	
 | 
			
		||||
	for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
 | 
			
		||||
		c = ARRAY_ITEM(&clients, i);
 | 
			
		||||
		if (c == NULL || c->session == NULL)
 | 
			
		||||
			continue;
 | 
			
		||||
		if (!session_has(c->session, w))
 | 
			
		||||
			continue;
 | 
			
		||||
		b = c->out;
 | 
			
		||||
 | 
			
		||||
		buffer_ensure(b, sizeof hdr);
 | 
			
		||||
		buffer_add(b, sizeof hdr);
 | 
			
		||||
		size = BUFFER_USED(b);
 | 
			
		||||
		
 | 
			
		||||
		screen_draw_start(&ctx, s, b, data->ox, data->oy);
 | 
			
		||||
	screen_draw_start_window(&ctx, w, data->ox, data->oy);
 | 
			
		||||
	screen_draw_set_selection(&ctx,
 | 
			
		||||
	    data->selflag, data->selx, data->sely,
 | 
			
		||||
	    data->cx + data->ox, data->size + data->cy - data->oy);
 | 
			
		||||
		for (j = 1; j < screen_size_y(s); j++) {
 | 
			
		||||
			screen_draw_move(&ctx, 0, j);
 | 
			
		||||
			input_store_one(b, CODE_DELETECHARACTER, nx);
 | 
			
		||||
	for (i = 1; i < screen_size_y(&w->screen); i++) {
 | 
			
		||||
		screen_draw_move_cursor(&ctx, 0, i);
 | 
			
		||||
 		screen_draw_delete_characters(&ctx, nx);
 | 
			
		||||
	}
 | 
			
		||||
		for (j = 0; j < nx; j++)
 | 
			
		||||
			screen_draw_column(&ctx, screen_last_x(s) - j);
 | 
			
		||||
	for (i = 0; i < nx; i++)
 | 
			
		||||
		screen_draw_column(&ctx, screen_last_x(&w->screen) - i);
 | 
			
		||||
	window_copy_draw_position(w, &ctx);
 | 
			
		||||
	screen_draw_stop(&ctx);
 | 
			
		||||
		
 | 
			
		||||
		size = BUFFER_USED(b) - size;
 | 
			
		||||
		hdr.type = MSG_DATA;
 | 
			
		||||
		hdr.size = size;
 | 
			
		||||
		memcpy(BUFFER_IN(b) - size - sizeof hdr, &hdr, sizeof hdr);
 | 
			
		||||
	}	
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
window_copy_scroll_right(struct window *w, u_int nx)
 | 
			
		||||
{
 | 
			
		||||
	struct window_copy_mode_data	*data = w->modedata;
 | 
			
		||||
	struct screen			*s = &w->screen;
 | 
			
		||||
	struct screen_draw_ctx		 ctx;
 | 
			
		||||
	struct client			*c;
 | 
			
		||||
	struct buffer			*b;
 | 
			
		||||
	u_int		 		 i, j;
 | 
			
		||||
	struct hdr			 hdr;
 | 
			
		||||
	size_t				 size;
 | 
			
		||||
	u_int		 		 i;
 | 
			
		||||
 | 
			
		||||
	if (data->ox < nx)
 | 
			
		||||
		nx = data->ox;
 | 
			
		||||
@@ -562,48 +489,26 @@ window_copy_scroll_right(struct window *w, u_int nx)
 | 
			
		||||
		return;
 | 
			
		||||
	data->ox -= nx;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
 | 
			
		||||
		c = ARRAY_ITEM(&clients, i);
 | 
			
		||||
		if (c == NULL || c->session == NULL)
 | 
			
		||||
			continue;
 | 
			
		||||
		if (!session_has(c->session, w))
 | 
			
		||||
			continue;
 | 
			
		||||
		b = c->out;
 | 
			
		||||
 | 
			
		||||
		buffer_ensure(b, sizeof hdr);
 | 
			
		||||
		buffer_add(b, sizeof hdr);
 | 
			
		||||
		size = BUFFER_USED(b);
 | 
			
		||||
		
 | 
			
		||||
		screen_draw_start(&ctx, s, b, data->ox, data->oy);
 | 
			
		||||
	screen_draw_start_window(&ctx, w, data->ox, data->oy);
 | 
			
		||||
	screen_draw_set_selection(&ctx,
 | 
			
		||||
	    data->selflag, data->selx, data->sely,
 | 
			
		||||
	    data->cx + data->ox, data->size + data->cy - data->oy);
 | 
			
		||||
		for (j = 1; j < screen_size_y(s); j++) {
 | 
			
		||||
			screen_draw_move(&ctx, 0, j);
 | 
			
		||||
			input_store_one(b, CODE_INSERTCHARACTER, nx);
 | 
			
		||||
	for (i = 1; i < screen_size_y(&w->screen); i++) {
 | 
			
		||||
		screen_draw_move_cursor(&ctx, 0, i);
 | 
			
		||||
 		screen_draw_insert_characters(&ctx, nx);
 | 
			
		||||
	}
 | 
			
		||||
		for (j = 0; j < nx; j++)
 | 
			
		||||
			screen_draw_column(&ctx, j);
 | 
			
		||||
	for (i = 0; i < nx; i++)
 | 
			
		||||
		screen_draw_column(&ctx, i);
 | 
			
		||||
	window_copy_draw_position(w, &ctx);
 | 
			
		||||
	screen_draw_stop(&ctx);
 | 
			
		||||
		
 | 
			
		||||
		size = BUFFER_USED(b) - size;
 | 
			
		||||
		hdr.type = MSG_DATA;
 | 
			
		||||
		hdr.size = size;
 | 
			
		||||
		memcpy(BUFFER_IN(b) - size - sizeof hdr, &hdr, sizeof hdr);
 | 
			
		||||
	}	
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
window_copy_scroll_up(struct window *w, u_int ny)
 | 
			
		||||
{
 | 
			
		||||
	struct window_copy_mode_data	*data = w->modedata;
 | 
			
		||||
	struct screen			*s = &w->screen;
 | 
			
		||||
	struct screen_draw_ctx		 ctx;
 | 
			
		||||
	struct client			*c;
 | 
			
		||||
	u_int		 		 i;
 | 
			
		||||
	struct hdr			 hdr;
 | 
			
		||||
	size_t				 size;
 | 
			
		||||
 | 
			
		||||
	if (data->oy < ny)
 | 
			
		||||
		ny = data->oy;
 | 
			
		||||
@@ -611,47 +516,26 @@ window_copy_scroll_up(struct window *w, u_int ny)
 | 
			
		||||
		return;
 | 
			
		||||
	data->oy -= ny;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
 | 
			
		||||
		c = ARRAY_ITEM(&clients, i);
 | 
			
		||||
		if (c == NULL || c->session == NULL)
 | 
			
		||||
			continue;
 | 
			
		||||
		if (!session_has(c->session, w))
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		buffer_ensure(c->out, sizeof hdr);
 | 
			
		||||
		buffer_add(c->out, sizeof hdr);
 | 
			
		||||
		size = BUFFER_USED(c->out);
 | 
			
		||||
		
 | 
			
		||||
		screen_draw_start(&ctx, s, c->out, data->ox, data->oy);
 | 
			
		||||
	screen_draw_start_window(&ctx, w, data->ox, data->oy);
 | 
			
		||||
	screen_draw_set_selection(&ctx,
 | 
			
		||||
	    data->selflag, data->selx, data->sely,
 | 
			
		||||
	    data->cx + data->ox, data->size + data->cy - data->oy);
 | 
			
		||||
		screen_draw_move(&ctx, 0, 0);
 | 
			
		||||
		input_store_one(c->out, CODE_DELETELINE, ny);
 | 
			
		||||
	screen_draw_move_cursor(&ctx, 0, 0);
 | 
			
		||||
	screen_draw_delete_lines(&ctx, ny);
 | 
			
		||||
	for (i = 0; i < ny; i++)
 | 
			
		||||
			screen_draw_line(&ctx, screen_last_y(s) - i);
 | 
			
		||||
		screen_draw_line(&ctx, screen_last_y(&w->screen) - i);
 | 
			
		||||
	if (data->selflag)
 | 
			
		||||
			screen_draw_line(&ctx, screen_last_y(s) - ny);
 | 
			
		||||
		screen_draw_line(&ctx, screen_last_y(&w->screen) - ny);
 | 
			
		||||
	window_copy_draw_position(w, &ctx);
 | 
			
		||||
	screen_draw_stop(&ctx);
 | 
			
		||||
		
 | 
			
		||||
		size = BUFFER_USED(c->out) - size;
 | 
			
		||||
		hdr.type = MSG_DATA;
 | 
			
		||||
		hdr.size = size;
 | 
			
		||||
		memcpy(BUFFER_IN(c->out) - size - sizeof hdr, &hdr, sizeof hdr);
 | 
			
		||||
	}	
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
window_copy_scroll_down(struct window *w, u_int ny)
 | 
			
		||||
{
 | 
			
		||||
	struct window_copy_mode_data	*data = w->modedata;
 | 
			
		||||
	struct screen			*s = &w->screen;
 | 
			
		||||
	struct screen_draw_ctx		 ctx;
 | 
			
		||||
	struct client			*c;
 | 
			
		||||
	u_int		 		 i;
 | 
			
		||||
	struct hdr			 hdr;
 | 
			
		||||
	size_t				 size;
 | 
			
		||||
 | 
			
		||||
	if (ny > data->size)
 | 
			
		||||
		return;
 | 
			
		||||
@@ -662,31 +546,14 @@ window_copy_scroll_down(struct window *w, u_int ny)
 | 
			
		||||
		return;
 | 
			
		||||
	data->oy += ny;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
 | 
			
		||||
		c = ARRAY_ITEM(&clients, i);
 | 
			
		||||
		if (c == NULL || c->session == NULL)
 | 
			
		||||
			continue;
 | 
			
		||||
		if (!session_has(c->session, w))
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		buffer_ensure(c->out, sizeof hdr);
 | 
			
		||||
		buffer_add(c->out, sizeof hdr);
 | 
			
		||||
		size = BUFFER_USED(c->out);
 | 
			
		||||
 | 
			
		||||
		screen_draw_start(&ctx, s, c->out, data->ox, data->oy);
 | 
			
		||||
	screen_draw_start_window(&ctx, w, data->ox, data->oy);
 | 
			
		||||
	screen_draw_set_selection(&ctx,
 | 
			
		||||
	    data->selflag, data->selx, data->sely,
 | 
			
		||||
	    data->cx + data->ox, data->size + data->cy - data->oy);
 | 
			
		||||
		screen_draw_move(&ctx, 0, 0);
 | 
			
		||||
		input_store_one(c->out, CODE_INSERTLINE, ny);
 | 
			
		||||
	screen_draw_move_cursor(&ctx, 0, 0);
 | 
			
		||||
	screen_draw_insert_lines(&ctx, ny);
 | 
			
		||||
	for (i = 1; i < ny + 1; i++)
 | 
			
		||||
		screen_draw_line(&ctx, i);
 | 
			
		||||
	window_copy_draw_position(w, &ctx);
 | 
			
		||||
	screen_draw_stop(&ctx);
 | 
			
		||||
 | 
			
		||||
		size = BUFFER_USED(c->out) - size;
 | 
			
		||||
		hdr.type = MSG_DATA;
 | 
			
		||||
		hdr.size = size;
 | 
			
		||||
		memcpy(BUFFER_IN(c->out) - size - sizeof hdr, &hdr, sizeof hdr);
 | 
			
		||||
	}	
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										122
									
								
								window-more.c
									
									
									
									
									
								
							
							
						
						
									
										122
									
								
								window-more.c
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: window-more.c,v 1.4 2007-11-22 18:09:43 nicm Exp $ */
 | 
			
		||||
/* $Id: window-more.c,v 1.5 2007-11-27 19:23:34 nicm Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -24,7 +24,8 @@
 | 
			
		||||
 | 
			
		||||
void	window_more_init(struct window *);
 | 
			
		||||
void	window_more_resize(struct window *, u_int, u_int);
 | 
			
		||||
void	window_more_draw(struct window *, struct buffer *, u_int, u_int);
 | 
			
		||||
void	window_more_draw(
 | 
			
		||||
    	    struct window *, struct screen_draw_ctx *, u_int, u_int);
 | 
			
		||||
void	window_more_key(struct window *, int);
 | 
			
		||||
 | 
			
		||||
void	window_more_draw_position(struct window *, struct screen_draw_ctx *);
 | 
			
		||||
@@ -90,8 +91,6 @@ window_more_draw_position(struct window *w, struct screen_draw_ctx *ctx)
 | 
			
		||||
	char				*ptr, buf[32];
 | 
			
		||||
	size_t	 			 len;
 | 
			
		||||
	char				*line;
 | 
			
		||||
	size_t				 n;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	len = xsnprintf(
 | 
			
		||||
	    buf, sizeof buf, "[%u/%u]", data->top, ARRAY_LENGTH(&data->list));
 | 
			
		||||
@@ -102,68 +101,50 @@ window_more_draw_position(struct window *w, struct screen_draw_ctx *ctx)
 | 
			
		||||
		len -= len - screen_size_x(ctx->s);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	screen_draw_move(ctx, 0, 0);
 | 
			
		||||
	screen_draw_move_cursor(ctx, 0, 0);
 | 
			
		||||
 | 
			
		||||
	if (data->top < ARRAY_LENGTH(&data->list)) {
 | 
			
		||||
		line = ARRAY_ITEM(&data->list, data->top);
 | 
			
		||||
		n = strlen(line);
 | 
			
		||||
		if (n > screen_size_x(ctx->s) - len)
 | 
			
		||||
			n = screen_size_x(ctx->s) - len;
 | 
			
		||||
		buffer_write(ctx->b, line, n);
 | 
			
		||||
	} else
 | 
			
		||||
		n = 0;
 | 
			
		||||
	for (; n < screen_size_x(ctx->s) - len; n++)
 | 
			
		||||
		input_store8(ctx->b, SCREEN_DEFDATA);
 | 
			
		||||
		line = xstrdup(ARRAY_ITEM(&data->list, data->top));
 | 
			
		||||
		if (strlen(line) > screen_size_x(ctx->s) - len)
 | 
			
		||||
			line[screen_size_x(ctx->s) - len] = '\0';
 | 
			
		||||
		screen_draw_write_string(ctx, "%s", line);
 | 
			
		||||
		xfree(line);
 | 
			
		||||
	}
 | 
			
		||||
	screen_draw_clear_line_to(ctx, screen_size_x(ctx->s) - len - 1);
 | 
			
		||||
 | 
			
		||||
	screen_draw_move(ctx, screen_size_x(ctx->s) - len, 0);
 | 
			
		||||
	screen_draw_move_cursor(ctx, screen_size_x(ctx->s) - len, 0);
 | 
			
		||||
	screen_draw_set_attributes(ctx, 0, status_colour);
 | 
			
		||||
	buffer_write(ctx->b, buf, len);
 | 
			
		||||
	screen_draw_write_string(ctx, "%s", ptr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
window_more_draw_line(struct window *w, struct screen_draw_ctx *ctx, u_int py)
 | 
			
		||||
{
 | 
			
		||||
	struct window_more_mode_data	*data = w->modedata;
 | 
			
		||||
	char				*line;
 | 
			
		||||
	size_t				 n;
 | 
			
		||||
	u_int				 p;
 | 
			
		||||
 | 
			
		||||
	screen_draw_move(ctx, 0, py);
 | 
			
		||||
	screen_draw_move_cursor(ctx, 0, py);
 | 
			
		||||
	screen_draw_set_attributes(ctx, SCREEN_DEFATTR, SCREEN_DEFCOLR);
 | 
			
		||||
	
 | 
			
		||||
	p = data->top + py;
 | 
			
		||||
	if (p >= ARRAY_LENGTH(&data->list)) {
 | 
			
		||||
		input_store_zero(ctx->b, CODE_CLEARLINE);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	if (p < ARRAY_LENGTH(&data->list))
 | 
			
		||||
		screen_draw_write_string(ctx, "%s", ARRAY_ITEM(&data->list, p));
 | 
			
		||||
 | 
			
		||||
	line = ARRAY_ITEM(&data->list, p);
 | 
			
		||||
	n = strlen(line);
 | 
			
		||||
	if (n > screen_size_x(ctx->s))
 | 
			
		||||
		n = screen_size_x(ctx->s);
 | 
			
		||||
	buffer_write(ctx->b, line, n);
 | 
			
		||||
	for (; n < screen_size_x(ctx->s); n++)
 | 
			
		||||
		input_store8(ctx->b, SCREEN_DEFDATA);
 | 
			
		||||
	screen_draw_clear_line_to(ctx, screen_last_x(ctx->s));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
window_more_draw(struct window *w, struct buffer *b, u_int py, u_int ny)
 | 
			
		||||
window_more_draw(
 | 
			
		||||
    struct window *w, struct screen_draw_ctx *ctx, u_int py, u_int ny)
 | 
			
		||||
{
 | 
			
		||||
	struct screen			*s = &w->screen;
 | 
			
		||||
	struct screen_draw_ctx		 ctx;
 | 
			
		||||
	u_int	i;
 | 
			
		||||
 | 
			
		||||
	screen_draw_start(&ctx, s, b, 0, 0);
 | 
			
		||||
 | 
			
		||||
	for (i = py; i < py + ny; i++) {
 | 
			
		||||
		if (i == 0)
 | 
			
		||||
			continue;
 | 
			
		||||
		window_more_draw_line(w, &ctx, i);
 | 
			
		||||
			window_more_draw_position(w, ctx);
 | 
			
		||||
		else
 | 
			
		||||
			window_more_draw_line(w, ctx, i);
 | 
			
		||||
	}
 | 
			
		||||
	if (py == 0)
 | 
			
		||||
		window_more_draw_position(w, &ctx);
 | 
			
		||||
 | 
			
		||||
	screen_draw_stop(&ctx);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -189,7 +170,7 @@ window_more_key(struct window *w, int key)
 | 
			
		||||
		w->screen.mode &= ~MODE_BACKGROUND;
 | 
			
		||||
 | 
			
		||||
		recalculate_sizes();
 | 
			
		||||
		server_redraw_window_all(w);
 | 
			
		||||
		server_redraw_window(w);
 | 
			
		||||
		return;
 | 
			
		||||
	case 'k':
 | 
			
		||||
	case 'K':
 | 
			
		||||
@@ -217,47 +198,25 @@ window_more_key(struct window *w, int key)
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
	if (top != data->top)
 | 
			
		||||
		server_redraw_window_all(w);
 | 
			
		||||
		server_redraw_window(w);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
window_more_up_1(struct window *w)
 | 
			
		||||
{
 | 
			
		||||
	struct window_more_mode_data	*data = w->modedata;
 | 
			
		||||
	struct screen			*s = &w->screen;
 | 
			
		||||
	struct screen_draw_ctx		 ctx;
 | 
			
		||||
	struct client			*c;
 | 
			
		||||
	u_int		 		 i;
 | 
			
		||||
	struct hdr			 hdr;
 | 
			
		||||
	size_t				 size;
 | 
			
		||||
 | 
			
		||||
	if (data->top == 0)
 | 
			
		||||
		return;
 | 
			
		||||
	data->top--;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
 | 
			
		||||
		c = ARRAY_ITEM(&clients, i);
 | 
			
		||||
		if (c == NULL || c->session == NULL)
 | 
			
		||||
			continue;
 | 
			
		||||
		if (!session_has(c->session, w))
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		buffer_ensure(c->out, sizeof hdr);
 | 
			
		||||
		buffer_add(c->out, sizeof hdr);
 | 
			
		||||
		size = BUFFER_USED(c->out);
 | 
			
		||||
 | 
			
		||||
		screen_draw_start(&ctx, s, c->out, 0, 0);
 | 
			
		||||
		screen_draw_move(&ctx, 0, 0);
 | 
			
		||||
		input_store_one(c->out, CODE_INSERTLINE, 1);
 | 
			
		||||
	screen_draw_start_window(&ctx, w, 0, 0);
 | 
			
		||||
	screen_draw_move_cursor(&ctx, 0, 0);
 | 
			
		||||
	screen_draw_insert_lines(&ctx, 1);
 | 
			
		||||
	window_more_draw_position(w, &ctx);
 | 
			
		||||
	window_more_draw_line(w, &ctx, 1);
 | 
			
		||||
	screen_draw_stop(&ctx);
 | 
			
		||||
 | 
			
		||||
		size = BUFFER_USED(c->out) - size;
 | 
			
		||||
		hdr.type = MSG_DATA;
 | 
			
		||||
		hdr.size = size;
 | 
			
		||||
		memcpy(BUFFER_IN(c->out) - size - sizeof hdr, &hdr, sizeof hdr);
 | 
			
		||||
	}	
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -266,36 +225,15 @@ window_more_down_1(struct window *w)
 | 
			
		||||
	struct window_more_mode_data	*data = w->modedata;
 | 
			
		||||
	struct screen			*s = &w->screen;
 | 
			
		||||
	struct screen_draw_ctx		 ctx;
 | 
			
		||||
	struct client			*c;
 | 
			
		||||
	u_int		 		 i;
 | 
			
		||||
	struct hdr			 hdr;
 | 
			
		||||
	size_t				 size;
 | 
			
		||||
 | 
			
		||||
	if (data->top >= ARRAY_LENGTH(&data->list))
 | 
			
		||||
		return;
 | 
			
		||||
	data->top++;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
 | 
			
		||||
		c = ARRAY_ITEM(&clients, i);
 | 
			
		||||
		if (c == NULL || c->session == NULL)
 | 
			
		||||
			continue;
 | 
			
		||||
		if (!session_has(c->session, w))
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		buffer_ensure(c->out, sizeof hdr);
 | 
			
		||||
		buffer_add(c->out, sizeof hdr);
 | 
			
		||||
		size = BUFFER_USED(c->out);
 | 
			
		||||
		
 | 
			
		||||
		screen_draw_start(&ctx, s, c->out, 0, 0);
 | 
			
		||||
		screen_draw_move(&ctx, 0, 0);
 | 
			
		||||
		input_store_one(c->out, CODE_DELETELINE, 1);
 | 
			
		||||
	screen_draw_start_window(&ctx, w, 0, 0);
 | 
			
		||||
	screen_draw_move_cursor(&ctx, 0, 0);
 | 
			
		||||
	screen_draw_delete_lines(&ctx, 1);
 | 
			
		||||
	window_more_draw_line(w, &ctx, screen_last_y(s));
 | 
			
		||||
	window_more_draw_position(w, &ctx);
 | 
			
		||||
	screen_draw_stop(&ctx);
 | 
			
		||||
		
 | 
			
		||||
		size = BUFFER_USED(c->out) - size;
 | 
			
		||||
		hdr.type = MSG_DATA;
 | 
			
		||||
		hdr.size = size;
 | 
			
		||||
		memcpy(BUFFER_IN(c->out) - size - sizeof hdr, &hdr, sizeof hdr);
 | 
			
		||||
	}	
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										154
									
								
								window-scroll.c
									
									
									
									
									
								
							
							
						
						
									
										154
									
								
								window-scroll.c
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: window-scroll.c,v 1.12 2007-11-22 18:09:43 nicm Exp $ */
 | 
			
		||||
/* $Id: window-scroll.c,v 1.13 2007-11-27 19:23:34 nicm Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -24,7 +24,8 @@
 | 
			
		||||
 | 
			
		||||
void	window_scroll_init(struct window *);
 | 
			
		||||
void	window_scroll_resize(struct window *, u_int, u_int);
 | 
			
		||||
void	window_scroll_draw(struct window *, struct buffer *, u_int, u_int);
 | 
			
		||||
void	window_scroll_draw(
 | 
			
		||||
    	    struct window *, struct screen_draw_ctx *, u_int, u_int);
 | 
			
		||||
void	window_scroll_key(struct window *, int);
 | 
			
		||||
 | 
			
		||||
void	window_scroll_draw_position(struct window *, struct screen_draw_ctx *);
 | 
			
		||||
@@ -83,33 +84,29 @@ window_scroll_draw_position(struct window *w, struct screen_draw_ctx *ctx)
 | 
			
		||||
	
 | 
			
		||||
	screen_draw_cells(ctx, 0, 0, screen_size_x(ctx->s) - len);
 | 
			
		||||
	
 | 
			
		||||
	screen_draw_move(ctx, screen_size_x(ctx->s) - len, 0);
 | 
			
		||||
	screen_draw_move_cursor(ctx, screen_size_x(ctx->s) - len, 0);
 | 
			
		||||
	screen_draw_set_attributes(ctx, 0, status_colour);
 | 
			
		||||
	buffer_write(ctx->b, ptr, len);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
window_scroll_draw(struct window *w, struct buffer *b, u_int py, u_int ny)
 | 
			
		||||
window_scroll_draw(
 | 
			
		||||
    struct window *w, struct screen_draw_ctx *ctx, u_int py, u_int ny)
 | 
			
		||||
{
 | 
			
		||||
	struct window_scroll_mode_data	*data = w->modedata;
 | 
			
		||||
	struct screen			*s = &w->screen;
 | 
			
		||||
	struct screen_draw_ctx		 ctx;
 | 
			
		||||
 | 
			
		||||
	if (s->hsize != data->size) {
 | 
			
		||||
		data->oy += s->hsize - data->size;
 | 
			
		||||
		data->size = s->hsize;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	screen_draw_start(&ctx, s, b, data->ox, data->oy);
 | 
			
		||||
	if (py != 0)
 | 
			
		||||
		screen_draw_lines(&ctx, py, ny);
 | 
			
		||||
	else if (ny > 1)
 | 
			
		||||
		screen_draw_lines(&ctx, py + 1, ny - 1);
 | 
			
		||||
 | 
			
		||||
	if (py == 0)
 | 
			
		||||
		window_scroll_draw_position(w, &ctx);
 | 
			
		||||
 | 
			
		||||
	screen_draw_stop(&ctx);
 | 
			
		||||
		screen_draw_lines(ctx, py, ny);
 | 
			
		||||
	else {
 | 
			
		||||
		if (ny > 1)
 | 
			
		||||
			screen_draw_lines(ctx, py + 1, ny - 1);
 | 
			
		||||
		window_scroll_draw_position(w, ctx);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -133,7 +130,7 @@ window_scroll_key(struct window *w, int key)
 | 
			
		||||
		w->screen.mode &= ~MODE_BACKGROUND;
 | 
			
		||||
 | 
			
		||||
		recalculate_sizes();
 | 
			
		||||
		server_redraw_window_all(w);
 | 
			
		||||
		server_redraw_window(w);
 | 
			
		||||
		return;
 | 
			
		||||
	case 'h':
 | 
			
		||||
	case KEYC_LEFT:
 | 
			
		||||
@@ -169,169 +166,84 @@ window_scroll_key(struct window *w, int key)
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
	if (ox != data->ox || oy != data->oy)
 | 
			
		||||
		server_redraw_window_all(w);
 | 
			
		||||
		server_redraw_window(w);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
window_scroll_up_1(struct window *w)
 | 
			
		||||
{
 | 
			
		||||
	struct window_scroll_mode_data	*data = w->modedata;
 | 
			
		||||
	struct screen			*s = &w->screen;
 | 
			
		||||
	struct screen_draw_ctx		 ctx;
 | 
			
		||||
	struct client			*c;
 | 
			
		||||
	u_int		 		 i;
 | 
			
		||||
	struct hdr			 hdr;
 | 
			
		||||
	size_t				 size;
 | 
			
		||||
 | 
			
		||||
	if (data->oy >= data->size)
 | 
			
		||||
		return;
 | 
			
		||||
	data->oy++;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
 | 
			
		||||
		c = ARRAY_ITEM(&clients, i);
 | 
			
		||||
		if (c == NULL || c->session == NULL)
 | 
			
		||||
			continue;
 | 
			
		||||
		if (!session_has(c->session, w))
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		buffer_ensure(c->out, sizeof hdr);
 | 
			
		||||
		buffer_add(c->out, sizeof hdr);
 | 
			
		||||
		size = BUFFER_USED(c->out);
 | 
			
		||||
 | 
			
		||||
		screen_draw_start(&ctx, s, c->out, data->ox, data->oy);
 | 
			
		||||
		screen_draw_move(&ctx, 0, 0);
 | 
			
		||||
		input_store_one(c->out, CODE_INSERTLINE, 1);
 | 
			
		||||
	screen_draw_start_window(&ctx, w, data->ox, data->oy);
 | 
			
		||||
	screen_draw_move_cursor(&ctx, 0, 0);
 | 
			
		||||
	screen_draw_insert_lines(&ctx, 1);
 | 
			
		||||
	window_scroll_draw_position(w, &ctx);
 | 
			
		||||
		screen_draw_line(&ctx, 1);	/* nuke old position display */
 | 
			
		||||
	screen_draw_line(&ctx, 1);
 | 
			
		||||
	screen_draw_stop(&ctx);
 | 
			
		||||
 | 
			
		||||
		size = BUFFER_USED(c->out) - size;
 | 
			
		||||
		hdr.type = MSG_DATA;
 | 
			
		||||
		hdr.size = size;
 | 
			
		||||
		memcpy(BUFFER_IN(c->out) - size - sizeof hdr, &hdr, sizeof hdr);
 | 
			
		||||
	}	
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
window_scroll_down_1(struct window *w)
 | 
			
		||||
{
 | 
			
		||||
	struct window_scroll_mode_data	*data = w->modedata;
 | 
			
		||||
	struct screen			*s = &w->screen;
 | 
			
		||||
	struct screen_draw_ctx		 ctx;
 | 
			
		||||
	struct client			*c;
 | 
			
		||||
	u_int		 		 i;
 | 
			
		||||
	struct hdr			 hdr;
 | 
			
		||||
	size_t				 size;
 | 
			
		||||
 | 
			
		||||
	if (data->oy == 0)
 | 
			
		||||
		return;
 | 
			
		||||
	data->oy--;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
 | 
			
		||||
		c = ARRAY_ITEM(&clients, i);
 | 
			
		||||
		if (c == NULL || c->session == NULL)
 | 
			
		||||
			continue;
 | 
			
		||||
		if (!session_has(c->session, w))
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		buffer_ensure(c->out, sizeof hdr);
 | 
			
		||||
		buffer_add(c->out, sizeof hdr);
 | 
			
		||||
		size = BUFFER_USED(c->out);
 | 
			
		||||
		
 | 
			
		||||
		screen_draw_start(&ctx, s, c->out, data->ox, data->oy);
 | 
			
		||||
		screen_draw_move(&ctx, 0, 0);
 | 
			
		||||
		input_store_one(c->out, CODE_DELETELINE, 1);
 | 
			
		||||
		screen_draw_line(&ctx, screen_last_y(s));
 | 
			
		||||
	screen_draw_start_window(&ctx, w, data->ox, data->oy);
 | 
			
		||||
	screen_draw_move_cursor(&ctx, 0, 0);
 | 
			
		||||
	screen_draw_delete_lines(&ctx, 1);
 | 
			
		||||
	screen_draw_line(&ctx, screen_last_y(&w->screen));
 | 
			
		||||
	window_scroll_draw_position(w, &ctx);
 | 
			
		||||
	screen_draw_stop(&ctx);
 | 
			
		||||
		
 | 
			
		||||
		size = BUFFER_USED(c->out) - size;
 | 
			
		||||
		hdr.type = MSG_DATA;
 | 
			
		||||
		hdr.size = size;
 | 
			
		||||
		memcpy(BUFFER_IN(c->out) - size - sizeof hdr, &hdr, sizeof hdr);
 | 
			
		||||
	}	
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
window_scroll_right_1(struct window *w)
 | 
			
		||||
{
 | 
			
		||||
	struct window_scroll_mode_data	*data = w->modedata;
 | 
			
		||||
	struct screen			*s = &w->screen;
 | 
			
		||||
	struct screen_draw_ctx		 ctx;
 | 
			
		||||
	struct client			*c;
 | 
			
		||||
	u_int		 		 i, j;
 | 
			
		||||
	struct hdr			 hdr;
 | 
			
		||||
	size_t				 size;
 | 
			
		||||
	u_int		 		 i;
 | 
			
		||||
 | 
			
		||||
	if (data->ox >= SHRT_MAX)
 | 
			
		||||
		return;
 | 
			
		||||
	data->ox++;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
 | 
			
		||||
		c = ARRAY_ITEM(&clients, i);
 | 
			
		||||
		if (c == NULL || c->session == NULL)
 | 
			
		||||
			continue;
 | 
			
		||||
		if (!session_has(c->session, w))
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		buffer_ensure(c->out, sizeof hdr);
 | 
			
		||||
		buffer_add(c->out, sizeof hdr);
 | 
			
		||||
		size = BUFFER_USED(c->out);
 | 
			
		||||
		
 | 
			
		||||
		screen_draw_start(&ctx, s, c->out, data->ox, data->oy);
 | 
			
		||||
		for (j = 1; j < screen_size_y(s); j++) {
 | 
			
		||||
			screen_draw_move(&ctx, 0, j);
 | 
			
		||||
			input_store_one(c->out, CODE_DELETECHARACTER, 1);
 | 
			
		||||
	screen_draw_start_window(&ctx, w, data->ox, data->oy);
 | 
			
		||||
	for (i = 1; i < screen_size_y(&w->screen); i++) {
 | 
			
		||||
		screen_draw_move_cursor(&ctx, 0, i);
 | 
			
		||||
		screen_draw_delete_characters(&ctx, 1);
 | 
			
		||||
	}
 | 
			
		||||
		screen_draw_column(&ctx, screen_last_x(s));
 | 
			
		||||
	screen_draw_column(&ctx, screen_last_x(&w->screen));
 | 
			
		||||
	window_scroll_draw_position(w, &ctx);
 | 
			
		||||
	screen_draw_stop(&ctx);
 | 
			
		||||
		
 | 
			
		||||
		size = BUFFER_USED(c->out) - size;
 | 
			
		||||
		hdr.type = MSG_DATA;
 | 
			
		||||
		hdr.size = size;
 | 
			
		||||
		memcpy(BUFFER_IN(c->out) - size - sizeof hdr, &hdr, sizeof hdr);
 | 
			
		||||
	}	
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
window_scroll_left_1(struct window *w)
 | 
			
		||||
{
 | 
			
		||||
	struct window_scroll_mode_data	*data = w->modedata;
 | 
			
		||||
	struct screen			*s = &w->screen;
 | 
			
		||||
	struct screen_draw_ctx		 ctx;
 | 
			
		||||
	struct client			*c;
 | 
			
		||||
	u_int		 		 i, j;
 | 
			
		||||
	struct hdr			 hdr;
 | 
			
		||||
	size_t				 size;
 | 
			
		||||
	u_int		 		 i;
 | 
			
		||||
 | 
			
		||||
	if (data->ox == 0)
 | 
			
		||||
		return;
 | 
			
		||||
	data->ox--;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
 | 
			
		||||
		c = ARRAY_ITEM(&clients, i);
 | 
			
		||||
		if (c == NULL || c->session == NULL)
 | 
			
		||||
			continue;
 | 
			
		||||
		if (!session_has(c->session, w))
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		buffer_ensure(c->out, sizeof hdr);
 | 
			
		||||
		buffer_add(c->out, sizeof hdr);
 | 
			
		||||
		size = BUFFER_USED(c->out);
 | 
			
		||||
		
 | 
			
		||||
		screen_draw_start(&ctx, s, c->out, data->ox, data->oy);
 | 
			
		||||
		for (j = 1; j < screen_size_y(s); j++) {
 | 
			
		||||
			screen_draw_move(&ctx, 0, j);
 | 
			
		||||
			input_store_one(c->out, CODE_INSERTCHARACTER, 1);
 | 
			
		||||
	screen_draw_start_window(&ctx, w, data->ox, data->oy);
 | 
			
		||||
	for (i = 1; i < screen_size_y(&w->screen); i++) {
 | 
			
		||||
		screen_draw_move_cursor(&ctx, 0, i);
 | 
			
		||||
		screen_draw_insert_characters(&ctx, 1);
 | 
			
		||||
	}
 | 
			
		||||
	screen_draw_column(&ctx, 0);
 | 
			
		||||
	window_scroll_draw_position(w, &ctx);
 | 
			
		||||
	screen_draw_stop(&ctx);
 | 
			
		||||
		
 | 
			
		||||
		size = BUFFER_USED(c->out) - size;
 | 
			
		||||
		hdr.type = MSG_DATA;
 | 
			
		||||
		hdr.size = size;
 | 
			
		||||
		memcpy(BUFFER_IN(c->out) - size - sizeof hdr, &hdr, sizeof hdr);
 | 
			
		||||
	}	
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										22
									
								
								window.c
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								window.c
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: window.c,v 1.31 2007-11-21 19:53:57 nicm Exp $ */
 | 
			
		||||
/* $Id: window.c,v 1.32 2007-11-27 19:23:34 nicm Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -274,24 +274,18 @@ window_resize(struct window *w, u_int sx, u_int sy)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
window_parse(struct window *w, struct buffer *b)
 | 
			
		||||
window_parse(struct window *w)
 | 
			
		||||
{
 | 
			
		||||
	input_parse(w, b);
 | 
			
		||||
	input_parse(w);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
window_draw(struct window *w, struct buffer *b, u_int py, u_int ny)
 | 
			
		||||
window_draw(struct window *w, struct screen_draw_ctx *ctx, u_int py, u_int ny)
 | 
			
		||||
{
 | 
			
		||||
	struct screen		*s = &w->screen;
 | 
			
		||||
	struct screen_draw_ctx	 ctx;
 | 
			
		||||
 | 
			
		||||
	if (w->mode != NULL)
 | 
			
		||||
		w->mode->draw(w, b, py, ny);
 | 
			
		||||
	else {
 | 
			
		||||
		screen_draw_start(&ctx, s, b, 0, 0);
 | 
			
		||||
		screen_draw_lines(&ctx, py, ny);
 | 
			
		||||
		screen_draw_stop(&ctx);
 | 
			
		||||
	}
 | 
			
		||||
		w->mode->draw(w, ctx, py, ny);
 | 
			
		||||
	else
 | 
			
		||||
		screen_draw_lines(ctx, py, ny);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -300,5 +294,5 @@ window_key(struct window *w, int key)
 | 
			
		||||
	if (w->mode != NULL)
 | 
			
		||||
		w->mode->key(w, key);
 | 
			
		||||
	else
 | 
			
		||||
		input_key(w->out, key);	
 | 
			
		||||
		input_key(w, key);	
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user