aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicholas Marriott <nicholas.marriott@gmail.com>2007-12-06 09:46:23 +0000
committerNicholas Marriott <nicholas.marriott@gmail.com>2007-12-06 09:46:23 +0000
commit103748d6adfe1b2d706cb0a1e1a128be5366d655 (patch)
treeb9d4feef5012083d9c0ba96693322286645a27a3
parent6f142e9ac61783e79c27e56ed6aa2fc7ff13683d (diff)
downloadrtmux-103748d6adfe1b2d706cb0a1e1a128be5366d655.tar.gz
rtmux-103748d6adfe1b2d706cb0a1e1a128be5366d655.tar.bz2
rtmux-103748d6adfe1b2d706cb0a1e1a128be5366d655.zip
Major reorganisation of screen handling.
-rw-r--r--CHANGES10
-rw-r--r--GNUmakefile4
-rw-r--r--Makefile4
-rw-r--r--TODO16
-rw-r--r--buffer.c4
-rw-r--r--client-msg.c8
-rw-r--r--client.c14
-rw-r--r--cmd-attach-session.c6
-rw-r--r--cmd-bind-key.c6
-rw-r--r--cmd-copy-mode.c4
-rw-r--r--cmd-kill-session.c6
-rw-r--r--cmd-kill-window.c8
-rw-r--r--cmd-last-window.c6
-rw-r--r--cmd-link-window.c10
-rw-r--r--cmd-list-windows.c20
-rw-r--r--cmd-new-session.c10
-rw-r--r--cmd-new-window.c10
-rw-r--r--cmd-next-window.c6
-rw-r--r--cmd-paste-buffer.c4
-rw-r--r--cmd-previous-window.c6
-rw-r--r--cmd-rename-session.c8
-rw-r--r--cmd-rename-window.c8
-rw-r--r--cmd-scroll-mode.c4
-rw-r--r--cmd-select-window.c10
-rw-r--r--cmd-send-prefix.c4
-rw-r--r--cmd-set-option.c16
-rw-r--r--cmd-swap-window.c8
-rw-r--r--cmd-switch-client.c10
-rw-r--r--cmd-unbind-key.c6
-rw-r--r--cmd-unlink-window.c8
-rw-r--r--cmd.c12
-rw-r--r--input.c398
-rw-r--r--key-bindings.c10
-rw-r--r--resize.c16
-rw-r--r--screen-display.c191
-rw-r--r--screen-redraw.c218
-rw-r--r--screen-write.c516
-rw-r--r--screen.c450
-rw-r--r--server-fn.c83
-rw-r--r--server-msg.c16
-rw-r--r--server.c8
-rw-r--r--session.c18
-rw-r--r--status.c24
-rw-r--r--tmux.c10
-rw-r--r--tmux.h211
-rw-r--r--tty-keys.c4
-rw-r--r--tty-write.c16
-rw-r--r--tty.c47
-rw-r--r--window-copy.c603
-rw-r--r--window-more.c227
-rw-r--r--window-scroll.c266
-rw-r--r--window.c36
52 files changed, 2085 insertions, 1539 deletions
diff --git a/CHANGES b/CHANGES
index 932ec115..69ef8fb6 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,11 @@
+06 December 2007
+
+* Another major reorganisation, this time of screen handling. A new set of
+ functions, screen_write_*, are now used to write to a screen and a tty
+ simultaneously. These are used by the input parser to update the base
+ window screen and also by the different modes which now interpose their own
+ screen.
+
30 November 2007
* Support \ek...\e\ to set window name.
@@ -289,4 +297,4 @@
(including mutt, emacs). No status bar yet and no key remapping or other
customisation.
-$Id: CHANGES,v 1.89 2007-11-30 11:08:34 nicm Exp $
+$Id: CHANGES,v 1.90 2007-12-06 09:46:21 nicm Exp $
diff --git a/GNUmakefile b/GNUmakefile
index 3acfd1c7..7c3354f1 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -1,4 +1,4 @@
-# $Id: GNUmakefile,v 1.8 2007-11-25 22:08:13 nicm Exp $
+# $Id: GNUmakefile,v 1.9 2007-12-06 09:46:21 nicm Exp $
.PHONY: clean
@@ -37,7 +37,7 @@ CFLAGS+= -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations
CFLAGS+= -Wwrite-strings -Wshadow -Wpointer-arith -Wcast-qual -Wsign-compare
CFLAGS+= -Wundef -Wbad-function-cast -Winline -Wcast-align
-LDFLAGS+=
+LDFLAGS+=
LIBS+= -lncurses
PREFIX?= /usr/local
diff --git a/Makefile b/Makefile
index 13155c90..cf31418e 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.51 2007-11-30 13:59:16 nicm Exp $
+# $Id: Makefile,v 1.52 2007-12-06 09:46:21 nicm Exp $
.SUFFIXES: .c .o .y .h
.PHONY: clean update-index.html upload-index.html
@@ -28,7 +28,7 @@ SRCS= tmux.c server.c server-msg.c server-fn.c buffer.c buffer-poll.c status.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 \
- tty.c tty-keys.c tty-write.c
+ tty.c tty-keys.c tty-write.c screen-write.c screen-redraw.c
CC?= cc
INCDIRS+= -I. -I- -I/usr/local/include
diff --git a/TODO b/TODO
index 47c7f90c..a4c6c8f9 100644
--- a/TODO
+++ b/TODO
@@ -66,7 +66,7 @@
-- For 0.2 --------------------------------------------------------------------
- window splitting?
-- restore term cap checks
+- restore term cap checks ****
- anything which uses cmd_{send,recv}_string will break if the string is
split. string length should be part of the command size
- echo \\033[35\;46m\\033[2J last line quirk (with C-b r)
@@ -74,6 +74,20 @@
- is ACS the right way round??
--------
+
+screen redraw.
+
+ops:
+- redraw screen or section of screen to tty without altering it
+ (screen-redraw.c, screen_redraw_ctx)
+ (switching screen etc)
+- draw to screen and optionally tty
+ (window output)
+ (screen-write.c, screen_write_ctx)
+- copy line/column from one screen (inc history) at offset??
+ (scroll/copy mode)
+
+--------
kmous -- \E[M
mouse init: putp("\033[?1000h");
diff --git a/buffer.c b/buffer.c
index f5864892..7bf0e4b0 100644
--- a/buffer.c
+++ b/buffer.c
@@ -1,4 +1,4 @@
-/* $Id: buffer.c,v 1.3 2007-11-27 19:23:33 nicm Exp $ */
+/* $Id: buffer.c,v 1.4 2007-12-06 09:46:21 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -215,7 +215,7 @@ 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);
diff --git a/client-msg.c b/client-msg.c
index 878bbcd0..65287f50 100644
--- a/client-msg.c
+++ b/client-msg.c
@@ -1,4 +1,4 @@
-/* $Id: client-msg.c,v 1.13 2007-11-27 20:03:08 nicm Exp $ */
+/* $Id: client-msg.c,v 1.14 2007-12-06 09:46:21 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -34,7 +34,7 @@ int client_msg_fn_pause(struct hdr *, struct client_ctx *, char **);
struct client_msg {
enum hdrtype type;
-
+
int (*fn)(struct hdr *, struct client_ctx *, char **);
};
struct client_msg client_msg_table[] = {
@@ -58,7 +58,7 @@ client_msg_dispatch(struct client_ctx *cctx, char **error)
if (BUFFER_USED(cctx->srv_in) < (sizeof hdr) + hdr.size)
return (1);
buffer_remove(cctx->srv_in, sizeof hdr);
-
+
for (i = 0; i < NCLIENTMSG; i++) {
msg = client_msg_table + i;
if (msg->type == hdr.type) {
@@ -92,7 +92,7 @@ client_msg_fn_detach(
client_write_server(cctx, MSG_EXITING, NULL, 0);
cctx->flags |= CCTX_DETACH;
-
+
return (0);
}
diff --git a/client.c b/client.c
index 4caf30a4..20e5dc33 100644
--- a/client.c
+++ b/client.c
@@ -1,4 +1,4 @@
-/* $Id: client.c,v 1.24 2007-12-01 11:10:33 nicm Exp $ */
+/* $Id: client.c,v 1.25 2007-12-06 09:46:21 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -134,7 +134,7 @@ client_main(struct client_ctx *cctx)
pfd.events = POLLIN;
if (BUFFER_USED(cctx->srv_out) > 0)
pfd.events |= POLLOUT;
-
+
if (poll(&pfd, 1, timeout) == -1) {
if (errno == EAGAIN || errno == EINTR)
continue;
@@ -157,18 +157,18 @@ client_main(struct client_ctx *cctx)
break;
}
}
-
+
out:
if (sigterm) {
printf("[terminated]\n");
return (1);
}
-
+
if (cctx->flags & CCTX_EXIT) {
printf("[exited]\n");
return (0);
}
-
+
if (cctx->flags & CCTX_DETACH) {
printf("[detached]\n");
return (0);
@@ -187,13 +187,13 @@ client_handle_winch(struct client_ctx *cctx)
{
struct msg_resize_data data;
struct winsize ws;
-
+
if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) == -1)
fatal("ioctl failed");
data.sx = ws.ws_col;
data.sy = ws.ws_row;
client_write_server(cctx, MSG_RESIZE, &data, sizeof data);
-
+
sigwinch = 0;
}
diff --git a/cmd-attach-session.c b/cmd-attach-session.c
index 930b756b..1741b36e 100644
--- a/cmd-attach-session.c
+++ b/cmd-attach-session.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-attach-session.c,v 1.10 2007-11-27 19:23:33 nicm Exp $ */
+/* $Id: cmd-attach-session.c,v 1.11 2007-12-06 09:46:21 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -40,7 +40,7 @@ const struct cmd_entry cmd_attach_session_entry = {
"attach-session", "attach", "[-d]",
CMD_CANTNEST|CMD_NOCLIENT,
cmd_attach_session_parse,
- cmd_attach_session_exec,
+ cmd_attach_session_exec,
cmd_attach_session_send,
cmd_attach_session_recv,
cmd_attach_session_free
@@ -63,7 +63,7 @@ cmd_attach_session_parse(void **ptr, int argc, char **argv, char **cause)
default:
goto usage;
}
- }
+ }
argc -= optind;
argv += optind;
if (argc != 0)
diff --git a/cmd-bind-key.c b/cmd-bind-key.c
index 5f739aca..537a12f5 100644
--- a/cmd-bind-key.c
+++ b/cmd-bind-key.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-bind-key.c,v 1.7 2007-11-16 21:12:31 nicm Exp $ */
+/* $Id: cmd-bind-key.c,v 1.8 2007-12-06 09:46:21 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -41,7 +41,7 @@ const struct cmd_entry cmd_bind_key_entry = {
"bind-key", "bind", "key command [arguments]",
CMD_NOCLIENT|CMD_NOSESSION,
cmd_bind_key_parse,
- cmd_bind_key_exec,
+ cmd_bind_key_exec,
cmd_bind_key_send,
cmd_bind_key_recv,
cmd_bind_key_free
@@ -61,7 +61,7 @@ cmd_bind_key_parse(void **ptr, int argc, char **argv, char **cause)
default:
goto usage;
}
- }
+ }
argc -= optind;
argv += optind;
if (argc < 1)
diff --git a/cmd-copy-mode.c b/cmd-copy-mode.c
index 665507e1..c5945743 100644
--- a/cmd-copy-mode.c
+++ b/cmd-copy-mode.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-copy-mode.c,v 1.2 2007-11-27 19:23:33 nicm Exp $ */
+/* $Id: cmd-copy-mode.c,v 1.3 2007-12-06 09:46:21 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -33,7 +33,7 @@ const struct cmd_entry cmd_copy_mode_entry = {
"copy-mode", NULL, "",
CMD_NOCLIENT,
NULL,
- cmd_copy_mode_exec,
+ cmd_copy_mode_exec,
NULL,
NULL,
NULL
diff --git a/cmd-kill-session.c b/cmd-kill-session.c
index e4addc87..21cb6025 100644
--- a/cmd-kill-session.c
+++ b/cmd-kill-session.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-kill-session.c,v 1.4 2007-11-21 13:11:41 nicm Exp $ */
+/* $Id: cmd-kill-session.c,v 1.5 2007-12-06 09:46:21 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -47,7 +47,7 @@ cmd_kill_session_exec(unused void *ptr, struct cmd_ctx *ctx)
{
struct client *c;
u_int i;
-
+
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c->session == ctx->session) {
@@ -57,7 +57,7 @@ cmd_kill_session_exec(unused void *ptr, struct cmd_ctx *ctx)
}
session_destroy(ctx->session);
-
+
if (ctx->cmdclient != NULL)
server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0);
}
diff --git a/cmd-kill-window.c b/cmd-kill-window.c
index e962fc75..13742e19 100644
--- a/cmd-kill-window.c
+++ b/cmd-kill-window.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-kill-window.c,v 1.6 2007-11-16 21:12:31 nicm Exp $ */
+/* $Id: cmd-kill-window.c,v 1.7 2007-12-06 09:46:21 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -41,7 +41,7 @@ const struct cmd_entry cmd_kill_window_entry = {
"kill-window", "killw", "[-i index]",
CMD_NOCLIENT,
cmd_kill_window_parse,
- cmd_kill_window_exec,
+ cmd_kill_window_exec,
cmd_kill_window_send,
cmd_kill_window_recv,
cmd_kill_window_free
@@ -69,7 +69,7 @@ cmd_kill_window_parse(void **ptr, int argc, char **argv, char **cause)
default:
goto usage;
}
- }
+ }
argc -= optind;
argv += optind;
if (argc != 0)
@@ -117,7 +117,7 @@ cmd_kill_window_exec(void *ptr, struct cmd_ctx *ctx)
} else
server_redraw_client(c);
}
-
+
if (ctx->cmdclient != NULL)
server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0);
}
diff --git a/cmd-last-window.c b/cmd-last-window.c
index 7052c1f1..e68289cd 100644
--- a/cmd-last-window.c
+++ b/cmd-last-window.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-last-window.c,v 1.5 2007-11-16 21:12:31 nicm Exp $ */
+/* $Id: cmd-last-window.c,v 1.6 2007-12-06 09:46:21 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -45,8 +45,8 @@ cmd_last_window_exec(unused void *ptr, struct cmd_ctx *ctx)
if (session_last(ctx->session) == 0)
server_redraw_session(ctx->session);
else
- ctx->error(ctx, "no last window");
-
+ ctx->error(ctx, "no last window");
+
if (ctx->cmdclient != NULL)
server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0);
}
diff --git a/cmd-link-window.c b/cmd-link-window.c
index 331c6c45..00e3b4a7 100644
--- a/cmd-link-window.c
+++ b/cmd-link-window.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-link-window.c,v 1.8 2007-11-21 15:05:53 nicm Exp $ */
+/* $Id: cmd-link-window.c,v 1.9 2007-12-06 09:46:21 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -45,7 +45,7 @@ const struct cmd_entry cmd_link_window_entry = {
"link-window", "linkw", "[-dk] [-i index] name index",
CMD_NOCLIENT,
cmd_link_window_parse,
- cmd_link_window_exec,
+ cmd_link_window_exec,
cmd_link_window_send,
cmd_link_window_recv,
cmd_link_window_free
@@ -83,7 +83,7 @@ cmd_link_window_parse(void **ptr, int argc, char **argv, char **cause)
default:
goto usage;
}
- }
+ }
argc -= optind;
argv += optind;
if (argc != 2)
@@ -116,7 +116,7 @@ cmd_link_window_exec(void *ptr, struct cmd_ctx *ctx)
if (data == NULL)
return;
-
+
if ((src = session_find(data->srcname)) == NULL) {
ctx->error(ctx, "session not found: %s", data->srcname);
return;
@@ -155,7 +155,7 @@ cmd_link_window_exec(void *ptr, struct cmd_ctx *ctx)
dst->lastw = NULL;
/*
- * Can't error out after this or there could be an empty
+ * Can't error out after this or there could be an empty
* session!
*/
}
diff --git a/cmd-list-windows.c b/cmd-list-windows.c
index 111101b2..056af295 100644
--- a/cmd-list-windows.c
+++ b/cmd-list-windows.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-list-windows.c,v 1.14 2007-11-23 13:11:43 nicm Exp $ */
+/* $Id: cmd-list-windows.c,v 1.15 2007-12-06 09:46:21 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -51,18 +51,18 @@ cmd_list_windows_exec(unused void *ptr, struct cmd_ctx *ctx)
w = wl->window;
size = 0;
- for (i = 0; i < w->screen.hsize; i++)
- size += w->screen.grid_size[i] * 3;
- size += w->screen.hsize * (sizeof *w->screen.grid_data);
- size += w->screen.hsize * (sizeof *w->screen.grid_attr);
- size += w->screen.hsize * (sizeof *w->screen.grid_colr);
- size += w->screen.hsize * (sizeof *w->screen.grid_size);
+ for (i = 0; i < w->base.hsize; i++)
+ size += w->base.grid_size[i] * 3;
+ size += w->base.hsize * (sizeof *w->base.grid_data);
+ size += w->base.hsize * (sizeof *w->base.grid_attr);
+ size += w->base.hsize * (sizeof *w->base.grid_colr);
+ size += w->base.hsize * (sizeof *w->base.grid_size);
ctx->print(ctx,
"%d: %s \"%s\" (%s) [%ux%u] [history %u/%u, %llu bytes]",
- wl->idx, w->name, w->screen.title, ttyname(w->fd),
- screen_size_x(&w->screen), screen_size_y(&w->screen),
- w->screen.hsize, w->screen.hlimit, size);
+ wl->idx, w->name, w->base.title, ttyname(w->fd),
+ screen_size_x(&w->base), screen_size_y(&w->base),
+ w->base.hsize, w->base.hlimit, size);
}
if (ctx->cmdclient != NULL)
diff --git a/cmd-new-session.c b/cmd-new-session.c
index 418fbf8e..aff19eab 100644
--- a/cmd-new-session.c
+++ b/cmd-new-session.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-new-session.c,v 1.18 2007-11-27 19:23:33 nicm Exp $ */
+/* $Id: cmd-new-session.c,v 1.19 2007-12-06 09:46:21 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -44,7 +44,7 @@ const struct cmd_entry cmd_new_session_entry = {
"[-d] [-s session-name] [-n window-name] [command]",
CMD_STARTSERVER|CMD_NOCLIENT|CMD_NOSESSION|CMD_CANTNEST,
cmd_new_session_parse,
- cmd_new_session_exec,
+ cmd_new_session_exec,
cmd_new_session_send,
cmd_new_session_recv,
cmd_new_session_free
@@ -76,7 +76,7 @@ cmd_new_session_parse(void **ptr, int argc, char **argv, char **cause)
default:
goto usage;
}
- }
+ }
argc -= optind;
argv += optind;
if (argc != 0 && argc != 1)
@@ -90,7 +90,7 @@ cmd_new_session_parse(void **ptr, int argc, char **argv, char **cause)
usage:
usage(cause, "%s %s",
cmd_new_session_entry.name, cmd_new_session_entry.usage);
-
+
cmd_new_session_free(data);
return (-1);
}
@@ -103,7 +103,7 @@ cmd_new_session_exec(void *ptr, struct cmd_ctx *ctx)
struct client *c = ctx->cmdclient;
char *cmd, *cause;
u_int sy;
-
+
if (data == NULL)
data = &std;
diff --git a/cmd-new-window.c b/cmd-new-window.c
index 730c0293..71d922f3 100644
--- a/cmd-new-window.c
+++ b/cmd-new-window.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-new-window.c,v 1.13 2007-11-16 21:12:31 nicm Exp $ */
+/* $Id: cmd-new-window.c,v 1.14 2007-12-06 09:46:22 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -44,7 +44,7 @@ const struct cmd_entry cmd_new_window_entry = {
"new-window", "neww", "[-d] [-i index] [-n name] [command]",
CMD_NOCLIENT,
cmd_new_window_parse,
- cmd_new_window_exec,
+ cmd_new_window_exec,
cmd_new_window_send,
cmd_new_window_recv,
cmd_new_window_free
@@ -81,7 +81,7 @@ cmd_new_window_parse(void **ptr, int argc, char **argv, char **cause)
default:
goto usage;
}
- }
+ }
argc -= optind;
argv += optind;
if (argc != 0 && argc != 1)
@@ -111,7 +111,7 @@ cmd_new_window_exec(void *ptr, struct cmd_ctx *ctx)
if (data == NULL)
data = &std;
-
+
cmd = data->cmd;
if (cmd == NULL)
cmd = default_command;
@@ -128,7 +128,7 @@ cmd_new_window_exec(void *ptr, struct cmd_ctx *ctx)
server_redraw_session(ctx->session);
} else
server_status_session(ctx->session);
-
+
if (ctx->cmdclient != NULL)
server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0);
}
diff --git a/cmd-next-window.c b/cmd-next-window.c
index 8a807714..4495558e 100644
--- a/cmd-next-window.c
+++ b/cmd-next-window.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-next-window.c,v 1.5 2007-11-16 21:12:31 nicm Exp $ */
+/* $Id: cmd-next-window.c,v 1.6 2007-12-06 09:46:22 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -45,8 +45,8 @@ cmd_next_window_exec(unused void *ptr, struct cmd_ctx *ctx)
if (session_next(ctx->session) == 0)
server_redraw_session(ctx->session);
else
- ctx->error(ctx, "no next window");
-
+ ctx->error(ctx, "no next window");
+
if (ctx->cmdclient != NULL)
server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0);
}
diff --git a/cmd-paste-buffer.c b/cmd-paste-buffer.c
index b4bdf324..349feb48 100644
--- a/cmd-paste-buffer.c
+++ b/cmd-paste-buffer.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-paste-buffer.c,v 1.1 2007-11-23 17:52:54 nicm Exp $ */
+/* $Id: cmd-paste-buffer.c,v 1.2 2007-12-06 09:46:22 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -34,7 +34,7 @@ const struct cmd_entry cmd_paste_buffer_entry = {
"paste-buffer", NULL, "paste",
CMD_NOCLIENT,
NULL,
- cmd_paste_buffer_exec,
+ cmd_paste_buffer_exec,
NULL,
NULL,
NULL
diff --git a/cmd-previous-window.c b/cmd-previous-window.c
index cdf0b7d8..d0423998 100644
--- a/cmd-previous-window.c
+++ b/cmd-previous-window.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-previous-window.c,v 1.5 2007-11-16 21:12:31 nicm Exp $ */
+/* $Id: cmd-previous-window.c,v 1.6 2007-12-06 09:46:22 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -45,8 +45,8 @@ cmd_previous_window_exec(unused void *ptr, struct cmd_ctx *ctx)
if (session_previous(ctx->session) == 0)
server_redraw_session(ctx->session);
else
- ctx->error(ctx, "no previous window");
-
+ ctx->error(ctx, "no previous window");
+
if (ctx->cmdclient != NULL)
server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0);
}
diff --git a/cmd-rename-session.c b/cmd-rename-session.c
index ae28eec6..498bacd2 100644
--- a/cmd-rename-session.c
+++ b/cmd-rename-session.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-rename-session.c,v 1.3 2007-11-16 21:12:31 nicm Exp $ */
+/* $Id: cmd-rename-session.c,v 1.4 2007-12-06 09:46:22 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -41,7 +41,7 @@ const struct cmd_entry cmd_rename_session_entry = {
"rename-session", "rename", "new-name",
CMD_NOCLIENT,
cmd_rename_session_parse,
- cmd_rename_session_exec,
+ cmd_rename_session_exec,
cmd_rename_session_send,
cmd_rename_session_recv,
cmd_rename_session_free
@@ -61,7 +61,7 @@ cmd_rename_session_parse(void **ptr, int argc, char **argv, char **cause)
default:
goto usage;
}
- }
+ }
argc -= optind;
argv += optind;
if (argc != 1)
@@ -89,7 +89,7 @@ cmd_rename_session_exec(void *ptr, struct cmd_ctx *ctx)
xfree(ctx->session->name);
ctx->session->name = xstrdup(data->newname);
-
+
if (ctx->cmdclient != NULL)
server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0);
}
diff --git a/cmd-rename-window.c b/cmd-rename-window.c
index ba2f4fad..5ed0c161 100644
--- a/cmd-rename-window.c
+++ b/cmd-rename-window.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-rename-window.c,v 1.13 2007-11-16 21:12:31 nicm Exp $ */
+/* $Id: cmd-rename-window.c,v 1.14 2007-12-06 09:46:22 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -42,7 +42,7 @@ const struct cmd_entry cmd_rename_window_entry = {
"rename-window", "renamew", "[-i index] new-name",
CMD_NOCLIENT,
cmd_rename_window_parse,
- cmd_rename_window_exec,
+ cmd_rename_window_exec,
cmd_rename_window_send,
cmd_rename_window_recv,
cmd_rename_window_free
@@ -71,7 +71,7 @@ cmd_rename_window_parse(void **ptr, int argc, char **argv, char **cause)
default:
goto usage;
}
- }
+ }
argc -= optind;
argv += optind;
if (argc != 1)
@@ -110,7 +110,7 @@ cmd_rename_window_exec(void *ptr, struct cmd_ctx *ctx)
wl->window->name = xstrdup(data->newname);
server_status_session(ctx->session);
-
+
if (ctx->cmdclient != NULL)
server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0);
}
diff --git a/cmd-scroll-mode.c b/cmd-scroll-mode.c
index 17d839ae..5bdf5bb6 100644
--- a/cmd-scroll-mode.c
+++ b/cmd-scroll-mode.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-scroll-mode.c,v 1.4 2007-11-27 19:23:33 nicm Exp $ */
+/* $Id: cmd-scroll-mode.c,v 1.5 2007-12-06 09:46:22 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -33,7 +33,7 @@ const struct cmd_entry cmd_scroll_mode_entry = {
"scroll-mode", NULL, "",
CMD_NOCLIENT,
NULL,
- cmd_scroll_mode_exec,
+ cmd_scroll_mode_exec,
NULL,
NULL,
NULL
diff --git a/cmd-select-window.c b/cmd-select-window.c
index 16329ecf..896b18cb 100644
--- a/cmd-select-window.c
+++ b/cmd-select-window.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-select-window.c,v 1.10 2007-11-16 21:12:31 nicm Exp $ */
+/* $Id: cmd-select-window.c,v 1.11 2007-12-06 09:46:22 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -41,7 +41,7 @@ const struct cmd_entry cmd_select_window_entry = {
"select-window", "selectw", "index",
CMD_NOCLIENT,
cmd_select_window_parse,
- cmd_select_window_exec,
+ cmd_select_window_exec,
cmd_select_window_send,
cmd_select_window_recv,
cmd_select_window_free
@@ -75,7 +75,7 @@ cmd_select_window_parse(void **ptr, int argc, char **argv, char **cause)
default:
goto usage;
}
- }
+ }
argc -= optind;
argv += optind;
if (argc != 1)
@@ -86,7 +86,7 @@ cmd_select_window_parse(void **ptr, int argc, char **argv, char **cause)
xasprintf(cause, "index %s", errstr);
goto error;
}
-
+
return (0);
usage:
@@ -116,7 +116,7 @@ cmd_select_window_exec(void *ptr, struct cmd_ctx *ctx)
ctx->error(ctx, "no window %d", data->idx);
break;
}
-
+
if (ctx->cmdclient != NULL)
server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0);
}
diff --git a/cmd-send-prefix.c b/cmd-send-prefix.c
index 3d556675..eb13b673 100644
--- a/cmd-send-prefix.c
+++ b/cmd-send-prefix.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-send-prefix.c,v 1.6 2007-11-21 13:11:41 nicm Exp $ */
+/* $Id: cmd-send-prefix.c,v 1.7 2007-12-06 09:46:22 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -44,6 +44,6 @@ cmd_send_prefix_exec(unused void *ptr, struct cmd_ctx *ctx)
{
window_key(ctx->client->session->curw->window, prefix_key);
- if (ctx->cmdclient != NULL)
+ if (ctx->cmdclient != NULL)
server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0);
}
diff --git a/cmd-set-option.c b/cmd-set-option.c
index 70a4c3e4..d0e86c89 100644
--- a/cmd-set-option.c
+++ b/cmd-set-option.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-set-option.c,v 1.14 2007-11-23 12:48:20 nicm Exp $ */
+/* $Id: cmd-set-option.c,v 1.15 2007-12-06 09:46:22 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -43,7 +43,7 @@ const struct cmd_entry cmd_set_option_entry = {
"set-option", "set", "option value",
CMD_NOCLIENT|CMD_NOSESSION,
cmd_set_option_parse,
- cmd_set_option_exec,
+ cmd_set_option_exec,
cmd_set_option_send,
cmd_set_option_recv,
cmd_set_option_free
@@ -64,7 +64,7 @@ cmd_set_option_parse(void **ptr, int argc, char **argv, char **cause)
default:
goto usage;
}
- }
+ }
argc -= optind;
argv += optind;
if (argc != 1 && argc != 2)
@@ -104,7 +104,7 @@ cmd_set_option_exec(void *ptr, unused struct cmd_ctx *ctx)
number = -1;
if (data->value != NULL) {
number = strtonum(data->value, 0, INT_MAX, &errstr);
-
+
bool = -1;
if (number == 1 || strcasecmp(data->value, "on") == 0 ||
strcasecmp(data->value, "yes") == 0)
@@ -171,10 +171,10 @@ cmd_set_option_exec(void *ptr, unused struct cmd_ctx *ctx)
server_redraw_client(c);
}
}
- } else if (strcmp(data->option, "bell-action") == 0) {
+ } else if (strcmp(data->option, "bell-action") == 0) {
if (data->value == NULL) {
ctx->error(ctx, "invalid value");
- return;
+ return;
}
if (strcmp(data->value, "any") == 0)
bell_action = BELL_ANY;
@@ -186,10 +186,10 @@ cmd_set_option_exec(void *ptr, unused struct cmd_ctx *ctx)
ctx->error(ctx, "unknown bell-action: %s", data->value);
return;
}
- } else if (strcmp(data->option, "default-command") == 0) {
+ } else if (strcmp(data->option, "default-command") == 0) {
if (data->value == NULL) {
ctx->error(ctx, "invalid value");
- return;
+ return;
}
xfree(default_command);
default_command = xstrdup(data->value);
diff --git a/cmd-swap-window.c b/cmd-swap-window.c
index 66480ebf..6c4cac0f 100644
--- a/cmd-swap-window.c
+++ b/cmd-swap-window.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-swap-window.c,v 1.3 2007-11-16 21:12:31 nicm Exp $ */
+/* $Id: cmd-swap-window.c,v 1.4 2007-12-06 09:46:22 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -44,7 +44,7 @@ const struct cmd_entry cmd_swap_window_entry = {
"swap-window", "swapw", "[-i index] name index",
CMD_NOCLIENT,
cmd_swap_window_parse,
- cmd_swap_window_exec,
+ cmd_swap_window_exec,
cmd_swap_window_send,
cmd_swap_window_recv,
cmd_swap_window_free
@@ -78,7 +78,7 @@ cmd_swap_window_parse(void **ptr, int argc, char **argv, char **cause)
default:
goto usage;
}
- }
+ }
argc -= optind;
argv += optind;
if (argc != 2)
@@ -112,7 +112,7 @@ cmd_swap_window_exec(void *ptr, struct cmd_ctx *ctx)
if (data == NULL)
return;
-
+
if ((src = session_find(data->srcname)) == NULL) {
ctx->error(ctx, "session not found: %s", data->srcname);
return;
diff --git a/cmd-switch-client.c b/cmd-switch-client.c
index 2d3788b7..ca122879 100644
--- a/cmd-switch-client.c
+++ b/cmd-switch-client.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-switch-client.c,v 1.1 2007-11-16 21:31:03 nicm Exp $ */
+/* $Id: cmd-switch-client.c,v 1.2 2007-12-06 09:46:22 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -42,7 +42,7 @@ const struct cmd_entry cmd_switch_client_entry = {
"switch-client", "switchc", "session-name",
CMD_NOSESSION,
cmd_switch_client_parse,
- cmd_switch_client_exec,
+ cmd_switch_client_exec,
cmd_switch_client_send,
cmd_switch_client_recv,
cmd_switch_client_free
@@ -62,7 +62,7 @@ cmd_switch_client_parse(void **ptr, int argc, char **argv, char **cause)
default:
goto usage;
}
- }
+ }
argc -= optind;
argv += optind;
if (argc != 1)
@@ -88,14 +88,14 @@ cmd_switch_client_exec(void *ptr, struct cmd_ctx *ctx)
if (data == NULL)
return;
-
+
if ((s = session_find(data->name)) == NULL) {
ctx->error(ctx, "session not found: %s", data->name);
return;
}
ctx->client->session = s;
-
+
recalculate_sizes();
server_redraw_client(ctx->client);
diff --git a/cmd-unbind-key.c b/cmd-unbind-key.c
index 86a795a4..fd4e775f 100644
--- a/cmd-unbind-key.c
+++ b/cmd-unbind-key.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-unbind-key.c,v 1.7 2007-11-16 21:12:31 nicm Exp $ */
+/* $Id: cmd-unbind-key.c,v 1.8 2007-12-06 09:46:22 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -40,7 +40,7 @@ const struct cmd_entry cmd_unbind_key_entry = {
"unbind-key", "unbind", "key",
CMD_NOCLIENT|CMD_NOSESSION,
cmd_unbind_key_parse,
- cmd_unbind_key_exec,
+ cmd_unbind_key_exec,
cmd_unbind_key_send,
cmd_unbind_key_recv,
cmd_unbind_key_free
@@ -59,7 +59,7 @@ cmd_unbind_key_parse(void **ptr, int argc, char **argv, char **cause)
default:
goto usage;
}
- }
+ }
argc -= optind;
argv += optind;
if (argc != 1)
diff --git a/cmd-unlink-window.c b/cmd-unlink-window.c
index 9ed48104..577a2e2d 100644
--- a/cmd-unlink-window.c
+++ b/cmd-unlink-window.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-unlink-window.c,v 1.4 2007-11-16 21:12:31 nicm Exp $ */
+/* $Id: cmd-unlink-window.c,v 1.5 2007-12-06 09:46:22 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -41,7 +41,7 @@ const struct cmd_entry cmd_unlink_window_entry = {
"unlink-window", "unlinkw", "[-i index]",
CMD_NOCLIENT,
cmd_unlink_window_parse,
- cmd_unlink_window_exec,
+ cmd_unlink_window_exec,
cmd_unlink_window_send,
cmd_unlink_window_recv,
cmd_unlink_window_free
@@ -69,7 +69,7 @@ cmd_unlink_window_parse(void **ptr, int argc, char **argv, char **cause)
default:
goto usage;
}
- }
+ }
argc -= optind;
argv += optind;
if (argc != 0)
@@ -98,7 +98,7 @@ cmd_unlink_window_exec(void *ptr, struct cmd_ctx *ctx)
if (data == NULL)
return;
-
+
if (data->idx < 0)
data->idx = -1;
if (data->idx == -1)
diff --git a/cmd.c b/cmd.c
index 6526fa90..8e46a92f 100644
--- a/cmd.c
+++ b/cmd.c
@@ -1,4 +1,4 @@
-/* $Id: cmd.c,v 1.32 2007-11-23 17:52:54 nicm Exp $ */
+/* $Id: cmd.c,v 1.33 2007-12-06 09:46:22 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -48,7 +48,7 @@ const struct cmd_entry *cmd_table[] = {
&cmd_scroll_mode_entry,
&cmd_select_window_entry,
&cmd_send_prefix_entry,
- &cmd_set_option_entry,
+ &cmd_set_option_entry,
&cmd_swap_window_entry,
&cmd_switch_client_entry,
&cmd_unbind_key_entry,
@@ -70,7 +70,7 @@ cmd_parse(int argc, char **argv, char **cause)
entry = NULL;
for (entryp = cmd_table; *entryp != NULL; entryp++) {
- if ((*entryp)->alias != NULL &&
+ if ((*entryp)->alias != NULL &&
strcmp((*entryp)->alias, argv[0]) == 0) {
entry = *entryp;
break;
@@ -165,7 +165,7 @@ cmd_recv(struct buffer *b)
u_int m, n;
buffer_read(b, &m, sizeof m);
-
+
n = 0;
for (entryp = cmd_table; *entryp != NULL; entryp++) {
if (n == m)
@@ -195,7 +195,7 @@ void
cmd_send_string(struct buffer *b, const char *s)
{
size_t n;
-
+
if (s == NULL) {
n = 0;
buffer_write(b, &n, sizeof n);
@@ -218,7 +218,7 @@ cmd_recv_string(struct buffer *b)
if (n == 0)
return (NULL);
-
+
s = xmalloc(n);
buffer_read(b, s, n);
s[n - 1] = '\0';
diff --git a/input.c b/input.c
index 6ac6b54f..33c7f074 100644
--- a/input.c
+++ b/input.c
@@ -1,4 +1,4 @@
-/* $Id: input.c,v 1.43 2007-11-30 11:08:35 nicm Exp $ */
+/* $Id: input.c,v 1.44 2007-12-06 09:46:22 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -43,7 +43,6 @@ void input_abort_string(struct input_ctx *);
int input_add_string(struct input_ctx *, u_char);
char *input_get_string(struct input_ctx *);
-void input_write(struct input_ctx *, int, ...);
void input_state(struct input_ctx *, void *);
void input_state_first(u_char, struct input_ctx *);
@@ -85,13 +84,6 @@ void input_handle_sequence_decstbm(struct input_ctx *);
void input_handle_sequence_sgr(struct input_ctx *);
void input_handle_sequence_dsr(struct input_ctx *);
-#define input_limit(v, lower, upper) do { \
- if (v < lower) \
- v = lower; \
- if (v > upper) \
- v = upper; \
-} while (0)
-
int
input_new_argument(struct input_ctx *ictx)
{
@@ -184,19 +176,6 @@ input_get_string(struct input_ctx *ictx)
}
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_state(struct input_ctx *ictx, void *state)
{
ictx->state = state;
@@ -239,11 +218,18 @@ input_parse(struct window *w)
log_debug2("entry; buffer=%zu", ictx->len);
+ if (w->mode == NULL)
+ screen_write_start(&ictx->ctx, &w->base, tty_write_window, w);
+ else
+ screen_write_start(&ictx->ctx, &w->base, NULL, NULL);
+
while (ictx->off < ictx->len) {
ch = ictx->buf[ictx->off++];
ictx->state(ch, ictx);
}
+ screen_write_stop(&ictx->ctx);
+
buffer_remove(w->in, ictx->len);
}
@@ -253,7 +239,7 @@ input_state_first(u_char ch, struct input_ctx *ictx)
if (INPUT_C0CONTROL(ch)) {
if (ch == 0x1b)
input_state(ictx, input_state_escape);
- else
+ else
input_handle_c0_control(ch, ictx);
return;
}
@@ -268,10 +254,10 @@ input_state_first(u_char ch, struct input_ctx *ictx)
input_handle_c1_control(ch, ictx);
return;
}
-
+
input_handle_character(ch, ictx);
}
-
+
void
input_state_escape(u_char ch, struct input_ctx *ictx)
{
@@ -326,7 +312,7 @@ input_state_title_first(u_char ch, struct input_ctx *ictx)
input_start_string(ictx, STRING_IGNORE);
input_state(ictx, input_state_title_second);
return;
- }
+ }
input_state(ictx, input_state_first);
}
@@ -345,13 +331,10 @@ input_state_title_second(u_char ch, struct input_ctx *ictx)
void
input_state_title_next(u_char ch, struct input_ctx *ictx)
{
- struct screen *s = &ictx->w->screen;
-
if (ch == '\007') {
if (ictx->string_type == STRING_TITLE) {
- xfree(s->title);
- s->title = input_get_string(ictx);
- input_write(ictx, TTY_TITLE, s->title);
+ screen_write_set_title(
+ &ictx->ctx, input_get_string(ictx));
} else
input_abort_string(ictx);
input_state(ictx, input_state_first);
@@ -440,7 +423,7 @@ input_state_sequence_next(u_char ch, struct input_ctx *ictx)
}
return;
}
-
+
input_state(ictx, input_state_first);
}
@@ -449,13 +432,13 @@ input_state_sequence_intermediate(u_char ch, struct input_ctx *ictx)
{
if (INPUT_INTERMEDIATE(ch))
return;
-
+
if (INPUT_UPPERCASE(ch) || INPUT_LOWERCASE(ch)) {
input_state(ictx, input_state_first);
input_handle_sequence(ch, ictx);
return;
}
-
+
input_state(ictx, input_state_first);
}
@@ -496,82 +479,63 @@ input_state_string_escape(u_char ch, struct input_ctx *ictx)
void
input_handle_character(u_char ch, struct input_ctx *ictx)
{
- struct screen *s = &ictx->w->screen;
-
log_debug2("-- ch %zu: %hhu (%c)", ictx->off, ch, ch);
-
- if (s->cx == screen_size_x(s)) {
- input_write(ictx, TTY_CHARACTER, '\r');
- input_write(ictx, TTY_CHARACTER, '\n');
- s->cx = 0;
- screen_display_cursor_down(s);
- } else if (!screen_in_x(s, s->cx) || !screen_in_y(s, s->cy))
- return;
-
- screen_display_cursor_set(s, ch);
- input_write(ictx, TTY_CHARACTER, ch);
-
- s->cx++;
+ screen_write_put_character(&ictx->ctx, ch);
}
void
input_handle_c0_control(u_char ch, struct input_ctx *ictx)
{
- struct screen *s = &ictx->w->screen;
+ struct screen *s = ictx->ctx.s;
log_debug2("-- c0 %zu: %hhu", ictx->off, ch);
switch (ch) {
case '\0': /* NUL */
- return;
+ break;
case '\n': /* LF */
- screen_display_cursor_down(s);
+ screen_write_cursor_down_scroll(&ictx->ctx);
break;
case '\r': /* CR */
- s->cx = 0;
+ screen_write_move_cursor(&ictx->ctx, 0, s->cy);
break;
case '\007': /* BELL */
ictx->w->flags |= WINDOW_BELL;
- return;
+ break;
case '\010': /* BS */
- if (s->cx > 0)
- s->cx--;
+ screen_write_cursor_left(&ictx->ctx, 1);
break;
case '\011': /* TAB */
s->cx = ((s->cx / 8) * 8) + 8;
if (s->cx > screen_last_x(s)) {
s->cx = 0;
- screen_display_cursor_down(s);
+ screen_write_cursor_down(&ictx->ctx, 1);
}
- input_write(ictx, TTY_CURSORMOVE, s->cy, s->cx);
- return;
+ screen_write_move_cursor(&ictx->ctx, s->cx, s->cy);
+ break;
case '\016': /* SO */
s->attr |= ATTR_CHARSET;
- input_write(ictx, TTY_ATTRIBUTES, s->attr, s->colr);
- return;
+ screen_write_set_attributes(&ictx->ctx, s->attr, s->colr);
+ break;
case '\017': /* SI */
s->attr &= ~ATTR_CHARSET;
- input_write(ictx, TTY_ATTRIBUTES, s->attr, s->colr);
- return;
+ screen_write_set_attributes(&ictx->ctx, s->attr, s->colr);
+ break;
default:
log_debug("unknown c0: %hhu", ch);
- return;
+ break;
}
- input_write(ictx, TTY_CHARACTER, ch);
}
void
input_handle_c1_control(u_char ch, struct input_ctx *ictx)
{
- struct screen *s = &ictx->w->screen;
-
log_debug2("-- c1 %zu: %hhu (%c)", ictx->off, ch, ch);
switch (ch) {
case 'M': /* RI */
- screen_display_cursor_up(s);
- input_write(ictx, TTY_REVERSEINDEX);
+ screen_write_cursor_up_scroll(&ictx->ctx);
break;
default:
log_debug("unknown c1: %hhu", ch);
@@ -582,16 +546,16 @@ input_handle_c1_control(u_char ch, struct input_ctx *ictx)
void
input_handle_private_two(u_char ch, struct input_ctx *ictx)
{
- struct screen *s = &ictx->w->screen;
+ struct screen *s = ictx->ctx.s;
log_debug2("-- p2 %zu: %hhu (%c)", ictx->off, ch, ch);
switch (ch) {
case '=': /* DECKPAM */
- input_write(ictx, TTY_KKEYPADON);
+ screen_write_set_mode(&ictx->ctx, MODE_KKEYPAD);
break;
case '>': /* DECKPNM*/
- input_write(ictx, TTY_KKEYPADOFF);
+ screen_write_clear_mode(&ictx->ctx, MODE_KKEYPAD);
break;
case '7': /* DECSC */
s->saved_cx = s->cx;
@@ -607,8 +571,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;
- input_write(ictx, TTY_ATTRIBUTES, s->attr, s->colr);
- input_write(ictx, TTY_CURSORMOVE, s->cy, s->cx);
+ screen_write_set_attributes(&ictx->ctx, s->attr, s->colr);
+ screen_write_move_cursor(&ictx->ctx, s->cx, s->cy);
break;
default:
log_debug("unknown p2: %hhu", ch);
@@ -659,10 +623,10 @@ input_handle_sequence(u_char ch, struct input_ctx *ictx)
{ 'n', input_handle_sequence_dsr },
{ 'r', input_handle_sequence_decstbm },
};
- struct screen *s = &ictx->w->screen;
+ struct screen *s = ictx->ctx.s;
u_int i;
struct input_arg *iarg;
-
+
log_debug2("-- sq %zu: %hhu (%c): %u [sx=%u, sy=%u, cx=%u, cy=%u, "
"ru=%u, rl=%u]", ictx->off, ch, ch, ARRAY_LENGTH(&ictx->args),
screen_size_x(s), screen_size_y(s), s->cx, s->cy, s->rupper,
@@ -687,8 +651,7 @@ input_handle_sequence(u_char ch, struct input_ctx *ictx)
void
input_handle_sequence_cuu(struct input_ctx *ictx)
{
- struct screen *s = &ictx->w->screen;
- uint16_t n;
+ uint16_t n;
if (ictx->private != '\0')
return;
@@ -697,21 +660,16 @@ input_handle_sequence_cuu(struct input_ctx *ictx)
return;
if (input_get_argument(ictx, 0, &n, 1) != 0)
return;
+ if (n == 0)
+ n = 1;
- if (n == 0 || n > s->cy) {
- log_debug3("cuu: out of range: %hu", n);
- return;
- }
-
- s->cy -= n;
- input_write(ictx, TTY_CURSORUP, n);
+ screen_write_cursor_up(&ictx->ctx, n);
}
void
input_handle_sequence_cud(struct input_ctx *ictx)
{
- struct screen *s = &ictx->w->screen;
- uint16_t n;
+ uint16_t n;
if (ictx->private != '\0')
return;
@@ -720,20 +678,16 @@ input_handle_sequence_cud(struct input_ctx *ictx)
return;
if (input_get_argument(ictx, 0, &n, 1) != 0)
return;
-
if (n == 0)
- return;
- input_limit(n, 1, screen_last_y(s) - s->cy);
+ n = 1;
- s->cy += n;
- input_write(ictx, TTY_CURSORDOWN, n);
+ screen_write_cursor_down(&ictx->ctx, n);
}
void
input_handle_sequence_cuf(struct input_ctx *ictx)
{
- struct screen *s = &ictx->w->screen;
- uint16_t n;
+ uint16_t n;
if (ictx->private != '\0')
return;
@@ -742,20 +696,16 @@ input_handle_sequence_cuf(struct input_ctx *ictx)
return;
if (input_get_argument(ictx, 0, &n, 1) != 0)
return;
-
if (n == 0)
- return;
- input_limit(n, 1, screen_last_x(s) - s->cx);
+ n = 1;
- s->cx += n;
- input_write(ictx, TTY_CURSORRIGHT, n);
+ screen_write_cursor_right(&ictx->ctx, n);
}
void
input_handle_sequence_cub(struct input_ctx *ictx)
{
- struct screen *s = &ictx->w->screen;
- uint16_t n;
+ uint16_t n;
if (ictx->private != '\0')
return;
@@ -764,21 +714,16 @@ input_handle_sequence_cub(struct input_ctx *ictx)
return;
if (input_get_argument(ictx, 0, &n, 1) != 0)
return;
+ if (n == 0)
+ n = 1;
- if (n == 0 || n > s->cx) {
- log_debug3("cub: out of range: %hu", n);
- return;
- }
-
- s->cx -= n;
- input_write(ictx, TTY_CURSORLEFT, n);
+ screen_write_cursor_left(&ictx->ctx, n);
}
void
input_handle_sequence_dch(struct input_ctx *ictx)
{
- struct screen *s = &ictx->w->screen;
- uint16_t n;
+ uint16_t n;
if (ictx->private != '\0')
return;
@@ -787,20 +732,16 @@ input_handle_sequence_dch(struct input_ctx *ictx)
return;
if (input_get_argument(ictx, 0, &n, 1) != 0)
return;
-
if (n == 0)
- return;
- input_limit(n, 1, screen_last_x(s) - s->cx);
+ n = 1;
- screen_display_delete_characters(s, s->cx, s->cy, n);
- input_write(ictx, TTY_DELETECHARACTER, n);
+ screen_write_delete_characters(&ictx->ctx, n);
}
void
input_handle_sequence_dl(struct input_ctx *ictx)
{
- struct screen *s = &ictx->w->screen;
- uint16_t n;
+ uint16_t n;
if (ictx->private != '\0')
return;
@@ -809,23 +750,16 @@ input_handle_sequence_dl(struct input_ctx *ictx)
return;
if (input_get_argument(ictx, 0, &n, 1) != 0)
return;
-
if (n == 0)
- return;
- input_limit(n, 1, screen_last_y(s) - s->cy);
+ n = 1;
- if (s->cy < s->rupper || s->cy > s->rlower)
- screen_display_delete_lines(s, s->cy, n);
- else
- screen_display_delete_lines_region(s, s->cy, n);
- input_write(ictx, TTY_DELETELINE, n);
+ screen_write_delete_lines(&ictx->ctx, n);
}
void
input_handle_sequence_ich(struct input_ctx *ictx)
{
- struct screen *s = &ictx->w->screen;
- uint16_t n;
+ uint16_t n;
if (ictx->private != '\0')
return;
@@ -834,20 +768,16 @@ input_handle_sequence_ich(struct input_ctx *ictx)
return;
if (input_get_argument(ictx, 0, &n, 1) != 0)
return;
-
if (n == 0)
- return;
- input_limit(n, 1, screen_last_x(s) - s->cx);
+ n = 1;
- screen_display_insert_characters(s, s->cx, s->cy, n);
- input_write(ictx, TTY_INSERTCHARACTER, n);
+ screen_write_insert_characters(&ictx->ctx, n);
}
void
input_handle_sequence_il(struct input_ctx *ictx)
{
- struct screen *s = &ictx->w->screen;
- uint16_t n;
+ uint16_t n;
if (ictx->private != '\0')
return;
@@ -856,23 +786,17 @@ input_handle_sequence_il(struct input_ctx *ictx)
return;
if (input_get_argument(ictx, 0, &n, 1) != 0)
return;
-
if (n == 0)
- return;
- input_limit(n, 1, screen_last_y(s) - s->cy);
+ n = 1;
- if (s->cy < s->rupper || s->cy > s->rlower)
- screen_display_insert_lines(s, s->cy, n);
- else
- screen_display_insert_lines_region(s, s->cy, n);
- input_write(ictx, TTY_INSERTLINE, n);
+ screen_write_insert_lines(&ictx->ctx, n);
}
void
input_handle_sequence_vpa(struct input_ctx *ictx)
{
- struct screen *s = &ictx->w->screen;
- uint16_t n;
+ struct screen *s = ictx->ctx.s;
+ uint16_t n;
if (ictx->private != '\0')
return;
@@ -881,20 +805,17 @@ input_handle_sequence_vpa(struct input_ctx *ictx)
return;
if (input_get_argument(ictx, 0, &n, 1) != 0)
return;
-
if (n == 0)
- return;
- input_limit(n, 1, screen_size_y(s));
+ n = 1;
- s->cy = n - 1;
- input_write(ictx, TTY_CURSORMOVE, s->cy, s->cx);
+ screen_write_move_cursor(&ictx->ctx, s->cx, n - 1);
}
void
input_handle_sequence_hpa(struct input_ctx *ictx)
{
- struct screen *s = &ictx->w->screen;
- uint16_t n;
+ struct screen *s = ictx->ctx.s;
+ uint16_t n;
if (ictx->private != '\0')
return;
@@ -903,20 +824,16 @@ input_handle_sequence_hpa(struct input_ctx *ictx)
return;
if (input_get_argument(ictx, 0, &n, 1) != 0)
return;
-
if (n == 0)
- return;
- input_limit(n, 1, screen_size_x(s));
+ n = 1;
- s->cx = n - 1;
- input_write(ictx, TTY_CURSORMOVE, s->cy, s->cx);
+ screen_write_move_cursor(&ictx->ctx, n - 1, s->cy);
}
void
input_handle_sequence_cup(struct input_ctx *ictx)
{
- struct screen *s = &ictx->w->screen;
- uint16_t n, m;
+ uint16_t n, m;
if (ictx->private != '\0')
return;
@@ -927,21 +844,18 @@ input_handle_sequence_cup(struct input_ctx *ictx)
return;
if (input_get_argument(ictx, 1, &m, 1) != 0)
return;
+ if (n == 0)
+ n = 1;
+ if (m == 0)
+ m = 1;
- input_limit(n, 1, screen_size_y(s));
- input_limit(m, 1, screen_size_x(s));
-
- s->cx = m - 1;
- s->cy = n - 1;
- input_write(ictx, TTY_CURSORMOVE, s->cy, s->cx);
+ screen_write_move_cursor(&ictx->ctx, m - 1, n - 1);
}
void
input_handle_sequence_ed(struct input_ctx *ictx)
{
- struct screen *s = &ictx->w->screen;
- uint16_t n;
- u_int i;
+ uint16_t n;
if (ictx->private != '\0')
return;
@@ -950,31 +864,15 @@ input_handle_sequence_ed(struct input_ctx *ictx)
return;
if (input_get_argument(ictx, 0, &n, 0) != 0)
return;
-
if (n > 2)
return;
switch (n) {
case 0:
- screen_display_fill_cursor_eos(
- s, SCREEN_DEFDATA, s->attr, s->colr);
-
- input_write(ictx, TTY_CLEARENDOFLINE);
- for (i = s->cy + 1; i < screen_size_y(s); i++) {
- input_write(ictx, TTY_CURSORMOVE, i, 0);
- input_write(ictx, TTY_CLEARENDOFLINE);
- }
- input_write(ictx, TTY_CURSORMOVE, s->cy, s->cx);
+ screen_write_fill_end_of_screen(&ictx->ctx);
break;
case 2:
- screen_display_fill_lines(
- s, 0, screen_size_y(s), SCREEN_DEFDATA, s->attr, s->colr);
-
- for (i = 0; i < screen_size_y(s); i++) {
- input_write(ictx, TTY_CURSORMOVE, i, 0);
- input_write(ictx, TTY_CLEARENDOFLINE);
- }
- input_write(ictx, TTY_CURSORMOVE, s->cy, s->cx);
+ screen_write_fill_screen(&ictx->ctx);
break;
}
}
@@ -982,8 +880,7 @@ input_handle_sequence_ed(struct input_ctx *ictx)
void
input_handle_sequence_el(struct input_ctx *ictx)
{
- struct screen *s = &ictx->w->screen;
- uint16_t n;
+ uint16_t n;
if (ictx->private != '\0')
return;
@@ -992,25 +889,18 @@ input_handle_sequence_el(struct input_ctx *ictx)
return;
if (input_get_argument(ictx, 0, &n, 0) != 0)
return;
-
if (n > 2)
return;
switch (n) {
case 0:
- screen_display_fill_cursor_eol(
- s, SCREEN_DEFDATA, s->attr, s->colr);
- input_write(ictx, TTY_CLEARENDOFLINE);
+ screen_write_fill_end_of_line(&ictx->ctx);
break;
case 1:
- screen_display_fill_cursor_bol(
- s, SCREEN_DEFDATA, s->attr, s->colr);
- input_write(ictx, TTY_CLEARSTARTOFLINE);
+ screen_write_fill_start_of_line(&ictx->ctx);
break;
case 2:
- screen_display_fill_line(
- s, s->cy, SCREEN_DEFDATA, s->attr, s->colr);
- input_write(ictx, TTY_CLEARLINE);
+ screen_write_fill_line(&ictx->ctx);
break;
}
}
@@ -1018,8 +908,7 @@ input_handle_sequence_el(struct input_ctx *ictx)
void
input_handle_sequence_sm(struct input_ctx *ictx)
{
- struct screen *s = &ictx->w->screen;
- uint16_t n;
+ uint16_t n;
if (ARRAY_LENGTH(&ictx->args) > 1)
return;
@@ -1029,16 +918,13 @@ input_handle_sequence_sm(struct input_ctx *ictx)
if (ictx->private == '?') {
switch (n) {
case 1: /* GATM */
- s->mode |= MODE_KCURSOR;
- input_write(ictx, TTY_KCURSORON);
+ screen_write_set_mode(&ictx->ctx, MODE_KCURSOR);
break;
case 25: /* TCEM */
- s->mode |= MODE_CURSOR;
- input_write(ictx, TTY_CURSORON);
+ screen_write_set_mode(&ictx->ctx, MODE_CURSOR);
break;
case 1000:
- s->mode |= MODE_MOUSE;
- input_write(ictx, TTY_MOUSEON);
+ screen_write_set_mode(&ictx->ctx, MODE_MOUSE);
break;
default:
log_debug("unknown SM [%hhu]: %u", ictx->private, n);
@@ -1047,8 +933,7 @@ input_handle_sequence_sm(struct input_ctx *ictx)
} else {
switch (n) {
case 4: /* IRM */
- s->mode |= MODE_INSERT;
- input_write(ictx, TTY_INSERTON);
+ screen_write_set_mode(&ictx->ctx, MODE_INSERT);
break;
case 34:
/* Cursor high visibility not supported. */
@@ -1063,7 +948,6 @@ input_handle_sequence_sm(struct input_ctx *ictx)
void
input_handle_sequence_rm(struct input_ctx *ictx)
{
- struct screen *s = &ictx->w->screen;
uint16_t n;
if (ARRAY_LENGTH(&ictx->args) > 1)
@@ -1074,16 +958,13 @@ input_handle_sequence_rm(struct input_ctx *ictx)
if (ictx->private == '?') {
switch (n) {
case 1: /* GATM */
- s->mode &= ~MODE_KCURSOR;
- input_write(ictx, TTY_KCURSOROFF);
+ screen_write_clear_mode(&ictx->ctx, MODE_KCURSOR);
break;
case 25: /* TCEM */
- s->mode &= ~MODE_CURSOR;
- input_write(ictx, TTY_CURSOROFF);
+ screen_write_clear_mode(&ictx->ctx, MODE_CURSOR);
break;
case 1000:
- s->mode &= ~MODE_MOUSE;
- input_write(ictx, TTY_MOUSEOFF);
+ screen_write_clear_mode(&ictx->ctx, MODE_MOUSE);
break;
default:
log_debug("unknown RM [%hhu]: %u", ictx->private, n);
@@ -1092,8 +973,7 @@ input_handle_sequence_rm(struct input_ctx *ictx)
} else if (ictx->private == '\0') {
switch (n) {
case 4: /* IRM */
- s->mode &= ~MODE_INSERT;
- input_write(ictx, TTY_INSERTOFF);
+ screen_write_clear_mode(&ictx->ctx, MODE_INSERT);
break;
case 34:
/* Cursor high visibility not supported. */
@@ -1108,9 +988,9 @@ input_handle_sequence_rm(struct input_ctx *ictx)
void
input_handle_sequence_dsr(struct input_ctx *ictx)
{
- struct screen *s = &ictx->w->screen;
- uint16_t n;
- char reply[32];
+ struct screen *s = ictx->ctx.s;
+ uint16_t n;
+ char reply[32];
if (ARRAY_LENGTH(&ictx->args) > 1)
return;
@@ -1133,8 +1013,8 @@ input_handle_sequence_dsr(struct input_ctx *ictx)
void
input_handle_sequence_decstbm(struct input_ctx *ictx)
{
- struct screen *s = &ictx->w->screen;
- uint16_t n, m;
+ struct screen *s = ictx->ctx.s;
+ uint16_t n, m;
if (ictx->private != '\0')
return;
@@ -1145,78 +1025,64 @@ input_handle_sequence_decstbm(struct input_ctx *ictx)
return;
if (input_get_argument(ictx, 1, &m, 0) != 0)
return;
-
- /* Special case: both zero restores to entire screen. */
- /* XXX this will catch [0;0r and [;r etc too, is this right? */
- if (n == 0 && m == 0) {
+ if (n == 0)
n = 1;
+ if (m == 0)
m = screen_size_y(s);
- }
-
- input_limit(n, 1, screen_size_y(s));
- input_limit(m, 1, screen_size_y(s));
-
- if (n > m) {
- log_debug3("decstbm: out of range: %hu,%hu", n, m);
- return;
- }
-
- /* Cursor moves to top-left. */
- s->cx = 0;
- s->cy = n - 1;
- s->rupper = n - 1;
- s->rlower = m - 1;
- input_write(ictx, TTY_SCROLLREGION, s->rupper, s->rlower);
+ screen_write_set_region(&ictx->ctx, n - 1, m - 1);
}
void
input_handle_sequence_sgr(struct input_ctx *ictx)
{
- struct screen *s = &ictx->w->screen;
- u_int i, n;
- uint16_t m;
+ struct screen *s = ictx->ctx.s;
+ u_int i, n;
+ uint16_t m;
+ u_char attr, colr;
n = ARRAY_LENGTH(&ictx->args);
if (n == 0) {
- s->attr = 0;
- s->colr = SCREEN_DEFCOLR;
+ attr = 0;
+ colr = SCREEN_DEFCOLR;
} else {
+ attr = s->attr;
+ colr = s->colr;
for (i = 0; i < n; i++) {
if (input_get_argument(ictx, i, &m, 0) != 0)
return;
switch (m) {
case 0:
case 10:
- s->attr &= ATTR_CHARSET;
- s->colr = SCREEN_DEFCOLR;
+ attr &= ATTR_CHARSET;
+ colr = SCREEN_DEFCOLR;
break;
case 1:
- s->attr |= ATTR_BRIGHT;
+ attr |= ATTR_BRIGHT;
break;
case 2:
- s->attr |= ATTR_DIM;
+ attr |= ATTR_DIM;
break;
case 3:
- s->attr |= ATTR_ITALICS;
+ attr |= ATTR_ITALICS;
break;
case 4:
- s->attr |= ATTR_UNDERSCORE;
+ attr |= ATTR_UNDERSCORE;
break;
case 5:
- s->attr |= ATTR_BLINK;
+ attr |= ATTR_BLINK;
break;
case 7:
- s->attr |= ATTR_REVERSE;
+ attr |= ATTR_REVERSE;
break;
case 8:
- s->attr |= ATTR_HIDDEN;
+ attr |= ATTR_HIDDEN;
break;
case 23:
- s->attr &= ~ATTR_ITALICS;
+ attr &= ~ATTR_ITALICS;
break;
case 24:
- s->attr &= ~ATTR_UNDERSCORE;
+ attr &= ~ATTR_UNDERSCORE;
break;
case 30:
case 31:
@@ -1226,12 +1092,12 @@ input_handle_sequence_sgr(struct input_ctx *ictx)
case 35:
case 36:
case 37:
- s->colr &= 0x0f;
- s->colr |= (m - 30) << 4;
+ colr &= 0x0f;
+ colr |= (m - 30) << 4;
break;
case 39:
- s->colr &= 0x0f;
- s->colr |= 0x80;
+ colr &= 0x0f;
+ colr |= 0x80;
break;
case 40:
case 41:
@@ -1241,15 +1107,15 @@ input_handle_sequence_sgr(struct input_ctx *ictx)
case 45:
case 46:
case 47:
- s->colr &= 0xf0;
- s->colr |= m - 40;
+ colr &= 0xf0;
+ colr |= m - 40;
break;
case 49:
- s->colr &= 0xf0;
- s->colr |= 0x08;
+ colr &= 0xf0;
+ colr |= 0x08;
break;
}
}
}
- input_write(ictx, TTY_ATTRIBUTES, s->attr, s->colr);
+ screen_write_set_attributes(&ictx->ctx, attr, colr);
}
diff --git a/key-bindings.c b/key-bindings.c
index d2f51b25..8889d81a 100644
--- a/key-bindings.c
+++ b/key-bindings.c
@@ -1,4 +1,4 @@
-/* $Id: key-bindings.c,v 1.22 2007-11-27 19:23:33 nicm Exp $ */
+/* $Id: key-bindings.c,v 1.23 2007-12-06 09:46:22 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -84,7 +84,7 @@ key_bindings_init(void)
{ 'S', &cmd_list_sessions_entry, NULL },
{ 's', &cmd_list_sessions_entry, NULL },
{ 'W', &cmd_list_windows_entry, NULL },
- { 'w', &cmd_list_windows_entry, NULL },
+ { 'w', &cmd_list_windows_entry, NULL },
{ '?', &cmd_list_keys_entry, NULL },
{ '/', &cmd_list_keys_entry, NULL },
{ 'C', &cmd_new_window_entry, NULL },
@@ -140,7 +140,7 @@ key_bindings_free(void)
cmd_free(bd->cmd);
xfree(bd);
}
-
+
ARRAY_FREE(&key_bindings);
}
@@ -168,6 +168,7 @@ key_bindings_print(struct cmd_ctx *ctx, const char *fmt, ...)
if (w->mode == NULL) {
w->mode = &window_more_mode;
w->mode->init(w);
+ server_redraw_window(w);
} else if (w->mode != &window_more_mode)
return;
@@ -202,7 +203,4 @@ key_bindings_dispatch(int key, struct client *c)
ctx.flags = CMD_KEY;
cmd_exec(bd->cmd, &ctx);
-
- if (c->session->curw->window->mode == &window_more_mode)
- server_redraw_window(c->session->curw->window);
}
diff --git a/resize.c b/resize.c
index c69ef08d..94a7621b 100644
--- a/resize.c
+++ b/resize.c
@@ -1,4 +1,4 @@
-/* $Id: resize.c,v 1.8 2007-12-02 23:00:22 nicm Exp $ */
+/* $Id: resize.c,v 1.9 2007-12-06 09:46:22 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -33,7 +33,7 @@
* smallest client it is attached to, and resize it to that size. Then for
* every window, find the smallest session it is attached to, resize it to that
* size and clear and redraw every client with it as the current window.
- *
+ *
* This is quite inefficient - better/additional data structures are needed
* to make it better.
*
@@ -50,7 +50,7 @@ recalculate_sizes(void)
struct client *c;
struct window *w;
u_int i, j, ssx, ssy;
-
+
for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
s = ARRAY_ITEM(&sessions, i);
if (s == NULL)
@@ -105,17 +105,17 @@ recalculate_sizes(void)
}
}
if (ssx == UINT_MAX || ssy == UINT_MAX) {
- w->screen.mode |= MODE_HIDDEN;
+ w->flags |= WINDOW_HIDDEN;
continue;
}
- w->screen.mode &= ~MODE_HIDDEN;
+ w->flags &= ~WINDOW_HIDDEN;
- if (screen_size_x(&w->screen) == ssx &&
- screen_size_y(&w->screen) == ssy)
+ if (screen_size_x(&w->base) == ssx &&
+ screen_size_y(&w->base) == ssy)
continue;
log_debug("window size %u,%u (was %u,%u)", ssx, ssy,
- screen_size_x(&w->screen), screen_size_y(&w->screen));
+ screen_size_x(&w->base), screen_size_y(&w->base));
server_clear_window(w);
window_resize(w, ssx, ssy);
diff --git a/screen-display.c b/screen-display.c
index 1985570e..4124a61e 100644
--- a/screen-display.c
+++ b/screen-display.c
@@ -1,4 +1,4 @@
-/* $Id: screen-display.c,v 1.9 2007-11-26 22:22:18 nicm Exp $ */
+/* $Id: screen-display.c,v 1.10 2007-12-06 09:46:22 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -22,17 +22,20 @@
#include "tmux.h"
-/*
- * Screen display modification functions. These alter the displayed portion
- * of the screen.
- */
+/* Set a cell. */
+void
+screen_display_set_cell(
+ struct screen *s, u_int px, u_int py, u_char data, u_char attr, u_char colr)
+{
+ screen_set_cell(s, screen_x(s, px), screen_y(s, py), data, attr, colr);
+}
/* Create a region of lines. */
void
screen_display_make_lines(struct screen *s, u_int py, u_int ny)
{
if (ny == 0 || !screen_in_y(s, py) || !screen_in_y(s, py + ny - 1))
- fatalx("bad value");
+ return;
screen_make_lines(s, screen_y(s, py), ny);
}
@@ -41,7 +44,7 @@ void
screen_display_free_lines(struct screen *s, u_int py, u_int ny)
{
if (ny == 0 || !screen_in_y(s, py) || !screen_in_y(s, py + ny - 1))
- fatalx("bad value");
+ return;
screen_free_lines(s, screen_y(s, py), ny);
}
@@ -50,116 +53,25 @@ void
screen_display_move_lines(struct screen *s, u_int dy, u_int py, u_int ny)
{
if (ny == 0 || !screen_in_y(s, py) || !screen_in_y(s, py + ny - 1))
- fatalx("bad value");
+ return;
if (!screen_in_y(s, dy) || !screen_in_y(s, dy + ny - 1) || dy == py)
- fatalx("bad value");
+ return;
screen_move_lines(s, screen_y(s, dy), screen_y(s, py), ny);
}
-/* Fill a set of lines. */
-void
-screen_display_fill_lines(
- struct screen *s, u_int py, u_int ny, u_char data, u_char attr, u_char colr)
-{
- if (ny == 0 || !screen_in_y(s, py) || !screen_in_y(s, py + ny - 1))
- fatalx("bad value");
- screen_fill_lines(s, screen_y(s, py), ny, data, attr, colr);
-}
-
-/* Fill a set of cellss. */
-void
-screen_display_fill_cells(struct screen *s,
- u_int px, u_int py, u_int nx, u_char data, u_char attr, u_char colr)
-{
- if (nx == 0 || !screen_in_x(s, px) || !screen_in_y(s, py))
- fatalx("bad value");
- screen_fill_cells(
- s, screen_x(s, px), screen_y(s, py), nx, data, attr, colr);
-}
-
-/* Fill entire screen. */
-void
-screen_display_fill_screen(
- struct screen *s, u_char data, u_char attr, u_char colr)
-{
- screen_display_fill_lines(s, 0, screen_size_y(s), data, attr, colr);
-}
-
-/* Fill end of screen from cursor. */
-void
-screen_display_fill_cursor_eos(
- struct screen *s, u_char data, u_char attr, u_char colr)
-{
- screen_display_fill_cursor_eol(s, data, attr, colr);
- if (s->cy != screen_last_y(s)) {
- screen_display_fill_lines(
- s, s->cy, screen_size_y(s) - s->cy, data, attr, colr);
- }
-}
-
-/* Fill beginning of screen from cursor. */
+/* Fill a set of cells. */
void
-screen_display_fill_cursor_bos(
- struct screen *s, u_char data, u_char attr, u_char colr)
+screen_display_fill_area(struct screen *s, u_int px, u_int py,
+ u_int nx, u_int ny, u_char data, u_char attr, u_char colr)
{
- screen_display_fill_lines(s, 0, s->cy, data, attr, colr);
-}
-
-/* Fill a single line. */
-void
-screen_display_fill_line(
- struct screen *s, u_int py, u_char data, u_char attr, u_char colr)
-{
- screen_display_fill_lines(s, py, 1, data, attr, colr);
-}
-
-/* Fill cursor to beginning of line. */
-void
-screen_display_fill_cursor_bol(
- struct screen *s, u_char data, u_char attr, u_char colr)
-{
- screen_display_fill_cells(s, 0, s->cy, s->cx, data, attr, colr);
-}
-
-/* Fill cursor to end of line. */
-void
-screen_display_fill_cursor_eol(
- struct screen *s, u_char data, u_char attr, u_char colr)
-{
- screen_display_fill_cells(
- s, s->cx, s->cy, screen_size_x(s) - s->cx, data, attr, colr);
-}
-
-/* Set character at cursor. */
-void
-screen_display_cursor_set(struct screen *s, u_char ch)
-{
- u_int px, py;
-
- px = screen_x(s, s->cx);
- py = screen_y(s, s->cy);
-
- screen_set_cell(s, px, py, ch, s->attr, s->colr);
-}
-
-/* Move cursor up and scroll if necessary. */
-void
-screen_display_cursor_up(struct screen *s)
-{
- if (s->cy == s->rupper)
- screen_display_scroll_region_down(s);
- else if (s->cy > 0)
- s->cy--;
-}
-
-/* Move cursor down and scroll if necessary. */
-void
-screen_display_cursor_down(struct screen *s)
-{
- if (s->cy == s->rlower)
- screen_display_scroll_region_up(s);
- else if (s->cy < screen_last_y(s))
- s->cy++;
+ if (nx == 0 || ny == 0)
+ return;
+ if (!screen_in_x(s, px) || !screen_in_y(s, py))
+ return;
+ if (!screen_in_x(s, px + nx - 1) || !screen_in_y(s, py - ny - 1))
+ return;
+ screen_fill_area(
+ s, screen_x(s, px), screen_y(s, py), nx, ny, data, attr, colr);
}
/* Scroll region up. */
@@ -167,13 +79,13 @@ void
screen_display_scroll_region_up(struct screen *s)
{
u_int ny, sy;
-
+
/*
* If the region is the entire screen, this is easy-peasy. Allocate
* a new line and adjust the history size.
* XXX should this be done somewhere else?
*/
- if (s->rupper == 0 && s->rlower == screen_last_y(s)) {
+ if (s->rupper == 0 && s->rlower == screen_last_y(s)) {
if (s->hsize == s->hlimit) {
/* If the limit is hit, free 10% and shift up. */
ny = s->hlimit / 10;
@@ -197,7 +109,7 @@ screen_display_scroll_region_up(struct screen *s)
return;
}
- /*
+ /*
* Scroll scrolling region up:
* - delete rupper
* - move rupper + 1 to rlower to rupper
@@ -213,7 +125,7 @@ screen_display_scroll_region_up(struct screen *s)
screen_display_free_lines(s, s->rupper, 1);
if (s->rupper != s->rlower) {
- screen_display_move_lines(s,
+ screen_display_move_lines(s,
s->rupper, s->rupper + 1, s->rlower - s->rupper);
}
@@ -224,7 +136,7 @@ screen_display_scroll_region_up(struct screen *s)
void
screen_display_scroll_region_down(struct screen *s)
{
- /*
+ /*
* Scroll scrolling region down:
* - delete rlower
* - move rupper to rlower - 1 to rupper + 1
@@ -252,14 +164,14 @@ void
screen_display_insert_lines(struct screen *s, u_int py, u_int ny)
{
if (!screen_in_y(s, py))
- fatalx("bad value");
+ return;
if (ny == 0)
- fatalx("bad value");
+ return;
if (py + ny > screen_last_y(s))
ny = screen_size_y(s) - py;
if (ny == 0)
- return;
+ return;
/*
* Insert range of ny lines at py:
@@ -289,9 +201,9 @@ void
screen_display_insert_lines_region(struct screen *s, u_int py, u_int ny)
{
if (!screen_in_region(s, py))
- fatalx("bad value");
+ return;
if (ny == 0)
- fatalx("bad value");
+ return;
if (py + ny > s->rlower)
ny = (s->rlower + 1) - py;
@@ -326,9 +238,9 @@ void
screen_display_delete_lines(struct screen *s, u_int py, u_int ny)
{
if (!screen_in_y(s, py))
- fatalx("bad value");
+ return;
if (ny == 0)
- fatalx("bad value");
+ return;
if (py + ny > screen_last_y(s))
ny = screen_size_y(s) - py;
@@ -363,9 +275,9 @@ void
screen_display_delete_lines_region(struct screen *s, u_int py, u_int ny)
{
if (!screen_in_region(s, py))
- fatalx("bad value");
+ return;
if (ny == 0)
- fatalx("bad value");
+ return;
if (py + ny > s->rlower)
ny = (s->rlower + 1) - py;
@@ -402,7 +314,7 @@ screen_display_insert_characters(struct screen *s, u_int px, u_int py, u_int nx)
u_int mx;
if (!screen_in_x(s, px) || !screen_in_y(s, py))
- fatalx("bad value");
+ return;
if (px + nx > screen_last_x(s))
nx = screen_last_x(s) - px;
@@ -439,7 +351,7 @@ screen_display_delete_characters(struct screen *s, u_int px, u_int py, u_int nx)
u_int mx;
if (!screen_in_x(s, px) || !screen_in_y(s, py))
- fatalx("bad value");
+ return;
if (px + nx > screen_last_x(s))
nx = screen_last_x(s) - px;
@@ -468,3 +380,28 @@ screen_display_delete_characters(struct screen *s, u_int px, u_int py, u_int nx)
memset(&s->grid_attr[py][screen_size_x(s) - nx], SCREEN_DEFATTR, nx);
memset(&s->grid_colr[py][screen_size_x(s) - nx], SCREEN_DEFCOLR, nx);
}
+
+/* Fill cells from another screen, with an offset. */
+void
+screen_display_copy_area(struct screen *dst, struct screen *src,
+ u_int px, u_int py, u_int nx, u_int ny, u_int ox, u_int oy)
+{
+ u_int i, j;
+ u_char data, attr, colr;
+
+ if (nx == 0 || ny == 0)
+ return;
+ if (!screen_in_x(dst, px) || !screen_in_y(dst, py))
+ return;
+ if (!screen_in_x(dst, px + nx - 1) || !screen_in_y(dst, py + ny - 1))
+ return;
+
+ for (i = py; i < py + ny; i++) {
+ for (j = px; j < px + nx; j++) {
+ screen_get_cell(src,
+ screen_x(src, j) + ox, screen_y(src, i) - oy,
+ &data, &attr, &colr);
+ screen_display_set_cell(dst, j, i, data, attr, colr);
+ }
+ }
+}
diff --git a/screen-redraw.c b/screen-redraw.c
new file mode 100644
index 00000000..76d7c96f
--- /dev/null
+++ b/screen-redraw.c
@@ -0,0 +1,218 @@
+/* $Id: screen-redraw.c,v 1.1 2007-12-06 09:46:22 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"
+
+void screen_redraw_get_cell(struct screen_redraw_ctx *,
+ u_int, u_int, u_char *, u_char *, u_char *);
+
+/* Initialise redrawing with a window. */
+void
+screen_redraw_start_window(struct screen_redraw_ctx *ctx, struct window *w)
+{
+ struct screen *t = w->screen;
+
+ screen_redraw_start(ctx, t, tty_write_window, w);
+}
+
+/* Initialise redrawing with a client. */
+void
+screen_redraw_start_client(struct screen_redraw_ctx *ctx, struct client *c)
+{
+ struct screen *t = c->session->curw->window->screen;
+
+ screen_redraw_start(ctx, t, tty_write_client, c);
+}
+
+/* Initialise redrawing with a session. */
+void
+screen_redraw_start_session(struct screen_redraw_ctx *ctx, struct session *s)
+{
+ struct screen *t = s->curw->window->screen;
+
+ screen_redraw_start(ctx, t, tty_write_session, s);
+}
+
+/* Initialise for redrawing. */
+void
+screen_redraw_start(struct screen_redraw_ctx *ctx,
+ struct screen *s, void (*write)(void *, int, ...), void *data)
+{
+ ctx->write = write;
+ ctx->data = data;
+
+ ctx->s = s;
+
+ /*
+ * Save screen cursor position. Emulation of some TTY_* commands
+ * requires this to be correct in the screen, so rather than having
+ * a local copy and just manipulating it, save the screen's values,
+ * modify them during redraw, and restore them when finished.
+ */
+ ctx->saved_cx = s->cx;
+ ctx->saved_cy = s->cy;
+
+ ctx->write(ctx->data, TTY_ATTRIBUTES, s->attr, s->colr);
+ ctx->write(ctx->data, TTY_SCROLLREGION, 0, screen_last_y(s));
+ ctx->write(ctx->data, TTY_CURSORMOVE, s->cy, s->cx);
+ ctx->write(ctx->data, TTY_CURSOROFF);
+ ctx->write(ctx->data, TTY_MOUSEOFF);
+}
+
+/* Finish redrawing. */
+void
+screen_redraw_stop(struct screen_redraw_ctx *ctx)
+{
+ struct screen *s = ctx->s;
+
+ s->cx = ctx->saved_cx;
+ s->cy = ctx->saved_cy;
+
+ ctx->write(ctx->data, TTY_ATTRIBUTES, s->attr, s->colr);
+ ctx->write(ctx->data, TTY_SCROLLREGION, s->rupper, s->rlower);
+ ctx->write(ctx->data, TTY_CURSORMOVE, s->cy, s->cx);
+ if (s->mode & MODE_CURSOR)
+ ctx->write(ctx->data, TTY_CURSORON);
+ if (s->mode & MODE_MOUSE)
+ ctx->write(ctx->data, TTY_MOUSEON);
+}
+
+/* Get cell data. */
+void
+screen_redraw_get_cell(struct screen_redraw_ctx *ctx,
+ u_int px, u_int py, u_char *data, u_char *attr, u_char *colr)
+{
+ struct screen *s = ctx->s;
+
+ screen_get_cell(s, screen_x(s, px), screen_y(s, py), data, attr, colr);
+}
+
+/* Move cursor. */
+void
+screen_redraw_move_cursor(struct screen_redraw_ctx *ctx, u_int px, u_int py)
+{
+ if (px != ctx->s->cx || py != ctx->s->cy) {
+ ctx->s->cx = px;
+ ctx->s->cy = py;
+ ctx->write(ctx->data, TTY_CURSORMOVE, ctx->s->cy, ctx->s->cx);
+ }
+}
+
+/* Set attributes. */
+void
+screen_redraw_set_attributes(
+ struct screen_redraw_ctx *ctx, u_int attr, u_int colr)
+{
+ ctx->write(ctx->data, TTY_ATTRIBUTES, attr, colr);
+}
+
+/* Write string. */
+void printflike2
+screen_redraw_write_string(struct screen_redraw_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->s->cx > screen_last_x(s))
+ break;
+ if (*ptr < 0x20)
+ continue;
+ ctx->write(ctx->data, TTY_CHARACTER, *ptr);
+ ctx->s->cx++;
+ }
+
+ xfree(msg);
+}
+
+/* Clear screen. */
+void
+screen_redraw_clear_screen(struct screen_redraw_ctx *ctx)
+{
+ u_int i;
+
+ for (i = 0; i < screen_size_y(ctx->s); i++) {
+ screen_redraw_move_cursor(ctx, 0, i);
+ ctx->write(ctx->data, TTY_CLEARLINE);
+ }
+}
+
+/* Clear to end of line. */
+void
+screen_redraw_clear_end_of_line(struct screen_redraw_ctx *ctx)
+{
+ ctx->write(ctx->data, TTY_CLEARENDOFLINE);
+}
+
+/* Redraw single cell. */
+void
+screen_redraw_cell(struct screen_redraw_ctx *ctx, u_int px, u_int py)
+{
+ u_char data, attr, colr;
+
+ screen_redraw_move_cursor(ctx, px, py);
+ screen_redraw_get_cell(ctx, px, py, &data, &attr, &colr);
+
+ ctx->write(ctx->data, TTY_ATTRIBUTES, attr, colr);
+ ctx->write(ctx->data, TTY_CHARACTER, data);
+
+ ctx->s->cx++;
+}
+
+/* Redraw area of cells. */
+void
+screen_redraw_area(
+ struct screen_redraw_ctx *ctx, u_int px, u_int py, u_int nx, u_int ny)
+{
+ u_int i, j;
+
+ for (i = py; i < py + ny; i++) {
+ for (j = px; j < px + nx; j++)
+ screen_redraw_cell(ctx, j, i);
+ }
+}
+
+/* Draw set of lines. */
+void
+screen_redraw_lines(struct screen_redraw_ctx *ctx, u_int py, u_int ny)
+{
+ u_int i, cx, sx;
+
+ sx = screen_size_x(ctx->s);
+ for (i = py; i < py + ny; i++) {
+ cx = ctx->s->grid_size[screen_y(ctx->s, i)];
+ if (ctx->s->sel.flag || sx < 5 || cx >= sx - 5) {
+ screen_redraw_area(ctx, 0, i, screen_size_x(ctx->s), 1);
+ continue;
+ }
+ screen_redraw_area(ctx, 0, i, cx, 1);
+ screen_redraw_move_cursor(ctx, cx, i);
+ screen_redraw_set_attributes(
+ ctx, SCREEN_DEFATTR, SCREEN_DEFCOLR);
+ ctx->write(ctx->data, TTY_CLEARENDOFLINE);
+ }
+}
diff --git a/screen-write.c b/screen-write.c
new file mode 100644
index 00000000..c033a782
--- /dev/null
+++ b/screen-write.c
@@ -0,0 +1,516 @@
+/* $Id: screen-write.c,v 1.1 2007-12-06 09:46:23 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"
+
+#define screen_write_limit(v, lower, upper) do { \
+ if (v < lower) \
+ v = lower; \
+ if (v > upper) \
+ v = upper; \
+} while (0)
+
+/* Initialise writing with a window. */
+void
+screen_write_start_window(struct screen_write_ctx *ctx, struct window *w)
+{
+ struct screen *t = w->screen;
+
+ screen_write_start(ctx, t, tty_write_window, w);
+}
+
+/* Initialise writing with a client. */
+void
+screen_write_start_client(struct screen_write_ctx *ctx, struct client *c)
+{
+ struct screen *t = c->session->curw->window->screen;
+
+ screen_write_start(ctx, t, tty_write_client, c);
+}
+
+/* Initialise writing with a session. */
+void
+screen_write_start_session(struct screen_write_ctx *ctx, struct session *s)
+{
+ struct screen *t = s->curw->window->screen;
+
+ screen_write_start(ctx, t, tty_write_session, s);
+}
+
+/* Initialise writing. */
+void
+screen_write_start(struct screen_write_ctx *ctx,
+ struct screen *s, void (*write)(void *, int, ...), void *data)
+{
+ ctx->write = write;
+ ctx->data = data;
+
+ ctx->s = s;
+
+ if (ctx->write != NULL)
+ ctx->write(ctx->data, TTY_CURSOROFF);
+}
+
+/* Finalise writing. */
+void
+screen_write_stop(struct screen_write_ctx *ctx)
+{
+ struct screen *s = ctx->s;
+
+ if (ctx->write != NULL && s->mode & MODE_CURSOR)
+ ctx->write(ctx->data, TTY_CURSORON);
+}
+
+/* Set screen title. */
+void
+screen_write_set_title(struct screen_write_ctx *ctx, char *title)
+{
+ struct screen *s = ctx->s;
+
+ xfree(s->title);
+ s->title = title;
+
+ if (ctx->write != NULL)
+ ctx->write(ctx->data, TTY_TITLE, s->title);
+}
+
+/* Put a character. */
+void
+screen_write_put_character(struct screen_write_ctx *ctx, u_char ch)
+{
+ struct screen *s = ctx->s;
+
+ if (s->cx == screen_size_x(s)) {
+ s->cx = 0;
+ screen_write_cursor_down_scroll(ctx);
+ } else if (!screen_in_x(s, s->cx) || !screen_in_y(s, s->cy))
+ return;
+
+ screen_display_set_cell(s, s->cx, s->cy, ch, s->attr, s->colr);
+ s->cx++;
+
+ if (ctx->write != NULL)
+ ctx->write(ctx->data, TTY_CHARACTER, ch);
+}
+
+/* Put a string right-justified. */
+size_t printflike2
+screen_write_put_string_rjust(
+ struct screen_write_ctx *ctx, const char *fmt, ...)
+{
+ struct screen *s = ctx->s;
+ va_list ap;
+ size_t size;
+ char *msg, *ptr;
+
+ va_start(ap, fmt);
+ size = vasprintf(&msg, fmt, ap);
+ va_end(ap);
+
+ ptr = msg;
+ if (size > screen_size_x(s)) {
+ ptr += size - screen_size_x(s);
+ size = screen_size_x(s);
+ }
+ screen_write_move_cursor(ctx, screen_size_x(s) - size, s->cy);
+ for (; *ptr != '\0'; ptr++) {
+ if (s->cx == screen_size_x(s))
+ break;
+ screen_write_put_character(ctx, *ptr);
+ }
+
+ xfree(msg);
+
+ return (size);
+}
+
+/* Put a string, truncating at end of line. */
+void printflike2
+screen_write_put_string(struct screen_write_ctx *ctx, const char *fmt, ...)
+{
+ struct screen *s = ctx->s;
+ va_list ap;
+ char *msg, *ptr;
+
+ va_start(ap, fmt);
+ vasprintf(&msg, fmt, ap);
+ va_end(ap);
+
+ for (ptr = msg; *ptr != '\0'; ptr++) {
+ if (s->cx == screen_size_x(s))
+ break;
+ screen_write_put_character(ctx, *ptr);
+ }
+
+ xfree(msg);
+}
+
+/* Set screen attributes. */
+void
+screen_write_set_attributes(
+ struct screen_write_ctx *ctx, u_char attr, u_char colr)
+{
+ struct screen *s = ctx->s;
+
+ if (s->attr != attr || s->colr != colr) {
+ s->attr = attr;
+ s->colr = colr;
+
+ if (ctx->write != NULL)
+ ctx->write(ctx->data, TTY_ATTRIBUTES, attr, colr);
+ }
+}
+
+/* Set scroll region. */
+void
+screen_write_set_region(struct screen_write_ctx *ctx, u_int upper, u_int lower)
+{
+ struct screen *s = ctx->s;
+
+ screen_write_limit(upper, 0, screen_last_y(s));
+ screen_write_limit(lower, 0, screen_last_y(s));
+ if (upper > lower)
+ return;
+
+ /* Cursor moves to top-left. */
+ s->cx = 0;
+ s->cy = upper;
+
+ s->rupper = upper;
+ s->rlower = lower;
+
+ if (ctx->write != NULL)
+ ctx->write(ctx->data, TTY_SCROLLREGION, s->rupper, s->rlower);
+}
+
+/* Move cursor up and scroll if necessary. */
+void
+screen_write_cursor_up_scroll(struct screen_write_ctx *ctx)
+{
+ struct screen *s = ctx->s;
+
+ if (s->cy == s->rupper)
+ screen_display_scroll_region_down(s);
+ else if (s->cy > 0)
+ s->cy--;
+
+ if (ctx->write != NULL)
+ ctx->write(ctx->data, TTY_REVERSEINDEX);
+}
+
+/* Move cursor down and scroll if necessary */
+void
+screen_write_cursor_down_scroll(struct screen_write_ctx *ctx)
+{
+ struct screen *s = ctx->s;
+
+ if (s->cy == s->rlower)
+ screen_display_scroll_region_up(s);
+ else if (s->cy < screen_last_y(s))
+ s->cy++;
+
+ if (ctx->write != NULL) /* XXX FORWARDINDEX */
+ ctx->write(ctx->data, TTY_CHARACTER, '\n');
+}
+
+/* Move cursor up. */
+void
+screen_write_cursor_up(struct screen_write_ctx *ctx, u_int n)
+{
+ struct screen *s = ctx->s;
+
+ screen_write_limit(n, 1, screen_above_y(s, s->cy) - 1);
+
+ s->cy -= n;
+
+ if (ctx->write != NULL)
+ ctx->write(ctx->data, TTY_CURSORMOVE, s->cy, s->cx);
+}
+
+/* Move cursor down. */
+void
+screen_write_cursor_down(struct screen_write_ctx *ctx, u_int n)
+{
+ struct screen *s = ctx->s;
+
+ screen_write_limit(n, 1, screen_below_y(s, s->cy) - 1);
+
+ s->cy += n;
+
+ if (ctx->write != NULL)
+ ctx->write(ctx->data, TTY_CURSORMOVE, s->cy, s->cx);
+}
+
+/* Move cursor left. */
+void
+screen_write_cursor_left(struct screen_write_ctx *ctx, u_int n)
+{
+ struct screen *s = ctx->s;
+
+ screen_write_limit(n, 1, screen_left_x(s, s->cx) - 1);
+
+ s->cx -= n;
+
+ if (ctx->write != NULL)
+ ctx->write(ctx->data, TTY_CURSORMOVE, s->cy, s->cx);
+}
+
+/* Move cursor right. */
+void
+screen_write_cursor_right(struct screen_write_ctx *ctx, u_int n)
+{
+ struct screen *s = ctx->s;
+
+ screen_write_limit(n, 1, screen_right_x(s, s->cx) - 1);
+
+ s->cx += n;
+
+ if (ctx->write != NULL)
+ ctx->write(ctx->data, TTY_CURSORMOVE, s->cy, s->cx);
+}
+
+/* Delete lines. */
+void
+screen_write_delete_lines(struct screen_write_ctx *ctx, u_int n)
+{
+ struct screen *s = ctx->s;
+
+ screen_write_limit(n, 1, screen_below_y(s, s->cy));
+
+ if (s->cy < s->rupper || s->cy > s->rlower)
+ screen_display_delete_lines(s, s->cy, n);
+ else
+ screen_display_delete_lines_region(s, s->cy, n);
+
+ if (ctx->write != NULL)
+ ctx->write(ctx->data, TTY_DELETELINE, n);
+}
+
+/* Delete characters. */
+void
+screen_write_delete_characters(struct screen_write_ctx *ctx, u_int n)
+{
+ struct screen *s = ctx->s;
+
+ screen_write_limit(n, 1, screen_right_x(s, s->cx));
+
+ screen_display_delete_characters(s, s->cx, s->cy, n);
+
+ if (ctx->write != NULL)
+ ctx->write(ctx->data, TTY_DELETECHARACTER, n);
+}
+
+/* Insert lines. */
+void
+screen_write_insert_lines(struct screen_write_ctx *ctx, u_int n)
+{
+ struct screen *s = ctx->s;
+
+ screen_write_limit(n, 1, screen_below_y(s, s->cy));
+
+ if (s->cy < s->rupper || s->cy > s->rlower)
+ screen_display_insert_lines(s, s->cy, n);
+ else
+ screen_display_insert_lines_region(s, s->cy, n);
+
+ if (ctx->write != NULL)
+ ctx->write(ctx->data, TTY_INSERTLINE, n);
+}
+
+/* Insert characters. */
+void
+screen_write_insert_characters(struct screen_write_ctx *ctx, u_int n)
+{
+ struct screen *s = ctx->s;
+
+ screen_write_limit(n, 1, screen_right_x(s, s->cx));
+
+ screen_display_insert_characters(s, s->cx, s->cy, n);
+
+ if (ctx->write != NULL)
+ ctx->write(ctx->data, TTY_INSERTCHARACTER, n);
+}
+
+/* Move the cursor. */
+void
+screen_write_move_cursor(struct screen_write_ctx *ctx, u_int n, u_int m)
+{
+ struct screen *s = ctx->s;
+
+ screen_write_limit(n, 0, screen_last_x(s));
+ screen_write_limit(m, 0, screen_last_y(s));
+
+ s->cx = n;
+ s->cy = m;
+
+ if (ctx->write != NULL)
+ ctx->write(ctx->data, TTY_CURSORMOVE, s->cy, s->cx);
+}
+
+/* Full to end of screen. */
+void
+screen_write_fill_end_of_screen(struct screen_write_ctx *ctx)
+{
+ struct screen *s = ctx->s;
+ u_int i;
+
+ screen_fill_area(s, s->cx, s->cy,
+ screen_right_x(s, s->cx), 1, SCREEN_DEFDATA, s->attr, s->colr);
+ screen_fill_area(s, 0, s->cy + 1,
+ screen_below_y(s, s->cy + 1), 1, SCREEN_DEFDATA, s->attr, s->colr);
+
+ if (ctx->write != NULL) {
+ ctx->write(ctx->data, TTY_CLEARENDOFLINE);
+ for (i = s->cy + 1; i < screen_size_y(s); i++) {
+ ctx->write(ctx->data, TTY_CURSORMOVE, i, 0);
+ ctx->write(ctx->data, TTY_CLEARENDOFLINE);
+ }
+ ctx->write(ctx->data, TTY_CURSORMOVE, s->cy, s->cx);
+ }
+}
+
+/* Fill entire screen. */
+void
+screen_write_fill_screen(struct screen_write_ctx *ctx)
+{
+ struct screen *s = ctx->s;
+ u_int i;
+
+ screen_display_fill_area(s, 0, 0, screen_size_x(s), screen_size_y(s),
+ SCREEN_DEFDATA, s->attr, s->colr);
+
+ if (ctx->write != NULL) {
+ for (i = 0; i < screen_size_y(s); i++) {
+ ctx->write(ctx->data, TTY_CURSORMOVE, i, 0);
+ ctx->write(ctx->data, TTY_CLEARENDOFLINE);
+ }
+ ctx->write(ctx->data, TTY_CURSORMOVE, s->cy, s->cx);
+ }
+}
+
+/* Fill to end of line. */
+void
+screen_write_fill_end_of_line(struct screen_write_ctx *ctx)
+{
+ struct screen *s = ctx->s;
+
+ screen_display_fill_area(s, s->cx, s->cy,
+ screen_right_x(s, s->cx), 1, SCREEN_DEFDATA, s->attr, s->colr);
+
+ if (ctx->write != NULL)
+ ctx->write(ctx->data, TTY_CLEARENDOFLINE);
+}
+
+/* Fill to start of line. */
+void
+screen_write_fill_start_of_line(struct screen_write_ctx *ctx)
+{
+ struct screen *s = ctx->s;
+
+ screen_display_fill_area(s, 0, s->cy,
+ screen_left_x(s, s->cx), 1, SCREEN_DEFDATA, s->attr, s->colr);
+
+ if (ctx->write != NULL)
+ ctx->write(ctx->data, TTY_CLEARSTARTOFLINE);
+}
+
+/* Fill entire line. */
+void
+screen_write_fill_line(struct screen_write_ctx *ctx)
+{
+ struct screen *s = ctx->s;
+
+ screen_display_fill_area(s, 0, s->cy,
+ screen_size_x(s), s->cy, SCREEN_DEFDATA, s->attr, s->colr);
+
+ if (ctx->write != NULL)
+ ctx->write(ctx->data, TTY_CLEARLINE);
+}
+
+/* Set a screen mode. */
+void
+screen_write_set_mode(struct screen_write_ctx *ctx, int mode)
+{
+ struct screen *s = ctx->s;
+
+ s->mode |= mode;
+
+ if (ctx->write == NULL)
+ return;
+
+ if (mode & MODE_INSERT)
+ ctx->write(ctx->data, TTY_INSERTON);
+ if (mode & MODE_KCURSOR)
+ ctx->write(ctx->data, TTY_KCURSORON);
+ if (mode & MODE_KKEYPAD)
+ ctx->write(ctx->data, TTY_KKEYPADON);
+ if (mode & MODE_MOUSE)
+ ctx->write(ctx->data, TTY_MOUSEON);
+}
+
+/* Clear a screen mode. */
+void
+screen_write_clear_mode(struct screen_write_ctx *ctx, int mode)
+{
+ struct screen *s = ctx->s;
+
+ s->mode &= ~mode;
+
+ if (ctx->write == NULL)
+ return;
+
+ if (mode & MODE_INSERT)
+ ctx->write(ctx->data, TTY_INSERTOFF);
+ if (mode & MODE_KCURSOR)
+ ctx->write(ctx->data, TTY_KCURSOROFF);
+ if (mode & MODE_KKEYPAD)
+ ctx->write(ctx->data, TTY_KKEYPADOFF);
+ if (mode & MODE_MOUSE)
+ ctx->write(ctx->data, TTY_MOUSEOFF);
+}
+
+/* Copy cells from another screen. */
+void
+screen_write_copy_area(struct screen_write_ctx *ctx,
+ struct screen *src, u_int nx, u_int ny, u_int ox, u_int oy)
+{
+ struct screen *s = ctx->s;
+ struct screen_redraw_ctx rctx;
+ int saved_mode;
+
+ screen_write_limit(nx, 1, screen_right_x(s, s->cx));
+ screen_write_limit(ny, 1, screen_below_y(s, s->cy));
+
+ screen_display_copy_area(ctx->s, src, s->cx, s->cy, nx, ny, ox, oy);
+
+ if (ctx->write != NULL) {
+ /* Save mode XXX hack */
+ saved_mode = ctx->s->mode;
+ ctx->s->mode &= ~MODE_CURSOR;
+
+ screen_redraw_start(&rctx, ctx->s, ctx->write, ctx->data);
+ screen_redraw_area(&rctx, s->cx, s->cy, nx, ny);
+ screen_redraw_stop(&rctx);
+
+ ctx->s->mode = saved_mode;
+ }
+}
diff --git a/screen.c b/screen.c
index 5643ece0..051d5ef5 100644
--- a/screen.c
+++ b/screen.c
@@ -1,4 +1,4 @@
-/* $Id: screen.c,v 1.55 2007-12-02 18:23:10 nicm Exp $ */
+/* $Id: screen.c,v 1.56 2007-12-06 09:46:23 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -24,6 +24,54 @@
/*
* Virtual screen.
+ *
+ * A screen is stored as three arrays of lines of 8-bit values, one for the
+ * actual characters (data), one for attributes and one for colours. Three
+ * seperate blocks means memset and friends can be used. Each array is y by x
+ * in size, row then column order. Sizes are 0-based. There is an additional
+ * array of u_ints with the size of each line.
+ *
+ * Each screen has a history starting at the beginning of the arrays and
+ * extending for hsize lines. Beyond that is the screen display of size
+ * dy:
+ *
+ * ----------- array base
+ * | |
+ * | history |
+ * ----------- array base + hsize
+ * | |
+ * | display |
+ * | |
+ * ----------- array base + hsize + dy
+ *
+ * The screen_x/screen_y macros are used to convert a cell on the displayed
+ * area to an absolute position in the arrays.
+ *
+ * Screen handling code is split into four files:
+ *
+ * screen.c: Creation/deletion, utility functions, and basic functions to
+ * manipulate the screen based on offsets from the base.
+ * screen-display.c: Basic functions for manipulating the displayed
+ * part of the screen. x,y coordinates passed to these
+ * are relative to the display. These are largely
+ * utility functions for screen-write.c.
+ * screen-redraw.c: Functions for redrawing all or part of a screen to
+ * one or more ttys. A context is filled via one of the
+ * screen_redraw_start* variants which sets up (removes
+ * cursor etc) and figures out which tty_write_* function
+ * to use to write to the terminals, then the other
+ * screen_redraw_* functions are used to draw the screen,
+ * and screen_redraw_stop used to reset the cursor and
+ * clean up. These are used when changing window and a
+ * few other bits (status line).
+ * screen-write.c: Functions for modifying (writing into) the screen and
+ * optionally simultaneously updating one or more ttys.
+ * These are used in much the same way as the redraw
+ * functions. These are used to update when parsing
+ * input from the window (input.c) and for the various
+ * other modes which maintain private screens.
+ *
+ * If you're thinking this all seems too complicated, that's because it is :-/.
*/
/* Colour to string. */
@@ -104,6 +152,8 @@ screen_create(struct screen *s, u_int dx, u_int dy)
s->grid_colr = xmalloc(dy * (sizeof *s->grid_colr));
s->grid_size = xmalloc(dy * (sizeof *s->grid_size));
screen_make_lines(s, 0, dy);
+
+ screen_clear_selection(s);
}
/* Resize screen. */
@@ -122,11 +172,11 @@ screen_resize(struct screen *s, u_int sx, u_int sy)
if (sx == ox && sy == oy)
return;
- /*
+ /*
* X dimension.
*/
if (sx != ox) {
- /*
+ /*
* If getting smaller, nuke any data in lines over the new
* size.
*/
@@ -163,10 +213,10 @@ screen_resize(struct screen *s, u_int sx, u_int sy)
screen_free_lines(s, s->hsize, my);
screen_move_lines(s, s->hsize, s->hsize + my, oy - my);
-
+
s->cy -= my;
oy -= my;
- }
+ }
ny = oy - sy;
if (ny > 0) {
@@ -178,7 +228,7 @@ screen_resize(struct screen *s, u_int sx, u_int sy)
s->cy = sy - 1;
}
}
-
+
/* Resize line arrays. */
ny = s->hsize + sy;
s->grid_data = xrealloc(s->grid_data, ny, sizeof *s->grid_data);
@@ -237,6 +287,9 @@ screen_get_cell(struct screen *s,
*attr = s->grid_attr[cy][cx];
*colr = s->grid_colr[cy][cx];
}
+
+ if (screen_check_selection(s, cx, cy))
+ *attr |= ATTR_REVERSE;
}
/* Set a cell. */
@@ -268,331 +321,6 @@ 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,
- void (*write)(void *, int, ...), void *data, u_int ox, u_int oy)
-{
- ctx->write = write;
- ctx->data = data;
-
- ctx->s = s;
-
- ctx->ox = ox;
- ctx->oy = oy;
-
- /* Resetting the scroll region homes the cursor so start at 0,0. */
- ctx->cx = 0;
- ctx->cy = 0;
-
- ctx->sel.flag = 0;
-
- ctx->write(ctx->data, TTY_ATTRIBUTES, s->attr, s->colr);
- ctx->write(ctx->data, TTY_SCROLLREGION, 0, screen_last_y(s));
- ctx->write(ctx->data, TTY_CURSOROFF);
- ctx->write(ctx->data, TTY_MOUSEOFF);
-}
-
-/* Set offset. */
-void
-screen_draw_set_offset(struct screen_draw_ctx *ctx, u_int ox, u_int oy)
-{
- ctx->ox = ox;
- ctx->oy = oy;
-}
-
-/* Set selection. */
-void
-screen_draw_set_selection(struct screen_draw_ctx *ctx,
- int flag, u_int sx, u_int sy, u_int ex, u_int ey)
-{
- struct screen_draw_sel *sel = &ctx->sel;
-
- sel->flag = flag;
- if (!sel->flag)
- return;
-
- if (ey < sy || (sy == ey && ex < sx)) {
- sel->sx = ex; sel->sy = ey;
- sel->ex = sx; sel->ey = sy;
- } else {
- sel->sx = sx; sel->sy = sy;
- sel->ex = ex; sel->ey = ey;
- }
-}
-
-/* Check if cell in selection. */
-int
-screen_draw_check_selection(struct screen_draw_ctx *ctx, u_int px, u_int py)
-{
- struct screen_draw_sel *sel = &ctx->sel;
-
- if (!sel->flag)
- return (0);
-
- if (py < sel->sy || py > sel->ey)
- return (0);
-
- if (py == sel->sy && py == sel->ey) {
- if (px < sel->sx || px > sel->ex)
- return (0);
- return (1);
- }
-
- if ((py == sel->sy && px < sel->sx) || (py == sel->ey && px > sel->ex))
- return (0);
- return (1);
-}
-
-/* Get cell data during drawing. */
-void
-screen_draw_get_cell(struct screen_draw_ctx *ctx,
- u_int px, u_int py, u_char *data, u_char *attr, u_char *colr)
-{
- struct screen *s = ctx->s;
- u_int cx, cy;
-
- cx = ctx->ox + px;
- cy = screen_y(s, py) - ctx->oy;
-
- screen_get_cell(s, cx, cy, data, attr, colr);
-
- if (screen_draw_check_selection(ctx, cx, cy))
- *attr |= ATTR_REVERSE;
-}
-
-/* Finalise drawing. */
-void
-screen_draw_stop(struct screen_draw_ctx *ctx)
-{
- struct screen *s = ctx->s;
-
- ctx->write(ctx->data, TTY_SCROLLREGION, s->rupper, s->rlower);
-
- if (ctx->cx != s->cx || ctx->cy != s->cy)
- ctx->write(ctx->data, TTY_CURSORMOVE, s->cy, s->cx);
-
- ctx->write(ctx->data, TTY_ATTRIBUTES, s->attr, s->colr);
-
- if (s->mode & MODE_BACKGROUND) {
- if (s->mode & MODE_BGCURSOR)
- ctx->write(ctx->data, TTY_CURSORON);
- } else {
- if (s->mode & MODE_CURSOR)
- ctx->write(ctx->data, TTY_CURSORON);
- }
- if (s->mode & MODE_MOUSE)
- ctx->write(ctx->data, TTY_MOUSEON);
-}
-
-/* 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;
-
- screen_draw_set_attributes(ctx, SCREEN_DEFATTR, SCREEN_DEFCOLR);
- 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_cursor(struct screen_draw_ctx *ctx, u_int px, u_int py)
-{
- if (px == ctx->cx && py == ctx->cy)
- return;
-
- if (px == 0 && py == ctx->cy)
- ctx->write(ctx->data, TTY_CHARACTER, '\r');
- else if (px == ctx->cx && py == ctx->cy + 1)
- ctx->write(ctx->data, TTY_CHARACTER, '\n');
- else if (px == 0 && py == ctx->cy + 1) {
- ctx->write(ctx->data, TTY_CHARACTER, '\r');
- ctx->write(ctx->data, TTY_CHARACTER, '\n');
- } else
- ctx->write(ctx->data, TTY_CURSORMOVE, py, px);
-
- ctx->cx = px;
- ctx->cy = py;
-}
-
-/* Set attributes. */
-void
-screen_draw_set_attributes(
- struct screen_draw_ctx *ctx, u_char attr, u_char colr)
-{
- ctx->write(ctx->data, TTY_ATTRIBUTES, attr, colr);
-}
-
-/* Draw single cell. */
-void
-screen_draw_cell(struct screen_draw_ctx *ctx, u_int px, u_int py)
-{
- u_char data, attr, colr;
-
- screen_draw_move_cursor(ctx, px, py);
-
- screen_draw_get_cell(ctx, px, py, &data, &attr, &colr);
- screen_draw_set_attributes(ctx, attr, colr);
- ctx->write(ctx->data, TTY_CHARACTER, data);
-
- /*
- * Don't try to wrap as it will cause problems when screen is smaller
- * than client.
- */
- ctx->cx++;
-}
-
-/* Draw range of cells. */
-void
-screen_draw_cells(struct screen_draw_ctx *ctx, u_int px, u_int py, u_int nx)
-{
- u_int i;
-
- for (i = px; i < px + nx; i++)
- screen_draw_cell(ctx, i, py);
-}
-
-/* Draw single column. */
-void
-screen_draw_column(struct screen_draw_ctx *ctx, u_int px)
-{
- u_int i;
-
- for (i = 0; i < screen_size_y(ctx->s); i++)
- screen_draw_cell(ctx, px, i);
-}
-
-/* Draw single line. */
-void
-screen_draw_line(struct screen_draw_ctx *ctx, u_int py)
-{
- u_int cx, cy;
-
- cy = screen_y(ctx->s, py) - ctx->oy;
- cx = ctx->s->grid_size[cy];
-
- if (ctx->sel.flag ||
- screen_size_x(ctx->s) < 5 || cx >= screen_size_x(ctx->s) - 5)
- screen_draw_cells(ctx, 0, py, screen_size_x(ctx->s));
- else {
- screen_draw_cells(ctx, 0, py, cx);
- screen_draw_move_cursor(ctx, cx, py);
- screen_draw_set_attributes(ctx, SCREEN_DEFATTR, SCREEN_DEFCOLR);
- ctx->write(ctx->data, TTY_CLEARENDOFLINE);
- }
-}
-
-/* Draw set of lines. */
-void
-screen_draw_lines(struct screen_draw_ctx *ctx, u_int py, u_int ny)
-{
- u_int i;
-
- for (i = py; i < py + ny; i++)
- screen_draw_line(ctx, i);
-}
-
-/* Draw entire screen. */
-void
-screen_draw_screen(struct screen_draw_ctx *ctx)
-{
- screen_draw_lines(ctx, 0, screen_size_y(ctx->s));
-}
-
/* Create a range of lines. */
void
screen_make_lines(struct screen *s, u_int py, u_int ny)
@@ -641,24 +369,60 @@ screen_move_lines(struct screen *s, u_int dy, u_int py, u_int ny)
&s->grid_size[dy], &s->grid_size[py], ny * (sizeof *s->grid_size));
}
-/* Fill a range of lines. */
+/* Fill an area. */
void
-screen_fill_lines(
- struct screen *s, u_int py, u_int ny, u_char data, u_char attr, u_char colr)
+screen_fill_area(struct screen *s, u_int px, u_int py,
+ u_int nx, u_int ny, u_char data, u_char attr, u_char colr)
{
- u_int i;
+ u_int i, j;
- for (i = py; i < py + ny; i++)
- screen_fill_cells(s, 0, i, s->dx, data, attr, colr);
+ for (i = py; i < py + ny; i++) {
+ for (j = px; j < px + nx; j++)
+ screen_set_cell(s, j, i, data, attr, colr);
+ }
}
-/* Fill a range of cells. */
+/* Set selection. */
void
-screen_fill_cells(struct screen *s,
- u_int px, u_int py, u_int nx, u_char data, u_char attr, u_char colr)
+screen_set_selection(struct screen *s, u_int sx, u_int sy, u_int ex, u_int ey)
{
- u_int i;
+ struct screen_sel *sel = &s->sel;
- for (i = px; i < px + nx; i++)
- screen_set_cell(s, i, py, data, attr, colr);
+ sel->flag = 1;
+ if (ey < sy || (sy == ey && ex < sx)) {
+ sel->sx = ex; sel->sy = ey;
+ sel->ex = sx; sel->ey = sy;
+ } else {
+ sel->sx = sx; sel->sy = sy;
+ sel->ex = ex; sel->ey = ey;
+ }
+}
+
+/* Clear selection. */
+void
+screen_clear_selection(struct screen *s)
+{
+ struct screen_sel *sel = &s->sel;
+
+ sel->flag = 0;
+}
+
+/* Check if cell in selection. */
+int
+screen_check_selection(struct screen *s, u_int px, u_int py)
+{
+ struct screen_sel *sel = &s->sel;
+
+ if (!sel->flag || py < sel->sy || py > sel->ey)
+ return (0);
+
+ if (py == sel->sy && py == sel->ey) {
+ if (px < sel->sx || px > sel->ex)
+ return (0);
+ return (1);
+ }
+
+ if ((py == sel->sy && px < sel->sx) || (py == sel->ey && px > sel->ex))
+ return (0);
+ return (1);
}
diff --git a/server-fn.c b/server-fn.c
index 8caea797..9da001f5 100644
--- a/server-fn.c
+++ b/server-fn.c
@@ -1,4 +1,4 @@
-/* $Id: server-fn.c,v 1.35 2007-11-27 19:23:34 nicm Exp $ */
+/* $Id: server-fn.c,v 1.36 2007-12-06 09:46:23 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -71,7 +71,7 @@ server_extract_session(struct msg_command_data *data, char *name, char **cause)
xasprintf(cause, "multiple sessions and session not specified");
return (NULL);
}
- return (s);
+ return (s);
}
void
@@ -123,11 +123,12 @@ server_write_window(
void
server_clear_client(struct client *c)
{
- struct screen_draw_ctx ctx;
+ struct screen_redraw_ctx ctx;
- screen_draw_start_client(&ctx, c, 0, 0);
- screen_draw_clear_screen(&ctx);
- screen_draw_stop(&ctx);
+ screen_redraw_start_client(&ctx, c);
+ screen_redraw_set_attributes(&ctx, SCREEN_DEFATTR, SCREEN_DEFCOLR);
+ screen_redraw_clear_screen(&ctx);
+ screen_redraw_stop(&ctx);
status_write_client(c);
}
@@ -135,12 +136,11 @@ server_clear_client(struct client *c)
void
server_redraw_client(struct client *c)
{
- struct screen_draw_ctx ctx;
- struct window *w = c->session->curw->window;
+ struct screen_redraw_ctx ctx;
- screen_draw_start_client(&ctx, c, 0, 0);
- window_draw(w, &ctx, 0, screen_size_y(&w->screen));
- screen_draw_stop(&ctx);
+ screen_redraw_start_client(&ctx, c);
+ screen_redraw_lines(&ctx, 0, screen_size_y(ctx.s));
+ screen_redraw_stop(&ctx);
status_write_client(c);
}
@@ -154,11 +154,12 @@ server_status_client(struct client *c)
void
server_clear_session(struct session *s)
{
- struct screen_draw_ctx ctx;
+ struct screen_redraw_ctx ctx;
- screen_draw_start_session(&ctx, s, 0, 0);
- screen_draw_clear_screen(&ctx);
- screen_draw_stop(&ctx);
+ screen_redraw_start_session(&ctx, s);
+ screen_redraw_set_attributes(&ctx, SCREEN_DEFATTR, SCREEN_DEFCOLR);
+ screen_redraw_clear_screen(&ctx);
+ screen_redraw_stop(&ctx);
status_write_session(s);
}
@@ -166,12 +167,11 @@ server_clear_session(struct session *s)
void
server_redraw_session(struct session *s)
{
- struct screen_draw_ctx ctx;
- struct window *w = s->curw->window;
+ struct screen_redraw_ctx ctx;
- screen_draw_start_session(&ctx, s, 0, 0);
- window_draw(w, &ctx, 0, screen_size_y(&w->screen));
- screen_draw_stop(&ctx);
+ screen_redraw_start_session(&ctx, s);
+ screen_redraw_lines(&ctx, 0, screen_size_y(ctx.s));
+ screen_redraw_stop(&ctx);
status_write_session(s);
}
@@ -185,11 +185,12 @@ server_status_session(struct session *s)
void
server_clear_window(struct window *w)
{
- struct screen_draw_ctx ctx;
+ struct screen_redraw_ctx ctx;
- screen_draw_start_window(&ctx, w, 0, 0);
- screen_draw_clear_screen(&ctx);
- screen_draw_stop(&ctx);
+ screen_redraw_start_window(&ctx, w);
+ screen_redraw_set_attributes(&ctx, SCREEN_DEFATTR, SCREEN_DEFCOLR);
+ screen_redraw_clear_screen(&ctx);
+ screen_redraw_stop(&ctx);
status_write_window(w);
}
@@ -197,11 +198,11 @@ server_clear_window(struct window *w)
void
server_redraw_window(struct window *w)
{
- struct screen_draw_ctx ctx;
+ struct screen_redraw_ctx ctx;
- screen_draw_start_window(&ctx, w, 0, 0);
- window_draw(w, &ctx, 0, screen_size_y(&w->screen));
- screen_draw_stop(&ctx);
+ screen_redraw_start_window(&ctx, w);
+ screen_redraw_lines(&ctx, 0, screen_size_y(ctx.s));
+ screen_redraw_stop(&ctx);
status_write_window(w);
}
@@ -228,36 +229,36 @@ server_status_window(struct window *w)
void printflike2
server_write_message(struct client *c, const char *fmt, ...)
{
- struct screen_draw_ctx ctx;
- va_list ap;
- char *msg;
- size_t size;
+ struct screen_redraw_ctx ctx;
+ va_list ap;
+ char *msg;
+ size_t size;
- 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);
+ screen_redraw_start_client(&ctx, c);
+ screen_redraw_move_cursor(&ctx, 0, c->sy - 1);
+ screen_redraw_set_attributes(&ctx, ATTR_REVERSE, 0x88);
va_start(ap, fmt);
xvasprintf(&msg, fmt, ap);
va_end(ap);
-
+
size = strlen(msg);
if (size < c->sx - 1) {
msg = xrealloc(msg, 1, c->sx);
msg[c->sx - 1] = '\0';
memset(msg + size, SCREEN_DEFDATA, (c->sx - 1) - size);
}
- screen_draw_write_string(&ctx, "%s", msg);
+ screen_redraw_write_string(&ctx, "%s", msg);
xfree(msg);
buffer_flush(c->tty.fd, c->tty.in, c->tty.out);
- usleep(750000);
+ usleep(750000);
if (status_lines == 0) {
- window_draw(c->session->curw->window, &ctx, c->sy - 1, 1);
- screen_draw_stop(&ctx);
+ screen_redraw_lines(&ctx, c->sy - 1, 1);
+ screen_redraw_stop(&ctx);
} else {
- screen_draw_stop(&ctx);
+ screen_redraw_stop(&ctx);
status_write_client(c);
}
}
diff --git a/server-msg.c b/server-msg.c
index a9f77bc2..fec44099 100644
--- a/server-msg.c
+++ b/server-msg.c
@@ -1,5 +1,5 @@
-/* $Id: server-msg.c,v 1.39 2007-11-27 20:01:30 nicm Exp $ */
+/* $Id: server-msg.c,v 1.40 2007-12-06 09:46:23 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -38,7 +38,7 @@ void printflike2 server_msg_fn_command_print(
struct server_msg {
enum hdrtype type;
-
+
int (*fn)(struct hdr *, struct client *);
};
const struct server_msg server_msg_table[] = {
@@ -64,7 +64,7 @@ server_msg_dispatch(struct client *c)
if (BUFFER_USED(c->in) < (sizeof hdr) + hdr.size)
return (0);
buffer_remove(c->in, sizeof hdr);
-
+
for (i = 0; i < NSERVERMSG; i++) {
msg = server_msg_table + i;
if (msg->type == hdr.type) {
@@ -72,7 +72,7 @@ server_msg_dispatch(struct client *c)
return (n);
break;
}
- }
+ }
if (i == NSERVERMSG)
fatalx("unexpected message");
}
@@ -120,7 +120,7 @@ server_msg_fn_command(struct hdr *hdr, struct client *c)
if (hdr->size < sizeof data)
fatalx("bad MSG_COMMAND size");
buffer_read(c->in, &data, sizeof data);
- name = cmd_recv_string(c->in);
+ name = cmd_recv_string(c->in);
client = cmd_recv_string(c->in);
cmd = cmd_recv(c->in);
@@ -147,7 +147,7 @@ server_msg_fn_command(struct hdr *hdr, struct client *c)
}
} else {
if (client == NULL) {
- server_msg_fn_command_error(&ctx,
+ server_msg_fn_command_error(&ctx,
"%s: must specify a client", cmd->entry->name);
goto out;
}
@@ -167,7 +167,7 @@ server_msg_fn_command(struct hdr *hdr, struct client *c)
ctx.session = NULL;
if (cmd->entry->flags & CMD_NOSESSION) {
if (name != NULL) {
- server_msg_fn_command_error(&ctx,
+ server_msg_fn_command_error(&ctx,
"%s: cannot specify a session", cmd->entry->name);
goto out;
}
@@ -179,7 +179,7 @@ server_msg_fn_command(struct hdr *hdr, struct client *c)
xfree(cause);
goto out;
}
- }
+ }
cmd_exec(cmd, &ctx);
cmd_free(cmd);
diff --git a/server.c b/server.c
index 6c974264..89e5970b 100644
--- a/server.c
+++ b/server.c
@@ -1,4 +1,4 @@
-/* $Id: server.c,v 1.43 2007-12-04 20:25:17 nicm Exp $ */
+/* $Id: server.c,v 1.44 2007-12-06 09:46:23 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -107,7 +107,7 @@ server_start(const char *path)
if (fcntl(fd, F_SETFL, mode|O_NONBLOCK) == -1)
fatal("fcntl failed");
if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
- fatal("fcntl failed");
+ fatal("fcntl failed");
if (daemon(1, 1) != 0)
fatal("daemon failed");
@@ -231,7 +231,7 @@ server_handle_windows(struct pollfd **pfd)
if ((w = ARRAY_ITEM(&windows, i)) != NULL) {
if (buffer_poll(*pfd, w->in, w->out) != 0)
server_lost_window(w);
- else
+ else
server_handle_window(w);
}
(*pfd)++;
@@ -371,7 +371,7 @@ server_lost_client(struct client *c)
if (ARRAY_ITEM(&clients, i) == c)
ARRAY_SET(&clients, i, NULL);
}
-
+
tty_free(&c->tty);
close(c->fd);
diff --git a/session.c b/session.c
index e4a543ec..2ba32499 100644
--- a/session.c
+++ b/session.c
@@ -1,4 +1,4 @@
-/* $Id: session.c,v 1.29 2007-11-12 16:39:30 nicm Exp $ */
+/* $Id: session.c,v 1.30 2007-12-06 09:46:23 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -26,7 +26,7 @@
#include "tmux.h"
/* Global session list. */
-struct sessions sessions;
+struct sessions sessions;
void
session_cancelbell(struct session *s, struct winlink *wl)
@@ -78,7 +78,7 @@ session_find(const char *name)
if (s != NULL && strcmp(s->name, name) == 0)
return (s);
}
-
+
return (NULL);
}
@@ -131,7 +131,7 @@ session_destroy(struct session *s)
ARRAY_SET(&sessions, i, NULL);
while (!ARRAY_EMPTY(&sessions) && ARRAY_LAST(&sessions) == NULL)
ARRAY_TRUNC(&sessions, 1);
-
+
while (!RB_EMPTY(&s->windows))
winlink_remove(&s->windows, RB_ROOT(&s->windows));
@@ -163,7 +163,7 @@ session_new(struct session *s, const char *name, const char *cmd, int idx)
fatalx("session not found");
xsnprintf(buf, sizeof buf, "TMUX=%ld,%u", (long) getpid(), i);
env[0] = buf;
-
+
if ((w = window_create(name, cmd, env, s->sx, s->sy)) == NULL)
return (NULL);
return (session_attach(s, w, idx));
@@ -227,7 +227,7 @@ session_next(struct session *s)
return (0);
}
-/* Move session to previous window. */
+/* Move session to previous window. */
int
session_previous(struct session *s)
{
@@ -247,7 +247,7 @@ session_previous(struct session *s)
return (0);
}
-/* Move session to specific window. */
+/* Move session to specific window. */
int
session_select(struct session *s, int idx)
{
@@ -264,7 +264,7 @@ session_select(struct session *s, int idx)
return (0);
}
-/* Move session to last used window. */
+/* Move session to last used window. */
int
session_last(struct session *s)
{
@@ -273,7 +273,7 @@ session_last(struct session *s)
wl = s->lastw;
if (wl == NULL)
return (-1);
- if (wl == s->curw)
+ if (wl == s->curw)
return (1);
s->lastw = s->curw;
diff --git a/status.c b/status.c
index f6b0a057..5ab5a6c5 100644
--- a/status.c
+++ b/status.c
@@ -1,4 +1,4 @@
-/* $Id: status.c,v 1.14 2007-11-27 19:23:34 nicm Exp $ */
+/* $Id: status.c,v 1.15 2007-12-06 09:46:23 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -27,16 +27,16 @@ void printflike3 status_print(struct buffer *, size_t *, const char *, ...);
void
status_write_client(struct client *c)
{
- struct screen_draw_ctx ctx;
- struct winlink *wl;
- char flag;
+ struct screen_redraw_ctx ctx;
+ struct winlink *wl;
+ char flag;
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);
+ screen_redraw_start_client(&ctx, c);
+ screen_redraw_move_cursor(&ctx, 0, c->sy - status_lines);
+ screen_redraw_set_attributes(&ctx, 0, status_colour);
RB_FOREACH(wl, winlinks, &c->session->windows) {
flag = ' ';
@@ -46,15 +46,15 @@ status_write_client(struct client *c)
flag = '*';
if (session_hasbell(c->session, wl))
flag = '!';
- screen_draw_write_string(
+ screen_redraw_write_string(
&ctx, "%d:%s%c ", wl->idx, wl->window->name, flag);
- if (ctx.cx >= screen_last_x(ctx.s))
+ if (ctx.s->cx >= screen_last_x(ctx.s))
break;
}
- screen_draw_clear_line_to(&ctx, screen_last_x(ctx.s));
+ screen_redraw_clear_end_of_line(&ctx);
- screen_draw_stop(&ctx);
+ screen_redraw_stop(&ctx);
}
void
@@ -63,7 +63,7 @@ status_write_window(struct window *w)
struct client *c;
u_int i;
- if (w->screen.mode & MODE_HIDDEN)
+ if (w->flags & WINDOW_HIDDEN)
return;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
diff --git a/tmux.c b/tmux.c
index 7f8a6272..c6424bd4 100644
--- a/tmux.c
+++ b/tmux.c
@@ -1,4 +1,4 @@
-/* $Id: tmux.c,v 1.44 2007-11-23 17:52:54 nicm Exp $ */
+/* $Id: tmux.c,v 1.45 2007-12-06 09:46:23 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -141,10 +141,10 @@ void
sigreset(void)
{
struct sigaction act;
-
+
memset(&act, 0, sizeof act);
sigemptyset(&act.sa_mask);
-
+
act.sa_handler = SIG_DFL;
if (sigaction(SIGPIPE, &act, NULL) != 0)
fatal("sigaction failed");
@@ -283,7 +283,7 @@ main(int argc, char **argv)
pfd.events = POLLIN;
if (BUFFER_USED(cctx.srv_out) > 0)
pfd.events |= POLLOUT;
-
+
if (poll(&pfd, 1, INFTIM) == -1) {
if (errno == EAGAIN || errno == EINTR)
continue;
@@ -316,7 +316,7 @@ main(int argc, char **argv)
if (hdr.size > INT_MAX - 1)
fatalx("bad MSG_ERROR size");
log_warnx("%.*s",
- (int) hdr.size, BUFFER_OUT(cctx.srv_in));
+ (int) hdr.size, BUFFER_OUT(cctx.srv_in));
buffer_remove(cctx.srv_in, hdr.size);
n = 1;
goto out;
diff --git a/tmux.h b/tmux.h
index 488a7d59..77901477 100644
--- a/tmux.h
+++ b/tmux.h
@@ -1,4 +1,4 @@
-/* $Id: tmux.h,v 1.108 2007-12-02 18:23:10 nicm Exp $ */
+/* $Id: tmux.h,v 1.109 2007-12-06 09:46:23 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -281,7 +281,7 @@ struct buffer {
#define TTY_KKEYPADON 23
#define TTY_TITLE 24
#define TTY_MOUSEON 25
-#define TTY_MOUSEOFF 26 /* XXX merge allon/off into 1 arg? */
+#define TTY_MOUSEOFF 26 /* XXX merge allon/off into 1 arg? */
/* Message codes. */
enum hdrtype {
@@ -335,23 +335,25 @@ struct msg_resize_data {
#define ATTR_CHARSET 0x80 /* alternative character set */
/* Modes. */
-#define MODE_CURSOR 0x001
-#define MODE_INSERT 0x002
-#define MODE_KCURSOR 0x004
-#define MODE_KKEYPAD 0x008
-#define MODE_SAVED 0x010
-#define MODE_HIDDEN 0x020
-#define MODE_BACKGROUND 0x040
-#define MODE_BGCURSOR 0x080
-#define MODE_MOUSE 0x100
+#define MODE_CURSOR 0x01
+#define MODE_INSERT 0x02
+#define MODE_KCURSOR 0x04
+#define MODE_KKEYPAD 0x08
+#define MODE_SAVED 0x10
+#define MODE_MOUSE 0x20
+
+/* Screen selection. */
+struct screen_sel {
+ int flag;
-/*
- * Virtual screen. This is stored as three blocks of 8-bit values, one for
- * the actual characters, one for attributes and one for colours. Three
- * seperate blocks means memset and friends can be used.
- *
- * Each block is y by x in size, row then column order. Sizes are 0-based.
- */
+ u_int sx;
+ u_int sy;
+
+ u_int ex;
+ u_int ey;
+};
+
+/* Virtual screen. */
struct screen {
char *title;
@@ -378,35 +380,29 @@ struct screen {
u_int saved_cy;
u_char saved_attr;
u_char saved_colr;
-
- int mode;
-};
-
-/* Screen redraw selection. */
-struct screen_draw_sel {
- int flag;
- u_int sx;
- u_int sy;
+ int mode;
- u_int ex;
- u_int ey;
+ struct screen_sel sel;
};
/* Screen redraw context. */
-struct screen_draw_ctx {
+struct screen_redraw_ctx {
void *data;
void (*write)(void *, int, ...);
- struct screen *s;
+ u_int saved_cx;
+ u_int saved_cy;
- u_int cx;
- u_int cy;
+ struct screen *s;
+};
- u_int ox;
- u_int oy;
+/* Screen write context. */
+struct screen_write_ctx {
+ void *data;
+ void (*write)(void *, int, ...);
- struct screen_draw_sel sel;
+ struct screen *s;
};
/* Screen display access macros. */
@@ -423,11 +419,20 @@ 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)
+/* These are inclusive... */
+#define screen_left_x(s, x) ((x) + 1)
+#define screen_right_x(s, x) \
+ ((x) < screen_size_x(s) ? screen_size_x(s) - (x) : 0)
+
+#define screen_above_y(s, y) ((y) + 1)
+#define screen_below_y(s, y) \
+ ((y) < screen_size_y(s) ? screen_size_y(s) - (y) : 0)
+
/* Screen default contents. */
#define SCREEN_DEFDATA ' '
#define SCREEN_DEFATTR 0
#define SCREEN_DEFCOLR 0x88
-
+
/* Input parser sequence argument. */
struct input_arg {
u_char data[64];
@@ -437,6 +442,7 @@ struct input_arg {
/* Input parser context. */
struct input_ctx {
struct window *w;
+ struct screen_write_ctx ctx;
u_char *buf;
size_t len;
@@ -462,9 +468,8 @@ struct input_ctx {
*/
struct window_mode {
void (*init)(struct window *);
+ void (*free)(struct window *);
void (*resize)(struct window *, u_int, u_int);
- void (*draw)(
- struct window *, struct screen_draw_ctx *, u_int, u_int);
void (*key)(struct window *, int);
};
@@ -480,8 +485,10 @@ struct window {
int flags;
#define WINDOW_BELL 0x1
+#define WINDOW_HIDDEN 0x2
- struct screen screen;
+ struct screen *screen;
+ struct screen base;
const struct window_mode *mode;
void *modedata;
@@ -661,7 +668,7 @@ 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);
+void tty_vwrite(struct tty *, struct screen *s, int, va_list);
/* tty-keys.c */
int tty_keys_cmp(struct tty_key *, struct tty_key *);
@@ -787,27 +794,13 @@ void input_parse(struct window *);
void input_key(struct window *, int);
/* screen-display.c */
+void screen_display_set_cell(
+ struct screen *, u_int, u_int, u_char, u_char, u_char);
void screen_display_make_lines(struct screen *, u_int, u_int);
void screen_display_free_lines(struct screen *, u_int, u_int);
void screen_display_move_lines(struct screen *, u_int, u_int, u_int);
-void screen_display_fill_lines(
- struct screen *, u_int, u_int, u_char, u_char, u_char);
-void screen_display_fill_cells(
- struct screen *, u_int, u_int, u_int, u_char, u_char, u_char);
-void screen_display_fill_screen(struct screen *, u_char, u_char, u_char);
-void screen_display_fill_cursor_eos(
- struct screen *, u_char, u_char, u_char);
-void screen_display_fill_cursor_bos(
- struct screen *, u_char, u_char, u_char);
-void screen_display_fill_line(
- struct screen *, u_int, u_char, u_char, u_char);
-void screen_display_fill_cursor_bol(
- struct screen *, u_char, u_char, u_char);
-void screen_display_fill_cursor_eol(
- struct screen *, u_char, u_char, u_char);
-void screen_display_cursor_set(struct screen *, u_char);
-void screen_display_cursor_up(struct screen *);
-void screen_display_cursor_down(struct screen *);
+void screen_display_fill_area(struct screen *,
+ u_int, u_int, u_int, u_int, u_char, u_char, u_char);
void screen_display_scroll_region_up(struct screen *);
void screen_display_scroll_region_down(struct screen *);
void screen_display_insert_lines(struct screen *, u_int, u_int);
@@ -816,6 +809,64 @@ void screen_display_delete_lines(struct screen *, u_int, u_int);
void screen_display_delete_lines_region(struct screen *, u_int, u_int);
void screen_display_insert_characters(struct screen *, u_int, u_int, u_int);
void screen_display_delete_characters(struct screen *, u_int, u_int, u_int);
+void screen_display_copy_area(struct screen *, struct screen *,
+ u_int, u_int, u_int, u_int, u_int, u_int);
+
+/* screen-write.c */
+void screen_write_start_window(struct screen_write_ctx *, struct window *);
+void screen_write_start_client(struct screen_write_ctx *, struct client *);
+void screen_write_start_session(
+ struct screen_write_ctx *, struct session *);
+void screen_write_start(struct screen_write_ctx *,
+ struct screen *, void (*)(void *, int, ...), void *);
+void screen_write_stop(struct screen_write_ctx *);
+void screen_write_set_title(struct screen_write_ctx *, char *);
+void screen_write_put_character(struct screen_write_ctx *, u_char);
+size_t printflike2 screen_write_put_string_rjust(
+ struct screen_write_ctx *, const char *, ...);
+void printflike2 screen_write_put_string(
+ struct screen_write_ctx *, const char *, ...);
+void screen_write_set_attributes(struct screen_write_ctx *, u_char, u_char);
+void screen_write_set_region(struct screen_write_ctx *, u_int, u_int);
+void screen_write_cursor_up_scroll(struct screen_write_ctx *);
+void screen_write_cursor_down_scroll(struct screen_write_ctx *);
+void screen_write_cursor_up(struct screen_write_ctx *, u_int);
+void screen_write_cursor_down(struct screen_write_ctx *, u_int);
+void screen_write_cursor_left(struct screen_write_ctx *, u_int);
+void screen_write_cursor_right(struct screen_write_ctx *, u_int);
+void screen_write_delete_lines(struct screen_write_ctx *, u_int);
+void screen_write_delete_characters(struct screen_write_ctx *, u_int);
+void screen_write_insert_lines(struct screen_write_ctx *, u_int);
+void screen_write_insert_characters(struct screen_write_ctx *, u_int);
+void screen_write_move_cursor(struct screen_write_ctx *, u_int, u_int);
+void screen_write_fill_end_of_screen(struct screen_write_ctx *);
+void screen_write_fill_screen(struct screen_write_ctx *);
+void screen_write_fill_end_of_line(struct screen_write_ctx *);
+void screen_write_fill_start_of_line(struct screen_write_ctx *);
+void screen_write_fill_line(struct screen_write_ctx *);
+void screen_write_set_mode(struct screen_write_ctx *, int);
+void screen_write_clear_mode(struct screen_write_ctx *, int);
+void screen_write_copy_area(struct screen_write_ctx *,
+ struct screen *, u_int, u_int, u_int, u_int);
+
+/* screen-redraw.c */
+void screen_redraw_start_window(struct screen_redraw_ctx *, struct window *);
+void screen_redraw_start_client(struct screen_redraw_ctx *, struct client *);
+void screen_redraw_start_session(
+ struct screen_redraw_ctx *, struct session *);
+void screen_redraw_start(struct screen_redraw_ctx *,
+ struct screen *, void (*)(void *, int, ...), void *);
+void screen_redraw_stop(struct screen_redraw_ctx *);
+void screen_redraw_move_cursor(struct screen_redraw_ctx *, u_int, u_int);
+void screen_redraw_set_attributes(struct screen_redraw_ctx *, u_int, u_int);
+void printflike2 screen_redraw_write_string(
+ struct screen_redraw_ctx *, const char *, ...);
+void screen_redraw_clear_end_of_line(struct screen_redraw_ctx *);
+void screen_redraw_clear_screen(struct screen_redraw_ctx *);
+void screen_redraw_cell(struct screen_redraw_ctx *, u_int, u_int);
+void screen_redraw_area(
+ struct screen_redraw_ctx *, u_int, u_int, u_int, u_int);
+void screen_redraw_lines(struct screen_redraw_ctx *, u_int, u_int);
/* screen.c */
const char *screen_colourstring(u_char);
@@ -828,44 +879,14 @@ 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_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_offset(struct screen_draw_ctx *, u_int, u_int);
-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_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);
-void screen_draw_column(struct screen_draw_ctx *, u_int);
-void screen_draw_line(struct screen_draw_ctx *, u_int);
-void screen_draw_lines(struct screen_draw_ctx *, u_int, u_int);
-void screen_draw_screen(struct screen_draw_ctx *);
void screen_make_lines(struct screen *, u_int, u_int);
void screen_free_lines(struct screen *, u_int, u_int);
void screen_move_lines(struct screen *, u_int, u_int, u_int);
-void screen_fill_lines(
- struct screen *, u_int, u_int, u_char, u_char, u_char);
-void screen_fill_cells(
- struct screen *, u_int, u_int, u_int, u_char, u_char, u_char);
+void screen_fill_area(struct screen *,
+ u_int, u_int, u_int, u_int, u_char, u_char, u_char);
+void screen_set_selection(struct screen *, u_int, u_int, u_int, u_int);
+void screen_clear_selection(struct screen *);
+int screen_check_selection(struct screen *, u_int, u_int);
/* window.c */
extern struct windows windows;
@@ -885,8 +906,6 @@ struct window *window_create(
void window_destroy(struct window *);
int window_resize(struct window *, 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 */
diff --git a/tty-keys.c b/tty-keys.c
index 186bf819..42c3e34f 100644
--- a/tty-keys.c
+++ b/tty-keys.c
@@ -1,4 +1,4 @@
-/* $Id: tty-keys.c,v 1.1 2007-11-27 19:23:34 nicm Exp $ */
+/* $Id: tty-keys.c,v 1.2 2007-12-06 09:46:23 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -259,7 +259,7 @@ tty_keys_next(struct tty *tty, int *code)
}
xfree(s);
if (tk == NULL) {
- /*
+ /*
* XXX Pass through unchanged.
*/
*code = '\e';
diff --git a/tty-write.c b/tty-write.c
index e796b3e1..a58f1b2e 100644
--- a/tty-write.c
+++ b/tty-write.c
@@ -1,4 +1,4 @@
-/* $Id: tty-write.c,v 1.1 2007-11-27 19:23:34 nicm Exp $ */
+/* $Id: tty-write.c,v 1.2 2007-12-06 09:46:23 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -24,8 +24,7 @@ void
tty_write_client(void *ptr, int cmd, ...)
{
struct client *c = ptr;
-
- va_list ap;
+ va_list ap;
va_start(ap, cmd);
tty_vwrite_client(c, cmd, ap);
@@ -36,8 +35,9 @@ void
tty_vwrite_client(void *ptr, int cmd, va_list ap)
{
struct client *c = ptr;
+ struct screen *s = c->session->curw->window->screen;
- tty_vwrite(&c->tty, cmd, ap);
+ tty_vwrite(&c->tty, s, cmd, ap);
}
void
@@ -58,7 +58,7 @@ tty_vwrite_window(void *ptr, int cmd, va_list ap)
va_list aq;
u_int i;
- if (w->screen.mode & MODE_HIDDEN)
+ if (w->flags & WINDOW_HIDDEN)
return;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
@@ -68,8 +68,8 @@ tty_vwrite_window(void *ptr, int cmd, va_list ap)
if (c->session->curw->window != w)
continue;
- va_copy(aq, ap);
- tty_vwrite(&c->tty, cmd, aq);
+ va_copy(aq, ap);
+ tty_vwrite_client(c, cmd, aq);
va_end(aq);
}
}
@@ -101,7 +101,7 @@ tty_vwrite_session(void *ptr, int cmd, va_list ap)
continue;
va_copy(aq, ap);
- tty_vwrite(&c->tty, cmd, aq);
+ tty_vwrite_client(c, cmd, aq);
va_end(aq);
}
}
diff --git a/tty.c b/tty.c
index 3944ff0a..ec7097c8 100644
--- a/tty.c
+++ b/tty.c
@@ -1,4 +1,4 @@
-/* $Id: tty.c,v 1.8 2007-12-03 10:47:27 nicm Exp $ */
+/* $Id: tty.c,v 1.9 2007-12-06 09:46:23 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -25,7 +25,7 @@
#include <string.h>
#define TTYDEFCHARS
/* glibc requires unistd.h before termios.h for TTYDEFCHARS. */
-#include <unistd.h>
+#include <unistd.h>
#include <termios.h>
#include "tmux.h"
@@ -87,7 +87,7 @@ tty_open(struct tty *tty, char **cause)
tty->colr = SCREEN_DEFCOLR;
tty_keys_init(tty);
-
+
tty_fill_acs(tty);
if (tcgetattr(tty->fd, &tty->tio) != 0)
@@ -95,7 +95,7 @@ tty_open(struct tty *tty, char **cause)
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 =
+ 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);
@@ -207,10 +207,10 @@ tty_putc(struct tty *tty, char ch)
}
void
-tty_vwrite(struct tty *tty, int cmd, va_list ap)
+tty_vwrite(struct tty *tty, unused struct screen *s, int cmd, va_list ap)
{
char ch;
- u_int ua, ub;
+ u_int i, ua, ub;
set_curterm(tty->termp);
@@ -258,13 +258,36 @@ tty_vwrite(struct tty *tty, int cmd, va_list ap)
tty_puts(tty, tparm(cursor_address, ua, ub));
break;
case TTY_CLEARENDOFLINE:
- tty_puts(tty, clr_eol);
+ if (clr_eol != NULL)
+ tty_puts(tty, clr_eol);
+ else {
+ tty_puts(tty, tparm(cursor_address, s->cy, s->cx));
+ for (i = s->cx; i < screen_size_x(s); i++)
+ tty_putc(tty, ' ');
+ tty_puts(tty, tparm(cursor_address, s->cy, s->cx));
+ }
break;
case TTY_CLEARSTARTOFLINE:
- tty_puts(tty, clr_bol);
+ if (clr_bol != NULL)
+ tty_puts(tty, clr_bol);
+ else {
+ tty_puts(tty, tparm(cursor_address, s->cy, 0));
+ for (i = 0; i < s->cx + 1; i++)
+ tty_putc(tty, ' ');
+ tty_puts(tty, tparm(cursor_address, s->cy, s->cx));
+ }
break;
case TTY_CLEARLINE:
- tty_puts(tty, clr_eol); /* XXX */
+ if (clr_eol != NULL) {
+ tty_puts(tty, tparm(cursor_address, s->cy, 0));
+ tty_puts(tty, clr_eol);
+ tty_puts(tty, tparm(cursor_address, s->cy, s->cx));
+ } else {
+ tty_puts(tty, tparm(cursor_address, s->cy, 0));
+ for (i = 0; i < screen_size_x(s); i++)
+ tty_putc(tty, ' ');
+ tty_puts(tty, tparm(cursor_address, s->cy, s->cx));
+ }
break;
case TTY_INSERTLINE:
ua = va_arg(ap, u_int);
@@ -323,6 +346,7 @@ tty_vwrite(struct tty *tty, int cmd, va_list ap)
ub = va_arg(ap, u_int);
tty_puts(tty, tparm(change_scroll_region, ua, ub));
break;
+#if 0
case TTY_INSERTON:
if (enter_insert_mode != NULL)
tty_puts(tty, enter_insert_mode);
@@ -331,7 +355,6 @@ tty_vwrite(struct tty *tty, int cmd, va_list ap)
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)
@@ -417,13 +440,13 @@ tty_attributes(struct tty *tty, u_char attr, u_char colr)
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) {
diff --git a/window-copy.c b/window-copy.c
index e6c588c4..afbeb31d 100644
--- a/window-copy.c
+++ b/window-copy.c
@@ -1,4 +1,4 @@
-/* $Id: window-copy.c,v 1.12 2007-11-27 19:43:50 nicm Exp $ */
+/* $Id: window-copy.c,v 1.13 2007-12-06 09:46:23 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -23,25 +23,34 @@
#include "tmux.h"
void window_copy_init(struct window *);
+void window_copy_free(struct window *);
void window_copy_resize(struct window *, 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 *);
-
+void window_copy_redraw_lines(struct window *, u_int, u_int);
+void window_copy_redraw_screen(struct window *);
+void window_copy_write_line(
+ struct window *, struct screen_write_ctx *, u_int);
+void window_copy_write_lines(
+ struct window *, struct screen_write_ctx *, u_int, u_int);
+void window_copy_write_column(
+ struct window *, struct screen_write_ctx *, u_int);
+void window_copy_write_columns(
+ struct window *, struct screen_write_ctx *, u_int, u_int);
+
+void window_copy_update_cursor(struct window *);
+void window_copy_start_selection(struct window *);
+int window_copy_update_selection(struct window *);
void window_copy_copy_selection(struct window *);
void window_copy_copy_line(
- struct window *, char **, size_t *, size_t *, u_int, u_int, u_int);
+ struct window *, char **, size_t *, size_t *, u_int, u_int, u_int);
u_int window_copy_find_length(struct window *, u_int);
-void window_copy_move_cursor(struct window *);
-void window_copy_cursor_bol(struct window *);
-void window_copy_cursor_eol(struct window *);
+void window_copy_cursor_start_of_line(struct window *);
+void window_copy_cursor_end_of_line(struct window *);
void window_copy_cursor_left(struct window *);
void window_copy_cursor_right(struct window *);
void window_copy_cursor_up(struct window *);
void window_copy_cursor_down(struct window *);
-void window_copy_draw_lines(struct window *, u_int, u_int);
void window_copy_scroll_left(struct window *, u_int);
void window_copy_scroll_right(struct window *, u_int);
void window_copy_scroll_up(struct window *, u_int);
@@ -49,106 +58,87 @@ void window_copy_scroll_down(struct window *, u_int);
const struct window_mode window_copy_mode = {
window_copy_init,
+ window_copy_free,
window_copy_resize,
- window_copy_draw,
window_copy_key
};
struct window_copy_mode_data {
+ struct screen screen;
+
u_int ox;
u_int oy;
- u_int cx;
- u_int cy;
- u_int size;
- int selflag;
u_int selx;
u_int sely;
+
+ u_int cx;
+ u_int cy;
};
void
window_copy_init(struct window *w)
{
struct window_copy_mode_data *data;
+ struct screen *s;
+ struct screen_write_ctx ctx;
+ u_int i;
w->modedata = data = xmalloc(sizeof *data);
- data->ox = data->oy = 0;
- data->cx = w->screen.cx;
- data->cy = w->screen.cy;
- data->size = w->screen.hsize;
- data->selflag = 0;
-
- w->screen.mode |= (MODE_BACKGROUND|MODE_BGCURSOR);
-}
-
-void
-window_copy_resize(unused struct window *w, unused u_int sx, unused u_int sy)
-{
+ data->ox = 0;
+ data->oy = 0;
+ data->cx = w->base.cx;
+ data->cy = w->base.cy;
+
+ s = &data->screen;
+ screen_create(s, screen_size_x(&w->base), screen_size_y(&w->base));
+ s->cx = data->cx;
+ s->cy = data->cy;
+ w->screen = s;
+
+ screen_write_start(&ctx, s, NULL, NULL);
+ for (i = 0; i < screen_size_y(s); i++)
+ window_copy_write_line(w, &ctx, i);
+ screen_write_move_cursor(&ctx, data->cx, data->cy);
+ screen_write_stop(&ctx);
}
void
-window_copy_draw_position(struct window *w, struct screen_draw_ctx *ctx)
+window_copy_free(struct window *w)
{
struct window_copy_mode_data *data = w->modedata;
- char *ptr, buf[32];
- size_t len;
- len = xsnprintf(
- buf, sizeof buf, "[%u,%u/%u]", data->ox, data->oy, data->size);
- if (len <= screen_size_x(ctx->s))
- ptr = buf;
- else {
- ptr = buf + len - screen_size_x(ctx->s);
- len -= len - screen_size_x(ctx->s);
- }
-
- screen_draw_cells(ctx, 0, 0, screen_size_x(ctx->s) - len);
-
- screen_draw_move_cursor(ctx, screen_size_x(ctx->s) - len, 0);
- screen_draw_set_attributes(ctx, 0, status_colour);
- screen_draw_write_string(ctx, "%s", ptr);
+ w->screen = &w->base;
+ screen_destroy(&data->screen);
+
+ w->mode = NULL;
+ xfree(w->modedata);
}
void
-window_copy_draw(
- struct window *w, struct screen_draw_ctx *ctx, u_int py, u_int ny)
+window_copy_resize(struct window *w, u_int sx, u_int sy)
{
struct window_copy_mode_data *data = w->modedata;
- struct screen *s = &w->screen;
-
- if (s->hsize != data->size) {
- data->oy += s->hsize - data->size;
- data->size = s->hsize;
- }
- screen_draw_set_offset(ctx, 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);
- window_copy_draw_position(w, ctx);
- }
+ struct screen *s = &data->screen;
- window_copy_move_cursor(w);
+ screen_resize(s, sx, sy);
+ screen_display_copy_area(&data->screen, &w->base,
+ 0, 0, screen_size_x(s), screen_size_y(s), data->ox, data->oy);
+ window_copy_update_selection(w);
}
void
window_copy_key(struct window *w, int key)
{
struct window_copy_mode_data *data = w->modedata;
- u_int oy, sy;
-
- sy = screen_size_y(&w->screen);
- oy = data->oy;
+ struct screen *s = &data->screen;
switch (key) {
case 'Q':
case 'q':
- goto done;
+ window_copy_free(w);
+ server_redraw_window(w);
+ break;
case 'h':
case KEYC_LEFT:
window_copy_cursor_left(w);
@@ -169,55 +159,199 @@ window_copy_key(struct window *w, int key)
return;
case '\025': /* C-u */
case KEYC_PPAGE:
- if (data->oy + sy > data->size)
- data->oy = data->size;
+ if (data->oy + screen_size_y(s) > w->base.hsize)
+ data->oy = w->base.hsize;
else
- data->oy += sy;
+ data->oy += screen_size_y(s);
+ window_copy_update_selection(w);
+ window_copy_redraw_screen(w);
break;
case '\006': /* C-f */
case KEYC_NPAGE:
- if (data->oy < sy)
+ if (data->oy < screen_size_y(s))
data->oy = 0;
else
- data->oy -= sy;
+ data->oy -= screen_size_y(s);
+ window_copy_update_selection(w);
+ window_copy_redraw_screen(w);
break;
case '\000': /* C-space */
case ' ':
- data->selflag = !data->selflag;
- data->selx = data->cx + data->ox;
- data->sely = data->size + data->cy - data->oy;
- oy = -1; /* XXX */
+ window_copy_start_selection(w);
break;
case '\033':
- data->selflag = 0;
- oy = -1; /* XXX */
- break;
+ screen_clear_selection(&data->screen);
+ break;
case '\027': /* C-w */
case '\r': /* enter */
- if (data->selflag)
- window_copy_copy_selection(w);
- goto done;
+ window_copy_copy_selection(w);
+ window_copy_free(w);
+ server_redraw_window(w);
+ break;
case '\001': /* C-a */
- window_copy_cursor_bol(w);
- return;
+ window_copy_cursor_start_of_line(w);
+ break;
case '\005': /* C-e */
- window_copy_cursor_eol(w);
- return;
+ window_copy_cursor_end_of_line(w);
+ break;
}
- if (data->oy != oy) {
- server_redraw_window(w);
- window_copy_move_cursor(w);
+}
+
+void
+window_copy_write_line(
+ struct window *w, struct screen_write_ctx *ctx, u_int py)
+{
+ struct window_copy_mode_data *data = w->modedata;
+ struct screen *s = &data->screen;
+ size_t size;
+
+ if (py == 0) {
+ screen_write_set_attributes(ctx, 0, status_colour);
+ screen_write_move_cursor(ctx, 0, 0);
+ size = screen_write_put_string_rjust(
+ ctx, "[%u,%u/%u]", data->ox, data->oy, w->base.hsize);
+ screen_write_set_attributes(
+ ctx, SCREEN_DEFATTR, SCREEN_DEFCOLR);
+ } else
+ size = 0;
+ screen_write_move_cursor(ctx, 0, py);
+ screen_write_copy_area(
+ ctx, &w->base, screen_size_x(s) - size, 1, data->ox, data->oy);
+}
+
+void
+window_copy_write_lines(
+ struct window *w, struct screen_write_ctx *ctx, u_int py, u_int ny)
+{
+ struct window_copy_mode_data *data = w->modedata;
+ struct screen *s = &data->screen;
+
+ if (py == 0) {
+ window_copy_write_line(w, ctx, 0);
+ if (ny == 1)
+ return;
+ py++;
+ ny--;
}
- return;
+ screen_write_move_cursor(ctx, 0, py);
+ screen_write_copy_area(
+ ctx, &w->base, screen_size_x(s), ny, data->ox, data->oy);
+}
-done:
- w->mode = NULL;
- xfree(w->modedata);
-
- w->screen.mode &= ~MODE_BACKGROUND;
-
- recalculate_sizes();
- server_redraw_window(w);
+void
+window_copy_write_column(
+ struct window *w, struct screen_write_ctx *ctx, u_int px)
+{
+ struct window_copy_mode_data *data = w->modedata;
+ struct screen *s = &data->screen;
+
+ screen_write_move_cursor(ctx, px, 0);
+ screen_write_copy_area(
+ ctx, &w->base, 1, screen_size_y(s), data->ox, data->oy);
+}
+
+void
+window_copy_write_columns(
+ struct window *w, struct screen_write_ctx *ctx, u_int px, u_int nx)
+{
+ struct window_copy_mode_data *data = w->modedata;
+ struct screen *s = &data->screen;
+
+ screen_write_move_cursor(ctx, px, 0);
+ screen_write_copy_area(
+ ctx, &w->base, nx, screen_size_y(s), data->ox, data->oy);
+}
+
+void
+window_copy_redraw_lines(struct window *w, u_int py, u_int ny)
+{
+ struct window_copy_mode_data *data = w->modedata;
+ struct screen_write_ctx ctx;
+ u_int i;
+
+ screen_write_start_window(&ctx, w);
+ for (i = py; i < py + ny; i++)
+ window_copy_write_line(w, &ctx, i);
+ screen_write_move_cursor(&ctx, data->cx, data->cy);
+ screen_write_stop(&ctx);
+}
+
+void
+window_copy_redraw_screen(struct window *w)
+{
+ struct window_copy_mode_data *data = w->modedata;
+
+ window_copy_redraw_lines(w, 0, screen_size_x(&data->screen));
+}
+
+void
+window_copy_update_cursor(struct window *w)
+{
+ struct window_copy_mode_data *data = w->modedata;
+ struct screen_write_ctx ctx;
+
+ screen_write_start_window(&ctx, w);
+ screen_write_move_cursor(&ctx, data->cx, data->cy);
+ screen_write_stop(&ctx);
+}
+
+void
+window_copy_start_selection(struct window *w)
+{
+ struct window_copy_mode_data *data = w->modedata;
+ struct screen *s = &data->screen;
+
+ data->selx = screen_x(&w->base, data->cx) + data->ox;
+ data->sely = screen_y(&w->base, data->cy) - data->oy;
+
+ s->sel.flag = 1;
+ window_copy_update_selection(w);
+}
+
+int
+window_copy_update_selection(struct window *w)
+{
+ struct window_copy_mode_data *data = w->modedata;
+ struct screen *s = &data->screen;
+ u_int sx, sy, tx, ty;
+
+ if (!s->sel.flag)
+ return (0);
+
+ /* Find top-left of screen. */
+ tx = screen_x(&w->base, 0) + data->ox;
+ ty = screen_y(&w->base, 0) - data->oy;
+
+ /* Adjust the selection. */
+ sx = data->selx;
+ sy = data->sely;
+ if (sy < ty) {
+ /* Above it. */
+ sx = 0;
+ sy = 0;
+ } else if (sy > ty + screen_last_y(s)) {
+ /* Below it. */
+ sx = screen_last_x(s);
+ sy = screen_last_y(s);
+ } else if (sx < tx) {
+ /* To the left. */
+ sx = 0;
+ } else if (sx > tx + screen_last_x(s)) {
+ /* To the right. */
+ sx = 0;
+ sy++;
+ if (sy > screen_last_y(s))
+ sy = screen_last_y(s);
+ } else {
+ sx -= tx;
+ sy -= ty;
+ }
+ sx = screen_x(s, sx);
+ sy = screen_x(s, sy);
+
+ screen_set_selection(
+ s, sx, sy, screen_x(s, data->cx), screen_y(s, data->cy));
+ return (1);
}
void
@@ -234,9 +368,14 @@ window_copy_copy_selection(struct window *w)
*buf = '\0';
+ /*
+ * The selection extends from selx,sely to (adjusted) cx,cy on
+ * the base screen.
+ */
+
/* Find start and end. */
- xx = data->cx + data->ox;
- yy = data->size + data->cy - data->oy;
+ xx = screen_x(&w->base, data->cx) + data->ox;
+ yy = screen_y(&w->base, data->cy) - data->oy;
if (xx < data->selx || (yy == data->sely && xx < data->selx)) {
sx = xx; sy = yy;
ex = data->selx; ey = data->sely;
@@ -281,8 +420,7 @@ void
window_copy_copy_line(struct window *w,
char **buf, size_t *off, size_t *len, u_int sy, u_int sx, u_int ex)
{
- struct screen *s = &w->screen;
- u_char i, xx;
+ u_char i, xx;
if (sx > ex)
return;
@@ -296,11 +434,11 @@ window_copy_copy_line(struct window *w,
if (sx < ex) {
for (i = sx; i < ex; i++) {
*buf = ensure_size(*buf, len, 1, *off + 1);
- (*buf)[*off] = s->grid_data[sy][i];
+ (*buf)[*off] = w->base.grid_data[sy][i];
(*off)++;
}
}
-
+
*buf = ensure_size(*buf, len, 1, *off + 1);
(*buf)[*off] = '\n';
(*off)++;
@@ -309,25 +447,16 @@ window_copy_copy_line(struct window *w,
u_int
window_copy_find_length(struct window *w, u_int py)
{
- struct screen *s = &w->screen;
- u_int px;
+ u_int px;
- px = s->grid_size[py];
- while (px > 0 && s->grid_data[py][px - 1] == SCREEN_DEFDATA)
+ px = w->base.grid_size[py];
+ while (px > 0 && w->base.grid_data[py][px - 1] == SCREEN_DEFDATA)
px--;
return (px);
}
void
-window_copy_move_cursor(struct window *w)
-{
- struct window_copy_mode_data *data = w->modedata;
-
- tty_write_window(w, TTY_CURSORMOVE, data->cy, data->cx);
-}
-
-void
-window_copy_cursor_bol(struct window *w)
+window_copy_cursor_start_of_line(struct window *w)
{
struct window_copy_mode_data *data = w->modedata;
@@ -335,49 +464,52 @@ window_copy_cursor_bol(struct window *w)
window_copy_scroll_right(w, data->ox);
data->cx = 0;
- if (data->selflag)
- window_copy_draw_lines(w, data->cy, 1);
- window_copy_move_cursor(w);
+ if (window_copy_update_selection(w))
+ window_copy_redraw_lines(w, data->cy, 1);
+ else
+ window_copy_update_cursor(w);
}
void
-window_copy_cursor_eol(struct window *w)
+window_copy_cursor_end_of_line(struct window *w)
{
struct window_copy_mode_data *data = w->modedata;
- struct screen *s = &w->screen;
- u_int xx;
+ struct screen *s = &data->screen;
+ u_int px, py;
- xx = window_copy_find_length(w, data->size + data->cy - data->oy);
+ py = screen_y(&w->base, data->cy) - data->oy;
+ px = window_copy_find_length(w, py);
/* On screen. */
- if (xx > data->ox && xx < data->ox + screen_last_x(s))
- data->cx = xx - data->ox;
+ if (px > data->ox && px < data->ox + screen_last_x(s))
+ data->cx = px - data->ox;
/* Off right of screen. */
- if (xx > data->ox + screen_last_x(s)) {
+ if (px > data->ox + screen_last_x(s)) {
/* Move cursor to last and scroll screen. */
window_copy_scroll_left(w,
- xx - data->ox - screen_last_x(s));
+ px - data->ox - screen_last_x(s));
data->cx = screen_last_x(s);
}
/* Off left of screen. */
- if (xx <= data->ox) {
- if (xx < screen_last_x(s)) {
+ if (px <= data->ox) {
+ if (px < screen_last_x(s)) {
/* Short enough to fit on screen. */
window_copy_scroll_right(w, data->ox);
- data->cx = xx;
+ data->cx = px;
} else {
/* Too long to fit on screen. */
window_copy_scroll_right(
- w, data->ox - (xx - screen_last_x(s)));
+ w, data->ox - (px - screen_last_x(s)));
data->cx = screen_last_x(s);
}
}
- if (data->selflag)
- window_copy_draw_lines(w, data->cy, 1);
- window_copy_move_cursor(w);
+ if (window_copy_update_selection(w))
+ window_copy_redraw_lines(w, data->cy, 1);
+ else
+ window_copy_update_cursor(w);
}
void
@@ -385,79 +517,102 @@ window_copy_cursor_left(struct window *w)
{
struct window_copy_mode_data *data = w->modedata;
- if (data->cx == 0)
- window_copy_scroll_right(w, 1);
- else {
+ if (data->cx == 0) {
+ if (data->ox > 0)
+ window_copy_scroll_right(w, 1);
+ else {
+ window_copy_cursor_up(w);
+ window_copy_cursor_end_of_line(w);
+ }
+ } else {
data->cx--;
- if (data->selflag)
- window_copy_draw_lines(w, data->cy, 1);
+ if (window_copy_update_selection(w))
+ window_copy_redraw_lines(w, data->cy, 1);
+ else
+ window_copy_update_cursor(w);
}
- window_copy_move_cursor(w);
}
void
window_copy_cursor_right(struct window *w)
{
struct window_copy_mode_data *data = w->modedata;
- struct screen *s = &w->screen;
+ u_int px, py;
- if (data->cx == screen_last_x(s))
- window_copy_scroll_left(w, 1);
- else {
+ py = screen_y(&w->base, data->cy) - data->oy;
+ px = window_copy_find_length(w, py);
+
+ if (data->cx >= px) {
+ window_copy_cursor_start_of_line(w);
+ window_copy_cursor_down(w);
+ } else {
data->cx++;
- if (data->selflag)
- window_copy_draw_lines(w, data->cy, 1);
+ if (window_copy_update_selection(w))
+ window_copy_redraw_lines(w, data->cy, 1);
+ else
+ window_copy_update_cursor(w);
}
- window_copy_move_cursor(w);
}
void
window_copy_cursor_up(struct window *w)
{
struct window_copy_mode_data *data = w->modedata;
+ u_int ox, oy, px, py;
+
+ oy = screen_y(&w->base, data->cy) - data->oy;
+ ox = window_copy_find_length(w, oy);
if (data->cy == 0)
window_copy_scroll_down(w, 1);
else {
data->cy--;
- if (data->selflag)
- window_copy_draw_lines(w, data->cy, 2);
+ if (window_copy_update_selection(w))
+ window_copy_redraw_lines(w, data->cy, 2);
+ else
+ window_copy_update_cursor(w);
}
- window_copy_move_cursor(w);
+
+ py = screen_y(&w->base, data->cy) - data->oy;
+ px = window_copy_find_length(w, py);
+
+ if (data->cx > px || data->cx == ox)
+ window_copy_cursor_end_of_line(w);
}
void
window_copy_cursor_down(struct window *w)
{
struct window_copy_mode_data *data = w->modedata;
- struct screen *s = &w->screen;
+ struct screen *s = &data->screen;
+ u_int ox, oy, px, py;
+
+ oy = screen_y(&w->base, data->cy) - data->oy;
+ ox = window_copy_find_length(w, oy);
if (data->cy == screen_last_y(s))
window_copy_scroll_up(w, 1);
else {
data->cy++;
- if (data->selflag)
- window_copy_draw_lines(w, data->cy - 1, 2);
+ if (window_copy_update_selection(w))
+ window_copy_redraw_lines(w, data->cy - 1, 2);
+ else
+ window_copy_update_cursor(w);
}
- window_copy_move_cursor(w);
-}
-void
-window_copy_draw_lines(struct window *w, u_int py, u_int ny)
-{
- struct window_copy_mode_data *data = w->modedata;
- struct screen_draw_ctx ctx;
+ py = screen_y(&w->base, data->cy) - data->oy;
+ px = window_copy_find_length(w, py);
- screen_draw_start_window(&ctx, w, data->ox, data->oy);
- window_copy_draw(w, &ctx, py, ny);
- screen_draw_stop(&ctx);
+ if (data->cx > px || data->cx == ox)
+ window_copy_cursor_end_of_line(w);
}
void
window_copy_scroll_left(struct window *w, u_int nx)
{
struct window_copy_mode_data *data = w->modedata;
- struct screen_draw_ctx ctx;
+ struct screen *s = &data->screen;
+ struct screen_write_ctx ctx;
u_int i;
if (data->ox > SHRT_MAX - nx)
@@ -465,26 +620,29 @@ window_copy_scroll_left(struct window *w, u_int nx)
if (nx == 0)
return;
data->ox += nx;
-
- 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 (i = 1; i < screen_size_y(&w->screen); i++) {
- screen_draw_move_cursor(&ctx, 0, i);
- screen_draw_delete_characters(&ctx, nx);
+ window_copy_update_selection(w);
+
+ screen_write_start_window(&ctx, w);
+ for (i = 1; i < screen_size_y(s); i++) {
+ screen_write_move_cursor(&ctx, 0, i);
+ screen_write_delete_characters(&ctx, nx);
+ }
+ window_copy_write_columns(w, &ctx, screen_size_x(s) - nx, nx);
+ window_copy_write_line(w, &ctx, 0);
+ if (s->sel.flag) {
+ window_copy_update_selection(w);
+ window_copy_write_lines(w, &ctx, data->cy, 1);
}
- 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);
+ screen_write_move_cursor(&ctx, data->cx, data->cy);
+ screen_write_stop(&ctx);
}
void
window_copy_scroll_right(struct window *w, u_int nx)
{
struct window_copy_mode_data *data = w->modedata;
- struct screen_draw_ctx ctx;
+ struct screen *s = &data->screen;
+ struct screen_write_ctx ctx;
u_int i;
if (data->ox < nx)
@@ -492,72 +650,71 @@ window_copy_scroll_right(struct window *w, u_int nx)
if (nx == 0)
return;
data->ox -= nx;
+ window_copy_update_selection(w);
- 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 (i = 1; i < screen_size_y(&w->screen); i++) {
- screen_draw_move_cursor(&ctx, 0, i);
- screen_draw_insert_characters(&ctx, nx);
+ screen_write_start_window(&ctx, w);
+ for (i = 1; i < screen_size_y(s); i++) {
+ screen_write_move_cursor(&ctx, 0, i);
+ screen_write_insert_characters(&ctx, nx);
}
- for (i = 0; i < nx; i++)
- screen_draw_column(&ctx, i);
- window_copy_draw_position(w, &ctx);
- screen_draw_stop(&ctx);
+ window_copy_write_columns(w, &ctx, 0, nx);
+ window_copy_write_line(w, &ctx, 0);
+ if (s->sel.flag)
+ window_copy_write_lines(w, &ctx, data->cy, 1);
+ screen_write_move_cursor(&ctx, data->cx, data->cy);
+ screen_write_stop(&ctx);
}
void
window_copy_scroll_up(struct window *w, u_int ny)
{
struct window_copy_mode_data *data = w->modedata;
- struct screen_draw_ctx ctx;
- u_int i;
+ struct screen *s = &data->screen;
+ struct screen_write_ctx ctx;
if (data->oy < ny)
ny = data->oy;
if (ny == 0)
return;
data->oy -= ny;
-
- 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_cursor(&ctx, 0, 0);
- screen_draw_delete_lines(&ctx, ny);
- for (i = 0; i < ny; i++)
- screen_draw_line(&ctx, screen_last_y(&w->screen) - i);
- if (data->selflag)
- screen_draw_line(&ctx, screen_last_y(&w->screen) - ny);
- window_copy_draw_position(w, &ctx);
- screen_draw_stop(&ctx);
+ window_copy_update_selection(w);
+
+ screen_write_start_window(&ctx, w);
+ screen_write_move_cursor(&ctx, 0, 0);
+ screen_write_delete_lines(&ctx, ny);
+ window_copy_write_lines(w, &ctx, screen_size_y(s) - ny, ny);
+ window_copy_write_line(w, &ctx, 0);
+ if (s->sel.flag && screen_size_y(s) > ny)
+ window_copy_write_lines(w, &ctx, screen_size_y(s) - ny - 1, 1);
+ screen_write_move_cursor(&ctx, data->cx, data->cy);
+ screen_write_stop(&ctx);
}
void
window_copy_scroll_down(struct window *w, u_int ny)
{
struct window_copy_mode_data *data = w->modedata;
- struct screen_draw_ctx ctx;
- u_int i;
+ struct screen *s = &data->screen;
+ struct screen_write_ctx ctx;
- if (ny > data->size)
+ if (ny > w->base.hsize)
return;
- if (data->oy > data->size - ny)
- ny = data->size - data->oy;
+ if (data->oy > w->base.hsize - ny)
+ ny = w->base.hsize - data->oy;
if (ny == 0)
return;
data->oy += ny;
-
- 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_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);
+ window_copy_update_selection(w);
+
+ screen_write_start_window(&ctx, w);
+ screen_write_move_cursor(&ctx, 0, 0);
+ screen_write_insert_lines(&ctx, ny);
+ window_copy_write_lines(w, &ctx, 0, ny);
+ if (s->sel.flag && screen_size_y(s) > ny)
+ window_copy_write_lines(w, &ctx, ny, 1);
+ else if (ny == 1) /* nuke position */
+ window_copy_write_line(w, &ctx, 1);
+ screen_write_move_cursor(&ctx, data->cx, data->cy);
+ screen_write_stop(&ctx);
}
diff --git a/window-more.c b/window-more.c
index 618b4f81..64e4f03f 100644
--- a/window-more.c
+++ b/window-more.c
@@ -1,4 +1,4 @@
-/* $Id: window-more.c,v 1.5 2007-11-27 19:23:34 nicm Exp $ */
+/* $Id: window-more.c,v 1.6 2007-12-06 09:46:23 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -23,25 +23,27 @@
#include "tmux.h"
void window_more_init(struct window *);
+void window_more_free(struct window *);
void window_more_resize(struct window *, 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 *);
-void window_more_draw_line(struct window *, struct screen_draw_ctx *, u_int);
+void window_more_redraw_screen(struct window *);
+void window_more_write_line(
+ struct window *, struct screen_write_ctx *, u_int);
-void window_more_up_1(struct window *);
-void window_more_down_1(struct window *);
+void window_more_scroll_up(struct window *);
+void window_more_scroll_down(struct window *);
const struct window_mode window_more_mode = {
window_more_init,
+ window_more_free,
window_more_resize,
- window_more_draw,
window_more_key
};
struct window_more_mode_data {
+ struct screen screen;
+
ARRAY_DECL(, char *) list;
u_int top;
};
@@ -50,10 +52,25 @@ void
window_more_vadd(struct window *w, const char *fmt, va_list ap)
{
struct window_more_mode_data *data = w->modedata;
- char *s;
+ struct screen *s = &data->screen;
+ struct screen_write_ctx ctx;
+ char *msg;
+ u_int size;
+
+ xvasprintf(&msg, fmt, ap);
+ ARRAY_ADD(&data->list, msg);
- xvasprintf(&s, fmt, ap);
- ARRAY_ADD(&data->list, s);
+ size = ARRAY_LENGTH(&data->list);
+ if (size == 0)
+ return;
+ size--;
+ if (size >= data->top && size <= data->top + screen_last_y(s)) {
+ screen_write_start_window(&ctx, w);
+ window_more_write_line(w, &ctx, size - data->top);
+ if (size != data->top)
+ window_more_write_line(w, &ctx, 0);
+ screen_write_stop(&ctx);
+ }
}
void
@@ -70,170 +87,160 @@ void
window_more_init(struct window *w)
{
struct window_more_mode_data *data;
+ struct screen *s;
w->modedata = data = xmalloc(sizeof *data);
ARRAY_INIT(&data->list);
data->top = 0;
- w->screen.mode |= MODE_BACKGROUND;
- w->screen.mode &= ~MODE_BGCURSOR;
-}
-
-void
-window_more_resize(unused struct window *w, unused u_int sx, unused u_int sy)
-{
+ s = &data->screen;
+ screen_create(s, screen_size_x(&w->base), screen_size_y(&w->base));
+ s->mode = 0;
+ w->screen = s;
}
void
-window_more_draw_position(struct window *w, struct screen_draw_ctx *ctx)
+window_more_free(struct window *w)
{
struct window_more_mode_data *data = w->modedata;
- char *ptr, buf[32];
- size_t len;
- char *line;
-
- len = xsnprintf(
- buf, sizeof buf, "[%u/%u]", data->top, ARRAY_LENGTH(&data->list));
- if (len <= screen_size_x(ctx->s))
- ptr = buf;
- else {
- ptr = buf + len - screen_size_x(ctx->s);
- len -= len - screen_size_x(ctx->s);
- }
+ u_int i;
- screen_draw_move_cursor(ctx, 0, 0);
+ w->screen = &w->base;
+ screen_destroy(&data->screen);
- if (data->top < ARRAY_LENGTH(&data->list)) {
- 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);
+ for (i = 0; i < ARRAY_LENGTH(&data->list); i++)
+ xfree(ARRAY_ITEM(&data->list, i));
+ ARRAY_FREE(&data->list);
- screen_draw_move_cursor(ctx, screen_size_x(ctx->s) - len, 0);
- screen_draw_set_attributes(ctx, 0, status_colour);
- screen_draw_write_string(ctx, "%s", ptr);
+ w->mode = NULL;
+ xfree(w->modedata);
}
void
-window_more_draw_line(struct window *w, struct screen_draw_ctx *ctx, u_int py)
+window_more_resize(struct window *w, u_int sx, u_int sy)
{
struct window_more_mode_data *data = w->modedata;
- u_int p;
+ struct screen *s = &data->screen;
- 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))
- screen_draw_write_string(ctx, "%s", ARRAY_ITEM(&data->list, p));
-
- screen_draw_clear_line_to(ctx, screen_last_x(ctx->s));
-}
-
-void
-window_more_draw(
- struct window *w, struct screen_draw_ctx *ctx, u_int py, u_int ny)
-{
- u_int i;
-
- for (i = py; i < py + ny; i++) {
- if (i == 0)
- window_more_draw_position(w, ctx);
- else
- window_more_draw_line(w, ctx, i);
- }
+ screen_resize(s, sx, sy);
+ window_more_redraw_screen(w);
}
void
window_more_key(struct window *w, int key)
{
struct window_more_mode_data *data = w->modedata;
- u_int top, sy, i;
-
- sy = screen_size_y(&w->screen);
-
- top = data->top;
+ struct screen *s = &data->screen;
switch (key) {
case 'Q':
case 'q':
- for (i = 0; i < ARRAY_LENGTH(&data->list); i++)
- xfree(ARRAY_ITEM(&data->list, i));
- ARRAY_FREE(&data->list);
-
- w->mode = NULL;
- xfree(w->modedata);
-
- w->screen.mode &= ~MODE_BACKGROUND;
-
- recalculate_sizes();
+ window_more_free(w);
server_redraw_window(w);
- return;
+ break;
case 'k':
case 'K':
case KEYC_UP:
- window_more_up_1(w);
- return;
+ window_more_scroll_up(w);
+ break;
case 'j':
case 'J':
case KEYC_DOWN:
- window_more_down_1(w);
- return;
+ window_more_scroll_down(w);
+ break;
case '\025': /* C-u */
case KEYC_PPAGE:
- if (data->top < sy)
+ if (data->top < screen_size_y(s))
data->top = 0;
else
- data->top -= sy;
+ data->top -= screen_size_y(s);
+ window_more_redraw_screen(w);
break;
case '\006': /* C-f */
case KEYC_NPAGE:
- if (data->top + sy > ARRAY_LENGTH(&data->list))
+ if (data->top + screen_size_y(s) > ARRAY_LENGTH(&data->list))
data->top = ARRAY_LENGTH(&data->list);
else
- data->top += sy;
+ data->top += screen_size_y(s);
+ window_more_redraw_screen(w);
break;
}
- if (top != data->top)
- server_redraw_window(w);
}
void
-window_more_up_1(struct window *w)
+window_more_write_line(struct window *w, struct screen_write_ctx *ctx, u_int py)
+{
+ struct window_more_mode_data *data = w->modedata;
+ struct screen *s = &data->screen;
+ char *msg;
+ size_t size;
+
+ if (py == 0) {
+ screen_write_set_attributes(ctx, 0, status_colour);
+ screen_write_move_cursor(ctx, 0, 0);
+ size = screen_write_put_string_rjust(
+ ctx, "[%u/%u]", data->top, ARRAY_LENGTH(&data->list));
+ } else
+ size = 0;
+
+ screen_write_set_attributes(ctx, SCREEN_DEFATTR, SCREEN_DEFCOLR);
+ screen_write_move_cursor(ctx, 0, py);
+ if (data->top + py < ARRAY_LENGTH(&data->list)) {
+ msg = ARRAY_ITEM(&data->list, data->top + py);
+ screen_write_put_string(
+ ctx, "%.*s", (int) (screen_size_x(s) - size), msg);
+ }
+ while (s->cx < screen_size_x(s) - size)
+ screen_write_put_character(ctx, SCREEN_DEFDATA);
+}
+
+void
+window_more_redraw_screen(struct window *w)
+{
+ struct window_more_mode_data *data = w->modedata;
+ struct screen *s = &data->screen;
+ struct screen_write_ctx ctx;
+ u_int i;
+
+ screen_write_start_window(&ctx, w);
+ for (i = 0; i < screen_size_y(s); i++)
+ window_more_write_line(w, &ctx, i);
+ screen_write_stop(&ctx);
+}
+
+void
+window_more_scroll_up(struct window *w)
{
struct window_more_mode_data *data = w->modedata;
- struct screen_draw_ctx ctx;
+ struct screen_write_ctx ctx;
if (data->top == 0)
return;
data->top--;
- 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);
+ screen_write_start_window(&ctx, w);
+ screen_write_move_cursor(&ctx, 0, 0);
+ screen_write_insert_lines(&ctx, 1);
+ window_more_write_line(w, &ctx, 0);
+ window_more_write_line(w, &ctx, 1);
+ screen_write_stop(&ctx);
}
void
-window_more_down_1(struct window *w)
+window_more_scroll_down(struct window *w)
{
struct window_more_mode_data *data = w->modedata;
- struct screen *s = &w->screen;
- struct screen_draw_ctx ctx;
+ struct screen *s = &data->screen;
+ struct screen_write_ctx ctx;
if (data->top >= ARRAY_LENGTH(&data->list))
return;
data->top++;
- 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);
+ screen_write_start_window(&ctx, w);
+ screen_write_move_cursor(&ctx, 0, 0);
+ screen_write_delete_lines(&ctx, 1);
+ window_more_write_line(w, &ctx, screen_last_y(s));
+ window_more_write_line(w, &ctx, 0);
+ screen_write_stop(&ctx);
}
diff --git a/window-scroll.c b/window-scroll.c
index d696dabe..60d3d9cd 100644
--- a/window-scroll.c
+++ b/window-scroll.c
@@ -1,4 +1,4 @@
-/* $Id: window-scroll.c,v 1.14 2007-11-27 19:32:15 nicm Exp $ */
+/* $Id: window-scroll.c,v 1.15 2007-12-06 09:46:23 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -23,229 +23,253 @@
#include "tmux.h"
void window_scroll_init(struct window *);
+void window_scroll_free(struct window *);
void window_scroll_resize(struct window *, 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 *);
+void window_scroll_redraw_screen(struct window *);
+void window_scroll_write_line(
+ struct window *, struct screen_write_ctx *, u_int);
+void window_scroll_write_column(
+ struct window *, struct screen_write_ctx *, u_int);
-void window_scroll_up_1(struct window *);
-void window_scroll_down_1(struct window *);
-void window_scroll_left_1(struct window *);
-void window_scroll_right_1(struct window *);
+void window_scroll_scroll_up(struct window *);
+void window_scroll_scroll_down(struct window *);
+void window_scroll_scroll_left(struct window *);
+void window_scroll_scroll_right(struct window *);
const struct window_mode window_scroll_mode = {
window_scroll_init,
+ window_scroll_free,
window_scroll_resize,
- window_scroll_draw,
window_scroll_key
};
struct window_scroll_mode_data {
- u_int ox;
- u_int oy;
- u_int size;
+ struct screen screen;
+
+ u_int ox;
+ u_int oy;
};
void
window_scroll_init(struct window *w)
{
struct window_scroll_mode_data *data;
+ struct screen *s;
+ struct screen_write_ctx ctx;
+ u_int i;
w->modedata = data = xmalloc(sizeof *data);
- data->ox = data->oy = 0;
- data->size = w->screen.hsize;
-
- w->screen.mode |= MODE_BACKGROUND;
- w->screen.mode &= ~MODE_BGCURSOR;
-}
-
-void
-window_scroll_resize(unused struct window *w, unused u_int sx, unused u_int sy)
-{
+ data->ox = 0;
+ data->oy = 0;
+
+ s = &data->screen;
+ screen_create(s, screen_size_x(&w->base), screen_size_y(&w->base));
+ s->mode = 0;
+ w->screen = s;
+
+ screen_write_start(&ctx, s, NULL, NULL);
+ for (i = 0; i < screen_size_y(s); i++)
+ window_scroll_write_line(w, &ctx, i);
+ screen_write_stop(&ctx);
}
void
-window_scroll_draw_position(struct window *w, struct screen_draw_ctx *ctx)
+window_scroll_free(struct window *w)
{
struct window_scroll_mode_data *data = w->modedata;
- char *ptr, buf[32];
- size_t len;
-
- len = xsnprintf(
- buf, sizeof buf, "[%u,%u/%u]", data->ox, data->oy, data->size);
- if (len <= screen_size_x(ctx->s))
- ptr = buf;
- else {
- ptr = buf + len - screen_size_x(ctx->s);
- len -= len - screen_size_x(ctx->s);
- }
-
- screen_draw_cells(ctx, 0, 0, screen_size_x(ctx->s) - len);
-
- screen_draw_move_cursor(ctx, screen_size_x(ctx->s) - len, 0);
- screen_draw_set_attributes(ctx, 0, status_colour);
- screen_draw_write_string(ctx, "%s", ptr);
+
+ w->screen = &w->base;
+ screen_destroy(&data->screen);
+
+ w->mode = NULL;
+ xfree(w->modedata);
}
void
-window_scroll_draw(
- struct window *w, struct screen_draw_ctx *ctx, u_int py, u_int ny)
+window_scroll_resize(struct window *w, u_int sx, u_int sy)
{
struct window_scroll_mode_data *data = w->modedata;
- struct screen *s = &w->screen;
+ struct screen *s = &data->screen;
- if (s->hsize != data->size) {
- data->oy += s->hsize - data->size;
- data->size = s->hsize;
- }
- screen_draw_set_offset(ctx, 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);
- window_scroll_draw_position(w, ctx);
- }
+ screen_resize(s, sx, sy);
+ screen_display_copy_area(&data->screen, &w->base,
+ 0, 0, screen_size_x(s), screen_size_y(s), data->ox, data->oy);
}
void
window_scroll_key(struct window *w, int key)
{
struct window_scroll_mode_data *data = w->modedata;
- u_int ox, oy, sx, sy;
-
- sx = screen_size_x(&w->screen);
- sy = screen_size_y(&w->screen);
-
- ox = data->ox;
- oy = data->oy;
+ struct screen *s = &data->screen;
switch (key) {
case 'Q':
case 'q':
- w->mode = NULL;
- xfree(w->modedata);
-
- w->screen.mode &= ~MODE_BACKGROUND;
-
- recalculate_sizes();
+ window_scroll_free(w);
server_redraw_window(w);
- return;
+ break;
case 'h':
case KEYC_LEFT:
- window_scroll_left_1(w);
- return;
+ window_scroll_scroll_left(w);
+ break;
case 'l':
case KEYC_RIGHT:
- window_scroll_right_1(w);
- return;
+ window_scroll_scroll_right(w);
+ break;
case 'k':
case 'K':
case KEYC_UP:
- window_scroll_up_1(w);
- return;
+ window_scroll_scroll_up(w);
+ break;
case 'j':
case 'J':
case KEYC_DOWN:
- window_scroll_down_1(w);
- return;
+ window_scroll_scroll_down(w);
+ break;
case '\025': /* C-u */
case KEYC_PPAGE:
- if (data->oy + sy > data->size)
- data->oy = data->size;
+ if (data->oy + screen_size_y(s) > w->base.hsize)
+ data->oy = w->base.hsize;
else
- data->oy += sy;
+ data->oy += screen_size_y(s);
+ window_scroll_redraw_screen(w);
break;
case '\006': /* C-f */
case KEYC_NPAGE:
- if (data->oy < sy)
+ if (data->oy < screen_size_y(s))
data->oy = 0;
else
- data->oy -= sy;
+ data->oy -= screen_size_y(s);
+ window_scroll_redraw_screen(w);
break;
}
- if (ox != data->ox || oy != data->oy)
- server_redraw_window(w);
}
void
-window_scroll_up_1(struct window *w)
+window_scroll_write_line(
+ struct window *w, struct screen_write_ctx *ctx, u_int py)
{
struct window_scroll_mode_data *data = w->modedata;
- struct screen_draw_ctx ctx;
+ struct screen *s = &data->screen;
+ size_t size;
+
+ if (py == 0) {
+ screen_write_set_attributes(ctx, 0, status_colour);
+ screen_write_move_cursor(ctx, 0, 0);
+ size = screen_write_put_string_rjust(
+ ctx, "[%u,%u/%u]", data->ox, data->oy, w->base.hsize);
+ } else
+ size = 0;
+ screen_write_move_cursor(ctx, 0, py);
+ screen_write_copy_area(
+ ctx, &w->base, screen_size_x(s) - size, 1, data->ox, data->oy);
+}
+
+void
+window_scroll_write_column(
+ struct window *w, struct screen_write_ctx *ctx, u_int px)
+{
+ struct window_scroll_mode_data *data = w->modedata;
+ struct screen *s = &data->screen;
+
+ screen_write_move_cursor(ctx, px, 0);
+ screen_write_copy_area(
+ ctx, &w->base, 1, screen_size_y(s), data->ox, data->oy);
+}
- if (data->oy >= data->size)
+void
+window_scroll_redraw_screen(struct window *w)
+{
+ struct window_scroll_mode_data *data = w->modedata;
+ struct screen *s = &data->screen;
+ struct screen_write_ctx ctx;
+ u_int i;
+
+ screen_write_start_window(&ctx, w);
+ for (i = 0; i < screen_size_y(s); i++)
+ window_scroll_write_line(w, &ctx, i);
+ screen_write_stop(&ctx);
+}
+
+void
+window_scroll_scroll_up(struct window *w)
+{
+ struct window_scroll_mode_data *data = w->modedata;
+ struct screen_write_ctx ctx;
+
+ if (data->oy >= w->base.hsize)
return;
data->oy++;
- 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);
- screen_draw_stop(&ctx);
+ screen_write_start_window(&ctx, w);
+ screen_write_move_cursor(&ctx, 0, 0);
+ screen_write_insert_lines(&ctx, 1);
+ window_scroll_write_line(w, &ctx, 0);
+ window_scroll_write_line(w, &ctx, 1);
+ screen_write_stop(&ctx);
}
void
-window_scroll_down_1(struct window *w)
+window_scroll_scroll_down(struct window *w)
{
struct window_scroll_mode_data *data = w->modedata;
- struct screen_draw_ctx ctx;
+ struct screen *s = &data->screen;
+ struct screen_write_ctx ctx;
if (data->oy == 0)
return;
data->oy--;
- 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);
+ screen_write_start_window(&ctx, w);
+ screen_write_move_cursor(&ctx, 0, 0);
+ screen_write_delete_lines(&ctx, 1);
+ window_scroll_write_line(w, &ctx, screen_last_y(s));
+ window_scroll_write_line(w, &ctx, 0);
+ screen_write_stop(&ctx);
}
void
-window_scroll_right_1(struct window *w)
+window_scroll_scroll_right(struct window *w)
{
struct window_scroll_mode_data *data = w->modedata;
- struct screen_draw_ctx ctx;
+ struct screen *s = &data->screen;
+ struct screen_write_ctx ctx;
u_int i;
if (data->ox >= SHRT_MAX)
return;
data->ox++;
- 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_write_start_window(&ctx, w);
+ for (i = 1; i < screen_size_y(s); i++) {
+ screen_write_move_cursor(&ctx, 0, i);
+ screen_write_delete_characters(&ctx, 1);
}
- screen_draw_column(&ctx, screen_last_x(&w->screen));
- window_scroll_draw_position(w, &ctx);
- screen_draw_stop(&ctx);
+ window_scroll_write_column(w, &ctx, screen_last_x(s));
+ window_scroll_write_line(w, &ctx, 0);
+ screen_write_stop(&ctx);
}
void
-window_scroll_left_1(struct window *w)
+window_scroll_scroll_left(struct window *w)
{
struct window_scroll_mode_data *data = w->modedata;
- struct screen_draw_ctx ctx;
+ struct screen *s = &data->screen;
+ struct screen_write_ctx ctx;
u_int i;
if (data->ox == 0)
return;
data->ox--;
-
- 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_write_start_window(&ctx, w);
+ for (i = 1; i < screen_size_y(s); i++) {
+ screen_write_move_cursor(&ctx, 0, i);
+ screen_write_insert_characters(&ctx, 1);
}
- screen_draw_column(&ctx, 0);
- window_scroll_draw_position(w, &ctx);
- screen_draw_stop(&ctx);
+ window_scroll_write_column(w, &ctx, 0);
+ window_scroll_write_line(w, &ctx, 0);
+ screen_write_stop(&ctx);
}
diff --git a/window.c b/window.c
index a0dfdaf3..47d4f05d 100644
--- a/window.c
+++ b/window.c
@@ -1,4 +1,4 @@
-/* $Id: window.c,v 1.32 2007-11-27 19:23:34 nicm Exp $ */
+/* $Id: window.c,v 1.33 2007-12-06 09:46:23 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -90,7 +90,7 @@ winlink_next_index(struct winlinks *wwl)
if (winlink_find_by_index(wwl, i) == NULL)
return (i);
}
-
+
fatalx("no free indexes");
}
@@ -136,7 +136,7 @@ struct winlink *
winlink_next(unused struct winlinks *wwl, struct winlink *wl)
{
return (RB_NEXT(winlinks, wwl, wl));
-}
+}
struct winlink *
winlink_previous(struct winlinks *wwl, struct winlink *wl)
@@ -153,7 +153,7 @@ winlink_previous(struct winlinks *wwl, struct winlink *wl)
if (wl == NULL)
return (NULL);
return (wk);
-}
+}
struct window *
window_create(
@@ -189,14 +189,15 @@ window_create(
if (fcntl(fd, F_SETFL, mode|O_NONBLOCK) == -1)
fatal("fcntl failed");
if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
- fatal("fcntl failed");
+ fatal("fcntl failed");
w = xmalloc(sizeof *w);
w->fd = fd;
w->in = buffer_create(BUFSIZ);
w->out = buffer_create(BUFSIZ);
w->mode = NULL;
- screen_create(&w->screen, sx, sy);
+ screen_create(&w->base, sx, sy);
+ w->screen = &w->base;
input_init(w);
if (name == NULL) {
@@ -238,12 +239,14 @@ window_destroy(struct window *w)
break;
}
ARRAY_REMOVE(&windows, i);
-
+
close(w->fd);
input_free(w);
- screen_destroy(&w->screen);
+ screen_destroy(&w->base);
+ if (w->mode != NULL)
+ w->mode->free(w);
buffer_destroy(w->in);
buffer_destroy(w->out);
@@ -257,16 +260,16 @@ window_resize(struct window *w, u_int sx, u_int sy)
{
struct winsize ws;
- if (sx == screen_size_x(&w->screen) && sy == screen_size_y(&w->screen))
+ if (sx == screen_size_x(&w->base) && sy == screen_size_y(&w->base))
return (-1);
-
+
memset(&ws, 0, sizeof ws);
ws.ws_col = sx;
ws.ws_row = sy;
+ screen_resize(&w->base, sx, sy);
if (w->mode != NULL)
w->mode->resize(w, sx, sy);
- screen_resize(&w->screen, sx, sy);
if (ioctl(w->fd, TIOCSWINSZ, &ws) == -1)
fatal("ioctl failed");
@@ -280,19 +283,10 @@ window_parse(struct window *w)
}
void
-window_draw(struct window *w, struct screen_draw_ctx *ctx, u_int py, u_int ny)
-{
- if (w->mode != NULL)
- w->mode->draw(w, ctx, py, ny);
- else
- screen_draw_lines(ctx, py, ny);
-}
-
-void
window_key(struct window *w, int key)
{
if (w->mode != NULL)
w->mode->key(w, key);
else
- input_key(w, key);
+ input_key(w, key);
}