aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicholas Marriott <nicholas.marriott@gmail.com>2009-01-11 23:31:46 +0000
committerNicholas Marriott <nicholas.marriott@gmail.com>2009-01-11 23:31:46 +0000
commit162bacdcd91caf631db6979a21c27d208a66046b (patch)
treed678a35fa4c017ec034d6d6b19140f56fd8ca65a
parentd78bc5dfc40fe8d1a3842bd91dcfa5ca4c44ae01 (diff)
downloadrtmux-162bacdcd91caf631db6979a21c27d208a66046b.tar.gz
rtmux-162bacdcd91caf631db6979a21c27d208a66046b.tar.bz2
rtmux-162bacdcd91caf631db6979a21c27d208a66046b.zip
Window splitting. Two vertical panes fixed 50% each. This is a huge diff, still a couple of bugs (notably heap corruption somewhere causing segfault on exit).
-rw-r--r--CHANGES17
-rw-r--r--GNUmakefile4
-rw-r--r--Makefile4
-rw-r--r--TODO21
-rw-r--r--cmd-clock-mode.c4
-rw-r--r--cmd-copy-mode.c4
-rw-r--r--cmd-list-windows.c43
-rw-r--r--cmd-paste-buffer.c6
-rw-r--r--cmd-respawn-window.c16
-rw-r--r--cmd-scroll-mode.c4
-rw-r--r--cmd-send-keys.c8
-rw-r--r--cmd-send-prefix.c4
-rw-r--r--cmd-split-window.c211
-rw-r--r--cmd-switch-pane.c61
-rw-r--r--cmd.c4
-rw-r--r--input-keys.c34
-rw-r--r--input.c54
-rw-r--r--key-bindings.c12
-rw-r--r--resize.c9
-rw-r--r--screen-redraw.c215
-rw-r--r--screen-write.c181
-rw-r--r--server-msg.c3
-rw-r--r--server.c247
-rw-r--r--status.c158
-rw-r--r--tmux.h151
-rw-r--r--tty-write.c77
-rw-r--r--tty.c299
-rw-r--r--window-clock.c55
-rw-r--r--window-copy.c476
-rw-r--r--window-more.c102
-rw-r--r--window-scroll.c140
-rw-r--r--window.c247
32 files changed, 1587 insertions, 1284 deletions
diff --git a/CHANGES b/CHANGES
index 4a002a8e..b1beefdf 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,20 @@
11 January 2009
+* Vertical window splitting. Currently can only split a window into two panes.
+ New split-window command splits (bound to ") and switch-pane command (bound to
+ o) switches between panes.
+
+ close-pane, swap-pane commands are to follow. Also to come are pane resizing,
+ >2 panes, the ability to break a pane out to a full window and vice versa and
+ possibly horizontal splitting.
+
+ Panes are subelements of windows rather than being windows in their own
+ right. I tried to make them windows (so the splitting was at the session or
+ client level) but this rapidly became very complex and invasive. So in the
+ interests of having something working, I just made it so each window can have
+ two child processes instead of one (and it still took me 12 hours straight
+ coding). Now the concept is proven and much of the support code is there,
+ this may change in future if more flexibility is needed.
* save-buffer command, from Tiago Cunha.
10 January 2009
@@ -859,7 +874,7 @@
(including mutt, emacs). No status bar yet and no key remapping or other
customisation.
-$Id: CHANGES,v 1.192 2009-01-11 23:14:57 nicm Exp $
+$Id: CHANGES,v 1.193 2009-01-11 23:31:46 nicm Exp $
LocalWords: showw utf UTF fulvio ciriaco joshe OSC APC gettime abc DEF OA clr
LocalWords: rivo nurges lscm Erdely eol smysession mysession ek dstname RB
diff --git a/GNUmakefile b/GNUmakefile
index 93c96151..9fe2321d 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -1,4 +1,4 @@
-# $Id: GNUmakefile,v 1.50 2009-01-11 23:14:57 nicm Exp $
+# $Id: GNUmakefile,v 1.51 2009-01-11 23:31:46 nicm Exp $
.PHONY: clean
@@ -33,7 +33,7 @@ SRCS= tmux.c server.c server-msg.c server-fn.c buffer.c buffer-poll.c status.c \
cmd-list-commands.c cmd-move-window.c cmd-select-prompt.c \
cmd-respawn-window.c cmd-source-file.c cmd-server-info.c \
cmd-clock-mode.c cmd-lock-server.c cmd-set-password.c \
- cmd-save-buffer.c \
+ cmd-save-buffer.c cmd-switch-pane.c cmd-split-window.c \
window-clock.c window-scroll.c window-more.c window-copy.c \
options.c options-cmd.c paste.c colour.c utf8.c clock.c \
tty.c tty-term.c tty-keys.c tty-write.c
diff --git a/Makefile b/Makefile
index 87b0b02c..a403378f 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.87 2009-01-11 23:14:57 nicm Exp $
+# $Id: Makefile,v 1.88 2009-01-11 23:31:46 nicm Exp $
.SUFFIXES: .c .o .y .h
.PHONY: clean update-index.html upload-index.html
@@ -37,7 +37,7 @@ SRCS= tmux.c server.c server-msg.c server-fn.c buffer.c buffer-poll.c status.c \
cmd-list-commands.c cmd-move-window.c cmd-select-prompt.c \
cmd-respawn-window.c cmd-source-file.c cmd-server-info.c \
cmd-clock-mode.c cmd-lock-server.c cmd-set-password.c \
- cmd-save-buffer.c \
+ cmd-save-buffer.c cmd-switch-pane.c cmd-split-window.c \
window-clock.c window-scroll.c window-more.c window-copy.c \
options.c options-cmd.c paste.c colour.c utf8.c clock.c \
tty.c tty-term.c tty-keys.c tty-write.c
diff --git a/TODO b/TODO
index ba766d91..e7bc7497 100644
--- a/TODO
+++ b/TODO
@@ -13,7 +13,7 @@
- status-fg/status-bg should be able to set attributes: bold, etc
- refer to windows by name etc (duplicates? fnmatch?)
- commands:
- command to run something without a window at all?
+ command to run something without a window at all - output to window-more
command to purge window history
extend list-clients to list clients attached to a session (-a for all?)
bring back detach-session to detach all clients on a session?
@@ -42,7 +42,7 @@
session not being watched?
- tidy up window modes
- problems with force-width when wrapping line in emacs?
-- next prev word etc in command prompt; also ^K; also make is support modes
+- next prev word etc in command prompt; also ^K; also make it support modes
to support vi. is there something could use for this? editline(3)/readline?
- many more info() displays for various things
- vi half page scroll
@@ -51,8 +51,8 @@
others do not. this might be hard: a flag for each grid line (top bit of size
maybe)? a single flag is insufficient as can't then tell when to /stop/
unwrapping
-- OPTIONS section in man page with description of new option handling
-- update set/setw in man page with -g and -u flags
+- document OPTIONS section in man page with description of new option handling
+- document update set/setw in man page with -g and -u flags
- more # commands in status-left,right eg #H for hostname. others?
- input.c is too complicated. simplify?
- try change from pass-though model to redraw model (use updated screen
@@ -66,7 +66,9 @@
- document clock-mode
- document password/locking commands
- document lock-after-time
+- document panes and window splitting: split-window and switch-pane
- a command to display the status line briefly when it is turned off
+- neww should support -k
- FAQ "Can I have some examples of cool things I can do with tmux?" -- linkw, more??
17:06 < NicM> tmux new then eg tmux linkw -s0:0
17:06 < simmel> NicM link-window?
@@ -87,3 +89,14 @@
17:09 < NicM> or kills it if it is only linked to one
17:09 < NicM> unlinkw only unlinks it
- clone session command
+- panes:
+ swap-panes
+ close-pane
+ move-pane (to window)
+ pane resizing
+ >2 panes per window
+- would be nice if tmux could be the shell
+- some sort of extension to command prompt so can do eg
+ bind m command-prompt 'split "man %%"'
+ bind r command-prompt 'renamew "%%"'
+ which then asks for a string, substitutes %% in command and executes it
diff --git a/cmd-clock-mode.c b/cmd-clock-mode.c
index 0e76135c..9c8e72d0 100644
--- a/cmd-clock-mode.c
+++ b/cmd-clock-mode.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-clock-mode.c,v 1.1 2009-01-10 19:35:39 nicm Exp $ */
+/* $Id: cmd-clock-mode.c,v 1.2 2009-01-11 23:31:46 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -48,7 +48,7 @@ cmd_clock_mode_exec(struct cmd *self, struct cmd_ctx *ctx)
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return;
- window_set_mode(wl->window, &window_clock_mode);
+ window_pane_set_mode(wl->window->active, &window_clock_mode);
if (ctx->cmdclient != NULL)
server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0);
diff --git a/cmd-copy-mode.c b/cmd-copy-mode.c
index 3ddd4759..f342e3fe 100644
--- a/cmd-copy-mode.c
+++ b/cmd-copy-mode.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-copy-mode.c,v 1.12 2009-01-10 18:08:55 nicm Exp $ */
+/* $Id: cmd-copy-mode.c,v 1.13 2009-01-11 23:31:46 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -48,7 +48,7 @@ cmd_copy_mode_exec(struct cmd *self, struct cmd_ctx *ctx)
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return;
- window_set_mode(wl->window, &window_copy_mode);
+ window_pane_set_mode(wl->window->active, &window_copy_mode);
if (ctx->cmdclient != NULL)
server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0);
diff --git a/cmd-list-windows.c b/cmd-list-windows.c
index efc9d47e..56434f67 100644
--- a/cmd-list-windows.c
+++ b/cmd-list-windows.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-list-windows.c,v 1.25 2008-09-26 06:45:25 nicm Exp $ */
+/* $Id: cmd-list-windows.c,v 1.26 2009-01-11 23:31:46 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -48,8 +48,9 @@ cmd_list_windows_exec(struct cmd *self, struct cmd_ctx *ctx)
struct session *s;
struct winlink *wl;
struct window *w;
+ struct window_pane *wp;
struct grid_data *gd;
- u_int i;
+ u_int i, j;
unsigned long long size;
const char *name;
@@ -58,23 +59,31 @@ cmd_list_windows_exec(struct cmd *self, struct cmd_ctx *ctx)
RB_FOREACH(wl, winlinks, &s->windows) {
w = wl->window;
- gd = w->base.grid;
- size = 0;
- for (i = 0; i < gd->hsize; i++)
- size += gd->size[i] * sizeof **gd->data;
- size += gd->hsize * (sizeof *gd->data);
- size += gd->hsize * (sizeof *gd->size);
-
- if (w->fd != -1)
- name = ttyname(w->fd);
- else
- name = "";
ctx->print(ctx,
- "%d: %s \"%s\" (%s) [%ux%u] [history %u/%u, %llu bytes]",
- wl->idx, w->name, w->base.title, name,
- screen_size_x(&w->base), screen_size_y(&w->base),
- gd->hsize, gd->hlimit, size);
+ "%d: %s [%ux%u]", wl->idx, w->name, w->sx, w->sy);
+ for (i = 0; i < 2; i++) {
+ wp = w->panes[i];
+ if (wp == NULL)
+ continue;
+ gd = wp->base.grid;
+
+ size = 0;
+ for (j = 0; j < gd->hsize; j++)
+ size += gd->size[j] * sizeof **gd->data;
+ size += gd->hsize * (sizeof *gd->data);
+ size += gd->hsize * (sizeof *gd->size);
+
+ if (wp->fd != -1)
+ name = ttyname(wp->fd);
+ else
+ name = "";
+
+ ctx->print(ctx, " pane %d:"
+ " %s [%ux%u] [history %u/%u, %llu bytes]", i, name,
+ screen_size_x(&wp->base), screen_size_y(&wp->base),
+ gd->hsize, gd->hlimit, size);
+ }
}
if (ctx->cmdclient != NULL)
diff --git a/cmd-paste-buffer.c b/cmd-paste-buffer.c
index 93ad57b5..5077b392 100644
--- a/cmd-paste-buffer.c
+++ b/cmd-paste-buffer.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-paste-buffer.c,v 1.13 2009-01-11 00:48:42 nicm Exp $ */
+/* $Id: cmd-paste-buffer.c,v 1.14 2009-01-11 23:31:46 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -46,11 +46,13 @@ cmd_paste_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_buffer_data *data = self->data;
struct winlink *wl;
+ struct window *w;
struct session *s;
struct paste_buffer *pb;
if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL)
return;
+ w = wl->window;
if (data->buffer == -1)
pb = paste_get_top(&s->buffers);
@@ -60,7 +62,7 @@ cmd_paste_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
}
if (pb != NULL)
- buffer_write(wl->window->out, pb->data, strlen(pb->data));
+ buffer_write(w->active->out, pb->data, strlen(pb->data));
/* Delete the buffer if -d. */
if (data->flags & CMD_DFLAG) {
diff --git a/cmd-respawn-window.c b/cmd-respawn-window.c
index 20002c3e..4590206c 100644
--- a/cmd-respawn-window.c
+++ b/cmd-respawn-window.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-respawn-window.c,v 1.6 2009-01-10 19:37:35 nicm Exp $ */
+/* $Id: cmd-respawn-window.c,v 1.7 2009-01-11 23:31:46 nicm Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -46,6 +46,7 @@ cmd_respawn_window_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct winlink *wl;
+ struct window *w;
struct session *s;
const char *env[] = {
NULL /* TMUX= */, "TERM=screen", NULL
@@ -55,8 +56,10 @@ cmd_respawn_window_exec(struct cmd *self, struct cmd_ctx *ctx)
if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL)
return;
+ w = wl->window;
- if (wl->window->fd != -1 && !(data->flags & CMD_KFLAG)) {
+ if ((w->panes[0]->fd != -1 || (w->panes[1] != NULL &&
+ w->panes[1]->fd != -1)) && !(data->flags & CMD_KFLAG)) {
ctx->error(ctx, "window still active: %s:%d", s->name, wl->idx);
return;
}
@@ -66,14 +69,17 @@ cmd_respawn_window_exec(struct cmd *self, struct cmd_ctx *ctx)
xsnprintf(buf, sizeof buf, "TMUX=%ld,%u", (long) getpid(), i);
env[0] = buf;
- if (window_spawn(wl->window, data->arg, wl->window->cwd, env) != 0) {
+ if (w->panes[1] != NULL)
+ window_remove_pane(w, 1);
+
+ if (window_pane_spawn(w->panes[0], data->arg, NULL, env) != 0) {
ctx->error(ctx, "respawn failed: %s:%d", s->name, wl->idx);
return;
}
- screen_reinit(&wl->window->base);
+ screen_reinit(&w->panes[0]->base);
recalculate_sizes();
- server_redraw_window(wl->window);
+ server_redraw_window(w);
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 b7e3c1aa..f1f448bd 100644
--- a/cmd-scroll-mode.c
+++ b/cmd-scroll-mode.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-scroll-mode.c,v 1.13 2009-01-10 18:08:55 nicm Exp $ */
+/* $Id: cmd-scroll-mode.c,v 1.14 2009-01-11 23:31:46 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -48,7 +48,7 @@ cmd_scroll_mode_exec(struct cmd *self, struct cmd_ctx *ctx)
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return;
- window_set_mode(wl->window, &window_scroll_mode);
+ window_pane_set_mode(wl->window->active, &window_scroll_mode);
if (ctx->cmdclient != NULL)
server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0);
diff --git a/cmd-send-keys.c b/cmd-send-keys.c
index ac03a5ec..afded43c 100644
--- a/cmd-send-keys.c
+++ b/cmd-send-keys.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-send-keys.c,v 1.15 2008-12-10 20:25:41 nicm Exp $ */
+/* $Id: cmd-send-keys.c,v 1.16 2009-01-11 23:31:46 nicm Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -119,8 +119,10 @@ cmd_send_keys_exec(struct cmd *self, struct cmd_ctx *ctx)
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return;
- for (i = 0; i < data->nkeys; i++)
- window_key(wl->window, ctx->curclient, data->keys[i]);
+ for (i = 0; i < data->nkeys; i++) {
+ window_pane_key(
+ wl->window->active, ctx->curclient, data->keys[i]);
+ }
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 78cd4afa..2d17bea1 100644
--- a/cmd-send-prefix.c
+++ b/cmd-send-prefix.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-send-prefix.c,v 1.19 2008-09-26 06:45:25 nicm Exp $ */
+/* $Id: cmd-send-prefix.c,v 1.20 2009-01-11 23:31:46 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -51,7 +51,7 @@ cmd_send_prefix_exec(struct cmd *self, struct cmd_ctx *ctx)
return;
key = options_get_number(&s->options, "prefix");
- window_key(wl->window, ctx->curclient, key);
+ window_pane_key(wl->window->active, ctx->curclient, key);
if (ctx->cmdclient != NULL)
server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0);
diff --git a/cmd-split-window.c b/cmd-split-window.c
new file mode 100644
index 00000000..5e9c0693
--- /dev/null
+++ b/cmd-split-window.c
@@ -0,0 +1,211 @@
+/* $Id: cmd-split-window.c,v 1.1 2009-01-11 23:31:46 nicm Exp $ */
+
+/*
+ * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "tmux.h"
+
+/*
+ * Create a new window.
+ */
+
+int cmd_split_window_parse(struct cmd *, int, char **, char **);
+void cmd_split_window_exec(struct cmd *, struct cmd_ctx *);
+void cmd_split_window_send(struct cmd *, struct buffer *);
+void cmd_split_window_recv(struct cmd *, struct buffer *);
+void cmd_split_window_free(struct cmd *);
+void cmd_split_window_init(struct cmd *, int);
+void cmd_split_window_print(struct cmd *, char *, size_t);
+
+struct cmd_split_window_data {
+ char *target;
+ char *cmd;
+ int flag_detached;
+};
+
+const struct cmd_entry cmd_split_window_entry = {
+ "split-window", "splitw",
+ "[-d] [-t target-window] [command]",
+ 0,
+ cmd_split_window_init,
+ cmd_split_window_parse,
+ cmd_split_window_exec,
+ cmd_split_window_send,
+ cmd_split_window_recv,
+ cmd_split_window_free,
+ cmd_split_window_print
+};
+
+void
+cmd_split_window_init(struct cmd *self, unused int arg)
+{
+ struct cmd_split_window_data *data;
+
+ self->data = data = xmalloc(sizeof *data);
+ data->target = NULL;
+ data->cmd = NULL;
+ data->flag_detached = 0;
+}
+
+int
+cmd_split_window_parse(struct cmd *self, int argc, char **argv, char **cause)
+{
+ struct cmd_split_window_data *data;
+ int opt;
+
+ self->entry->init(self, 0);
+ data = self->data;
+
+ while ((opt = getopt(argc, argv, "dt:")) != -1) {
+ switch (opt) {
+ case 'd':
+ data->flag_detached = 1;
+ break;
+ case 't':
+ if (data->target == NULL)
+ data->target = xstrdup(optarg);
+ break;
+ default:
+ goto usage;
+ }
+ }
+ argc -= optind;
+ argv += optind;
+ if (argc != 0 && argc != 1)
+ goto usage;
+
+ if (argc == 1)
+ data->cmd = xstrdup(argv[0]);
+
+ return (0);
+
+usage:
+ xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
+
+ self->entry->free(self);
+ return (-1);
+}
+
+void
+cmd_split_window_exec(struct cmd *self, struct cmd_ctx *ctx)
+{
+ struct cmd_split_window_data *data = self->data;
+ struct session *s;
+ struct winlink *wl;
+ const char *env[] = {
+ NULL /* TMUX= */, "TERM=screen", NULL
+ };
+ char buf[256];
+ char *cmd, *cwd;
+ u_int i, sx, sy, hlimit;
+
+ if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL)
+ return;
+
+ if (wl->window->panes[1] != NULL) {
+ ctx->error(ctx, "window is already split");
+ return;
+ }
+
+ if (session_index(s, &i) != 0)
+ fatalx("session not found");
+ xsnprintf(buf, sizeof buf, "TMUX=%ld,%u", (long) getpid(), i);
+ env[0] = buf;
+
+ cmd = data->cmd;
+ if (cmd == NULL)
+ cmd = options_get_string(&s->options, "default-command");
+ if (ctx->cmdclient == NULL || ctx->cmdclient->cwd == NULL)
+ cwd = options_get_string(&global_options, "default-path");
+ else
+ cwd = ctx->cmdclient->cwd;
+
+ hlimit = options_get_number(&s->options, "history-limit");
+ sx = wl->window->sx;
+ sy = wl->window->sy - (wl->window->sy / 2);
+ wl->window->panes[1] = window_pane_create(wl->window, sx, sy, hlimit);
+ if (window_pane_spawn(wl->window->panes[1], cmd, cwd, env) != 0) {
+ ctx->error(ctx, "command failed: %s", cmd);
+ return;
+ }
+ window_resize(wl->window, wl->window->sx, wl->window->sy);
+ server_redraw_window(wl->window);
+
+ if (!data->flag_detached) {
+ wl->window->active = wl->window->panes[1];
+ session_select(s, wl->idx);
+ server_redraw_session(s);
+ } else
+ server_status_window(s);
+
+ if (ctx->cmdclient != NULL)
+ server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0);
+}
+
+void
+cmd_split_window_send(struct cmd *self, struct buffer *b)
+{
+ struct cmd_split_window_data *data = self->data;
+
+ buffer_write(b, data, sizeof *data);
+ cmd_send_string(b, data->target);
+ cmd_send_string(b, data->cmd);
+}
+
+void
+cmd_split_window_recv(struct cmd *self, struct buffer *b)
+{
+ struct cmd_split_window_data *data;
+
+ self->data = data = xmalloc(sizeof *data);
+ buffer_read(b, data, sizeof *data);
+ data->target = cmd_recv_string(b);
+ data->cmd = cmd_recv_string(b);
+}
+
+void
+cmd_split_window_free(struct cmd *self)
+{
+ struct cmd_split_window_data *data = self->data;
+
+ if (data->target != NULL)
+ xfree(data->target);
+ if (data->cmd != NULL)
+ xfree(data->cmd);
+ xfree(data);
+}
+
+void
+cmd_split_window_print(struct cmd *self, char *buf, size_t len)
+{
+ struct cmd_split_window_data *data = self->data;
+ size_t off = 0;
+
+ off += xsnprintf(buf, len, "%s", self->entry->name);
+ if (data == NULL)
+ return;
+ if (off < len && data->flag_detached)
+ off += xsnprintf(buf + off, len - off, " -d");
+ if (off < len && data->target != NULL)
+ off += xsnprintf(buf + off, len - off, " -t %s", data->target);
+ if (off < len && data->cmd != NULL)
+ off += xsnprintf(buf + off, len - off, " %s", data->cmd);
+}
diff --git a/cmd-switch-pane.c b/cmd-switch-pane.c
new file mode 100644
index 00000000..a84f01fa
--- /dev/null
+++ b/cmd-switch-pane.c
@@ -0,0 +1,61 @@
+/* $Id: cmd-switch-pane.c,v 1.1 2009-01-11 23:31:46 nicm Exp $ */
+
+/*
+ * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+
+#include "tmux.h"
+
+/*
+ * Enter clock mode.
+ */
+
+void cmd_switch_pane_exec(struct cmd *, struct cmd_ctx *);
+
+const struct cmd_entry cmd_switch_pane_entry = {
+ "switch-pane", "switchp",
+ CMD_TARGET_WINDOW_USAGE,
+ 0,
+ cmd_target_init,
+ cmd_target_parse,
+ cmd_switch_pane_exec,
+ cmd_target_send,
+ cmd_target_recv,
+ cmd_target_free,
+ cmd_target_print
+};
+
+void
+cmd_switch_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
+{
+ struct cmd_target_data *data = self->data;
+ struct winlink *wl;
+
+ if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
+ return;
+
+ if (wl->window->panes[1] != NULL) {
+ if (wl->window->active == wl->window->panes[0])
+ wl->window->active = wl->window->panes[1];
+ else
+ wl->window->active = wl->window->panes[0];
+ server_redraw_window(wl->window);
+ }
+
+ if (ctx->cmdclient != NULL)
+ server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0);
+}
diff --git a/cmd.c b/cmd.c
index 5b1ce895..d1d5ffe1 100644
--- a/cmd.c
+++ b/cmd.c
@@ -1,4 +1,4 @@
-/* $Id: cmd.c,v 1.73 2009-01-11 23:14:57 nicm Exp $ */
+/* $Id: cmd.c,v 1.74 2009-01-11 23:31:46 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -71,9 +71,11 @@ const struct cmd_entry *cmd_table[] = {
&cmd_show_options_entry,
&cmd_show_window_options_entry,
&cmd_source_file_entry,
+ &cmd_split_window_entry,
&cmd_start_server_entry,
&cmd_swap_window_entry,
&cmd_switch_client_entry,
+ &cmd_switch_pane_entry,
&cmd_unbind_key_entry,
&cmd_unlink_window_entry,
NULL
diff --git a/input-keys.c b/input-keys.c
index 98d0e001..efddf217 100644
--- a/input-keys.c
+++ b/input-keys.c
@@ -1,4 +1,4 @@
-/* $Id: input-keys.c,v 1.20 2009-01-10 18:28:09 nicm Exp $ */
+/* $Id: input-keys.c,v 1.21 2009-01-11 23:31:46 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -104,7 +104,7 @@ struct input_key_ent input_keys[] = {
/* Translate a key code from client into an output key sequence. */
void
-input_key(struct window *w, int key)
+input_key(struct window_pane *wp, int key)
{
struct input_key_ent *ike;
u_int i;
@@ -115,8 +115,8 @@ input_key(struct window *w, int key)
if (key != KEYC_NONE && KEYC_REMOVEESC(key) < KEYC_OFFSET) {
if (KEYC_ISESC(key))
- buffer_write8(w->out, '\033');
- buffer_write8(w->out, (uint8_t) KEYC_REMOVEESC(key));
+ buffer_write8(wp->out, '\033');
+ buffer_write8(wp->out, (uint8_t) KEYC_REMOVEESC(key));
return;
}
@@ -124,10 +124,10 @@ input_key(struct window *w, int key)
ike = &input_keys[i];
if ((ike->flags & INPUTKEY_KEYPAD) &&
- !(w->screen->mode & MODE_KKEYPAD))
+ !(wp->screen->mode & MODE_KKEYPAD))
continue;
if ((ike->flags & INPUTKEY_CURSOR) &&
- !(w->screen->mode & MODE_KCURSOR))
+ !(wp->screen->mode & MODE_KCURSOR))
continue;
if (ike->flags & INPUTKEY_MODIFIER) {
@@ -150,7 +150,7 @@ input_key(struct window *w, int key)
log_debug2("found key 0x%x: \"%s\"", key, ike->data);
if (ike->flags & INPUTKEY_XTERM &&
- options_get_number(&w->options, "xterm-keys")) {
+ options_get_number(&wp->window->options, "xterm-keys")) {
/* In xterm keys mode, append modifier argument. */
ch = '\0';
if (KEYC_ISSFT(key) && KEYC_ISESC(key) && KEYC_ISCTL(key))
@@ -169,12 +169,12 @@ input_key(struct window *w, int key)
ch = '2';
if (ch != '\0') {
log_debug("output argument is: %c", ch);
- buffer_write(w->out, ike->data, dlen - 1);
- buffer_write8(w->out, ';');
- buffer_write8(w->out, ch);
- buffer_write8(w->out, ike->data[dlen - 1]);
+ buffer_write(wp->out, ike->data, dlen - 1);
+ buffer_write8(wp->out, ';');
+ buffer_write8(wp->out, ch);
+ buffer_write8(wp->out, ike->data[dlen - 1]);
} else
- buffer_write(w->out, ike->data, dlen);
+ buffer_write(wp->out, ike->data, dlen);
return;
}
if (ike->flags & INPUTKEY_MODIFIER) {
@@ -183,15 +183,15 @@ input_key(struct window *w, int key)
* control (shift not supported).
*/
if (KEYC_ISESC(key))
- buffer_write8(w->out, '\033');
+ buffer_write8(wp->out, '\033');
if (!KEYC_ISCTL(key)) {
- buffer_write(w->out, ike->data, dlen);
+ buffer_write(wp->out, ike->data, dlen);
return;
}
- buffer_write(w->out, ike->data, dlen - 1);
- buffer_write8(w->out, ike->data[dlen - 1] ^ 0x20);
+ buffer_write(wp->out, ike->data, dlen - 1);
+ buffer_write8(wp->out, ike->data[dlen - 1] ^ 0x20);
return;
}
- buffer_write(w->out, ike->data, dlen);
+ buffer_write(wp->out, ike->data, dlen);
}
diff --git a/input.c b/input.c
index 880462af..c073b6e2 100644
--- a/input.c
+++ b/input.c
@@ -1,4 +1,4 @@
-/* $Id: input.c,v 1.72 2009-01-10 01:51:22 nicm Exp $ */
+/* $Id: input.c,v 1.73 2009-01-11 23:31:46 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -217,9 +217,9 @@ input_state(struct input_ctx *ictx, void *state)
}
void
-input_init(struct window *w)
+input_init(struct window_pane *wp)
{
- struct input_ctx *ictx = &w->ictx;
+ struct input_ctx *ictx = &wp->ictx;
ARRAY_INIT(&ictx->args);
@@ -236,38 +236,38 @@ input_init(struct window *w)
}
void
-input_free(struct window *w)
+input_free(struct window_pane *wp)
{
- if (w->ictx.string_buf != NULL)
- xfree(w->ictx.string_buf);
+ if (wp->ictx.string_buf != NULL)
+ xfree(wp->ictx.string_buf);
- ARRAY_FREE(&w->ictx.args);
+ ARRAY_FREE(&wp->ictx.args);
}
void
-input_parse(struct window *w)
+input_parse(struct window_pane *wp)
{
- struct input_ctx *ictx = &w->ictx;
+ struct input_ctx *ictx = &wp->ictx;
u_char ch;
- if (BUFFER_USED(w->in) == 0)
+ if (BUFFER_USED(wp->in) == 0)
return;
- ictx->buf = BUFFER_OUT(w->in);
- ictx->len = BUFFER_USED(w->in);
+ ictx->buf = BUFFER_OUT(wp->in);
+ ictx->len = BUFFER_USED(wp->in);
ictx->off = 0;
- ictx->w = w;
+ ictx->wp = wp;
log_debug2("entry; buffer=%zu", ictx->len);
- if (w->mode == NULL)
- screen_write_start(&ictx->ctx, &w->base, tty_write_window, w);
+ if (wp->mode == NULL)
+ screen_write_start(&ictx->ctx, wp, &wp->base);
else
- screen_write_start(&ictx->ctx, &w->base, NULL, NULL);
+ screen_write_start(&ictx->ctx, NULL, &wp->base);
if (ictx->off != ictx->len)
- w->flags |= WINDOW_ACTIVITY;
+ wp->window->flags |= WINDOW_ACTIVITY;
while (ictx->off < ictx->len) {
ch = ictx->buf[ictx->off++];
ictx->state(ch, ictx);
@@ -275,7 +275,7 @@ input_parse(struct window *w)
screen_write_stop(&ictx->ctx);
- buffer_remove(w->in, ictx->len);
+ buffer_remove(wp->in, ictx->len);
}
void
@@ -499,7 +499,7 @@ input_state_string_escape(u_char ch, struct input_ctx *ictx)
return;
}
screen_set_title(ictx->ctx.s, s + 2);
- server_status_window(ictx->w);
+ server_status_window(ictx->wp->window);
xfree(s);
break;
case STRING_APPLICATION:
@@ -507,15 +507,15 @@ input_state_string_escape(u_char ch, struct input_ctx *ictx)
return;
s = input_get_string(ictx);
screen_set_title(ictx->ctx.s, s);
- server_status_window(ictx->w);
+ server_status_window(ictx->wp->window);
xfree(s);
break;
case STRING_NAME:
if (ch != '\\')
return;
- xfree(ictx->w->name);
- ictx->w->name = input_get_string(ictx);
- server_status_window(ictx->w);
+ xfree(ictx->wp->window->name);
+ ictx->wp->window->name = input_get_string(ictx);
+ server_status_window(ictx->wp->window);
break;
}
return;
@@ -548,7 +548,9 @@ input_state_utf8(u_char ch, struct input_ctx *ictx)
void
input_handle_character(u_char ch, struct input_ctx *ictx)
{
- if (ch > 0x7f && options_get_number(&ictx->w->options, "utf8")) {
+ struct window_pane *wp = ictx->wp;
+
+ if (ch > 0x7f && options_get_number(&wp->window->options, "utf8")) {
/*
* UTF-8 sequence.
*
@@ -602,7 +604,7 @@ input_handle_c0_control(u_char ch, struct input_ctx *ictx)
screen_write_carriagereturn(&ictx->ctx);
break;
case '\007': /* BELL */
- ictx->w->flags |= WINDOW_BELL;
+ ictx->wp->window->flags |= WINDOW_BELL;
break;
case '\010': /* BS */
screen_write_cursorleft(&ictx->ctx, 1);
@@ -1128,7 +1130,7 @@ input_handle_sequence_dsr(struct input_ctx *ictx)
xsnprintf(reply, sizeof reply,
"\033[%u;%uR", s->cy + 1, s->cx + 1);
log_debug("cursor request, reply: %s", reply);
- buffer_write(ictx->w->out, reply, strlen(reply));
+ buffer_write(ictx->wp->out, reply, strlen(reply));
break;
}
}
diff --git a/key-bindings.c b/key-bindings.c
index f7b8e75e..b4084526 100644
--- a/key-bindings.c
+++ b/key-bindings.c
@@ -1,4 +1,4 @@
-/* $Id: key-bindings.c,v 1.42 2009-01-10 19:35:39 nicm Exp $ */
+/* $Id: key-bindings.c,v 1.43 2009-01-11 23:31:46 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -77,6 +77,7 @@ key_bindings_init(void)
int key;
const struct cmd_entry *entry;
} table[] = {
+ { '"', &cmd_split_window_entry },
{ '#', &cmd_list_buffers_entry },
{ '&', &cmd_kill_window_entry },
{ '-', &cmd_delete_buffer_entry },
@@ -94,17 +95,18 @@ key_bindings_init(void)
{ '=', &cmd_scroll_mode_entry },
{ '?', &cmd_list_keys_entry },
{ '[', &cmd_copy_mode_entry },
+ { '\'', &cmd_select_prompt_entry },
{ ']', &cmd_paste_buffer_entry },
{ 'c', &cmd_new_window_entry },
{ 'd', &cmd_detach_client_entry },
{ 'l', &cmd_last_window_entry },
{ 'n', &cmd_next_window_entry },
+ { 'o', &cmd_switch_pane_entry },
{ 'p', &cmd_previous_window_entry },
{ 'r', &cmd_refresh_client_entry },
{ 's', &cmd_list_sessions_entry },
{ 't', &cmd_clock_mode_entry },
{ 'w', &cmd_list_windows_entry },
- { '\'', &cmd_select_prompt_entry },
{ META, &cmd_send_prefix_entry },
};
u_int i;
@@ -152,13 +154,13 @@ key_bindings_error(struct cmd_ctx *ctx, const char *fmt, ...)
void printflike2
key_bindings_print(struct cmd_ctx *ctx, const char *fmt, ...)
{
- struct window *w = ctx->cursession->curw->window;
+ struct winlink *wl = ctx->cursession->curw;
va_list ap;
- window_set_mode(w, &window_more_mode);
+ window_pane_set_mode(wl->window->active, &window_more_mode);
va_start(ap, fmt);
- window_more_vadd(w, fmt, ap);
+ window_more_vadd(wl->window->active, fmt, ap);
va_end(ap);
}
diff --git a/resize.c b/resize.c
index 4068e471..2c2ee5fc 100644
--- a/resize.c
+++ b/resize.c
@@ -1,4 +1,4 @@
-/* $Id: resize.c,v 1.17 2008-12-08 16:19:51 nicm Exp $ */
+/* $Id: resize.c,v 1.18 2009-01-11 23:31:46 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -125,12 +125,11 @@ recalculate_sizes(void)
if (limit != 0 && ssy > limit)
ssy = limit;
- if (screen_size_x(&w->base) == ssx &&
- screen_size_y(&w->base) == ssy)
+ if (w->sx == ssx && w->sy == ssy)
continue;
- log_debug("window size %u,%u (was %u,%u)", ssx, ssy,
- screen_size_x(&w->base), screen_size_y(&w->base));
+ log_debug(
+ "window size %u,%u (was %u,%u)", ssx, ssy, w->sx, w->sy);
window_resize(w, ssx, ssy);
server_redraw_window(w);
diff --git a/screen-redraw.c b/screen-redraw.c
index 7b3a8ec0..df57c7da 100644
--- a/screen-redraw.c
+++ b/screen-redraw.c
@@ -1,4 +1,4 @@
-/* $Id: screen-redraw.c,v 1.15 2009-01-09 23:57:42 nicm Exp $ */
+/* $Id: screen-redraw.c,v 1.16 2009-01-11 23:31:46 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -22,146 +22,143 @@
#include "tmux.h"
-/* Initialise redrawing with a window. */
-void
-screen_redraw_start_window(struct screen_redraw_ctx *ctx, struct window *w)
-{
- struct screen *t = w->screen;
+void screen_redraw_blankx(struct client *, u_int, u_int);
+void screen_redraw_blanky(struct client *, u_int, u_int);
+void screen_redraw_line(struct client *, struct screen *, u_int, u_int);
- screen_redraw_start(ctx, t, tty_write_window, w);
-}
-
-/* Initialise redrawing with a client. */
+/* Redraw entire screen.. */
void
-screen_redraw_start_client(struct screen_redraw_ctx *ctx, struct client *c)
+screen_redraw_screen(struct client *c, struct screen *s)
{
- struct screen *t = c->session->curw->window->screen;
+ struct winlink *wl = c->session->curw;
+ u_int i, cx, cy, sy;
+ int status;
- screen_redraw_start(ctx, t, tty_write_client, c);
-}
+ status = options_get_number(&c->session->options, "status");
-/* 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 *, enum tty_cmd, ...), void *data)
-{
- ctx->write = write;
- ctx->data = data;
-
- ctx->s = s;
+ /* Override the normal screen if one is given. */
+ if (s != NULL) {
+ for (i = 0; i < screen_size_y(s); i++)
+ screen_redraw_line(c, s, 0, i);
+ return;
+ }
- /*
- * 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. XXX.
+ /*
+ * A normal client screen is made up of three parts: a top window, a
+ * bottom window and a status line. The bottom window may be turned
+ * off; the status line is always drawn.
*/
- ctx->saved_cx = s->cx;
- ctx->saved_cy = s->cy;
- ctx->write(ctx->data, TTY_SCROLLREGION, 0, screen_size_y(s) - 1);
- ctx->write(ctx->data, TTY_CURSORMOVE, s->cx, s->cy);
- ctx->write(ctx->data, TTY_CURSORMODE, 0);
- ctx->write(ctx->data, TTY_MOUSEMODE, 0);
-}
+ /* Draw the top window. */
+ s = wl->window->panes[0]->screen;
+ sy = screen_size_y(s);
+ if (screen_size_y(s) == c->sy && wl->window->panes[1] == NULL)
+ sy--;
+ cx = s->cx;
+ cy = s->cy;
+ for (i = 0; i < sy; i++)
+ screen_redraw_line(c, s, 0, i);
+ s->cx = cx;
+ s->cy = cy;
+
+ /* Draw the bottom window. */
+ if (wl->window->panes[1] != NULL) {
+ s = wl->window->panes[1]->screen;
+ sy = screen_size_y(s);
+ if (!status && screen_size_y(s) == c->sy - (c->sy / 2) - 1)
+ sy--;
+ cx = s->cx;
+ cy = s->cy;
+ for (i = 0; i < sy; i++)
+ screen_redraw_line(c, s, wl->window->sy / 2, i);
+ s->cx = cx;
+ s->cy = cy;
+ }
-/* Finish redrawing. */
-void
-screen_redraw_stop(struct screen_redraw_ctx *ctx)
-{
- struct screen *s = ctx->s;
+ /* Fill in empty space. */
+ if (wl->window->sx < c->sx) {
+ screen_redraw_blankx(
+ c, wl->window->sx, c->sx - wl->window->sx);
+ }
+ if (wl->window->sy < c->sy - status) {
+ screen_redraw_blanky(
+ c, wl->window->sy, c->sy - wl->window->sy);
+ }
- s->cx = ctx->saved_cx;
- s->cy = ctx->saved_cy;
+ /* Draw separator line. */
+ s = wl->window->panes[0]->screen;
+ if (screen_size_y(s) != wl->window->sy)
+ screen_redraw_blanky(c, screen_size_y(s), 1);
- ctx->write(ctx->data, TTY_SCROLLREGION, s->rupper, s->rlower);
- ctx->write(ctx->data, TTY_CURSORMOVE, s->cx, s->cy);
- if (s->mode & MODE_CURSOR)
- ctx->write(ctx->data, TTY_CURSORMODE, 1);
- if (s->mode & MODE_MOUSE)
- ctx->write(ctx->data, TTY_MOUSEMODE, 1);
+ /* Draw the status line. */
+ screen_redraw_status(c);
}
-/* Write character. */
+/* Draw the status line. */
void
-screen_redraw_putc(
- struct screen_redraw_ctx *ctx, struct grid_cell *gc, u_char ch)
+screen_redraw_status(struct client *c)
{
- gc->data = ch;
- ctx->write(ctx->data, TTY_CELL, gc);
- ctx->s->cx++;
-}
-
-/* Write string. */
-void printflike3
-screen_redraw_puts(
- struct screen_redraw_ctx *ctx, struct grid_cell *gc, const char *fmt, ...)
-{
- va_list ap;
- char *msg, *ptr;
-
- va_start(ap, fmt);
- xvasprintf(&msg, fmt, ap);
- va_end(ap);
-
- for (ptr = msg; *ptr != '\0'; ptr++)
- screen_redraw_putc(ctx, gc, (u_char) *ptr);
-
- xfree(msg);
+ screen_redraw_line(c, &c->status, c->sy - 1, 0);
}
-/* Redraw single cell. */
+/* Draw blank columns. */
void
-screen_redraw_cell(struct screen_redraw_ctx *ctx, u_int px, u_int py)
+screen_redraw_blankx(struct client *c, u_int ox, u_int nx)
{
- const struct grid_cell *gc;
- struct grid_cell tc;
+ u_int i, j;
- 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->cx, ctx->s->cy);
+ tty_putcode(&c->tty, TTYC_SGR0);
+ for (j = 0; j < c->sy; j++) {
+ tty_putcode2(&c->tty, TTYC_CUP, j, ox);
+ for (i = 0; i < nx; i++)
+ tty_putc(&c->tty, ' ');
}
- gc = grid_view_peek_cell(ctx->s->grid, px, py);
- if (screen_check_selection(ctx->s, px, py)) {
- memcpy(&tc, &ctx->s->sel.cell, sizeof tc);
- tc.data = gc->data;
- ctx->write(ctx->data, TTY_CELL, &tc);
- } else
- ctx->write(ctx->data, TTY_CELL, gc);
- ctx->s->cx++;
+ c->tty.cx = UINT_MAX;
+ c->tty.cy = UINT_MAX;
+ memcpy(&c->tty.cell, &grid_default_cell, sizeof c->tty.cell);
}
-/* Draw set of lines. */
+/* Draw blank lines. */
void
-screen_redraw_lines(struct screen_redraw_ctx *ctx, u_int py, u_int ny)
+screen_redraw_blanky(struct client *c, u_int oy, u_int ny)
{
u_int i, j;
- for (j = py; j < py + ny; j++) {
- for (i = 0; i < screen_size_x(ctx->s); i++)
- screen_redraw_cell(ctx, i, j);
+ tty_putcode(&c->tty, TTYC_SGR0);
+ for (j = 0; j < ny; j++) {
+ tty_putcode2(&c->tty, TTYC_CUP, oy + j, 0);
+ for (i = 0; i < c->sx; i++) {
+ if (j == 0)
+ tty_putc(&c->tty, '-');
+ else
+ tty_putc(&c->tty, ' ');
+ }
}
+
+ c->tty.cx = UINT_MAX;
+ c->tty.cy = UINT_MAX;
+ memcpy(&c->tty.cell, &grid_default_cell, sizeof c->tty.cell);
}
-/* Draw set of columns. */
+/* Draw a line. */
void
-screen_redraw_columns(struct screen_redraw_ctx *ctx, u_int px, u_int nx)
+screen_redraw_line(struct client *c, struct screen *s, u_int oy, u_int py)
{
- u_int i, j;
-
- for (j = 0; j < screen_size_y(ctx->s); j++) {
- for (i = px; i < px + nx; i++)
- screen_redraw_cell(ctx, i, j);
+ const struct grid_cell *gc;
+ struct grid_cell tc;
+ u_int i;
+
+ for (i = 0; i < screen_size_x(s); i++) {
+ s->cx = i;
+ s->cy = py;
+
+ gc = grid_view_peek_cell(s->grid, i, py);
+ if (screen_check_selection(s, i, py)) {
+ memcpy(&tc, &s->sel.cell, sizeof tc);
+ tc.data = gc->data;
+ tty_write(&c->tty, s, oy, TTY_CELL, &tc);
+ } else
+ tty_write(&c->tty, s, oy, TTY_CELL, gc);
}
}
diff --git a/screen-write.c b/screen-write.c
index 2b3a7c17..e6d9cb88 100644
--- a/screen-write.c
+++ b/screen-write.c
@@ -1,4 +1,4 @@
-/* $Id: screen-write.c,v 1.23 2009-01-10 01:51:22 nicm Exp $ */
+/* $Id: screen-write.c,v 1.24 2009-01-11 23:31:46 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -24,53 +24,28 @@
/* Initialise writing with a window. */
void
-screen_write_start_window(struct screen_write_ctx *ctx, struct window *w)
+screen_write_start(
+ struct screen_write_ctx *ctx, struct window_pane *wp, struct screen *s)
{
- 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 *, enum tty_cmd, ...), void *data)
-{
- ctx->write = write;
- ctx->data = data;
-
ctx->s = s;
-
+ if (wp != NULL) {
+ ctx->write = tty_write_window;
+ ctx->data = wp;
+ if (ctx->s == NULL)
+ ctx->s = wp->screen;
+ } else {
+ ctx->write = NULL;
+ ctx->data = NULL;
+ }
+
if (ctx->write != NULL)
ctx->write(ctx->data, TTY_CURSORMODE, 0);
}
/* Finish writing. */
void
-screen_write_stop(struct screen_write_ctx *ctx)
+screen_write_stop(unused struct screen_write_ctx *ctx)
{
- struct screen *s = ctx->s;
-
- if (ctx->write != NULL && s->mode & MODE_CURSOR)
- ctx->write(ctx->data, TTY_CURSORMODE, 1);
}
/* Write character. */
@@ -140,9 +115,6 @@ screen_write_cursorup(struct screen_write_ctx *ctx, u_int ny)
return;
s->cy -= ny;
-
- if (ctx->write != NULL)
- ctx->write(ctx->data, TTY_CURSORUP, ny);
}
/* Cursor down by ny. */
@@ -160,9 +132,6 @@ screen_write_cursordown(struct screen_write_ctx *ctx, u_int ny)
return;
s->cy += ny;
-
- if (ctx->write != NULL)
- ctx->write(ctx->data, TTY_CURSORDOWN, ny);
}
/* Cursor right by nx. */
@@ -180,9 +149,6 @@ screen_write_cursorright(struct screen_write_ctx *ctx, u_int nx)
return;
s->cx += nx;
-
- if (ctx->write != NULL)
- ctx->write(ctx->data, TTY_CURSORRIGHT, nx);
}
/* Cursor left by nx. */
@@ -200,9 +166,6 @@ screen_write_cursorleft(struct screen_write_ctx *ctx, u_int nx)
return;
s->cx -= nx;
-
- if (ctx->write != NULL)
- ctx->write(ctx->data, TTY_CURSORLEFT, nx);
}
/* Insert nx characters. */
@@ -219,11 +182,11 @@ screen_write_insertcharacter(struct screen_write_ctx *ctx, u_int nx)
if (nx == 0)
return;
- if (s->cx <= screen_size_x(s) - 1)
- grid_view_insert_cells(s->grid, s->cx, s->cy, nx);
-
if (ctx->write != NULL)
ctx->write(ctx->data, TTY_INSERTCHARACTER, nx);
+
+ if (s->cx <= screen_size_x(s) - 1)
+ grid_view_insert_cells(s->grid, s->cx, s->cy, nx);
}
/* Delete nx characters. */
@@ -240,11 +203,11 @@ screen_write_deletecharacter(struct screen_write_ctx *ctx, u_int nx)
if (nx == 0)
return;
- if (s->cx <= screen_size_x(s) - 1)
- grid_view_delete_cells(s->grid, s->cx, s->cy, nx);
-
if (ctx->write != NULL)
ctx->write(ctx->data, TTY_DELETECHARACTER, nx);
+
+ if (s->cx <= screen_size_x(s) - 1)
+ grid_view_delete_cells(s->grid, s->cx, s->cy, nx);
}
/* Insert ny lines. */
@@ -261,15 +224,15 @@ screen_write_insertline(struct screen_write_ctx *ctx, u_int ny)
if (ny == 0)
return;
+ if (ctx->write != NULL)
+ ctx->write(ctx->data, TTY_INSERTLINE, ny);
+
if (s->cy < s->rupper || s->cy > s->rlower)
grid_view_insert_lines(s->grid, s->cy, ny);
else {
grid_view_insert_lines_region(
s->grid, s->rupper, s->rlower, s->cy, ny);
}
-
- if (ctx->write != NULL)
- ctx->write(ctx->data, TTY_INSERTLINE, ny);
}
/* Delete ny lines. */
@@ -286,15 +249,15 @@ screen_write_deleteline(struct screen_write_ctx *ctx, u_int ny)
if (ny == 0)
return;
+ if (ctx->write != NULL)
+ ctx->write(ctx->data, TTY_DELETELINE, ny);
+
if (s->cy < s->rupper || s->cy > s->rlower)
grid_view_delete_lines(s->grid, s->cy, ny);
else {
grid_view_delete_lines_region(
s->grid, s->rupper, s->rlower, s->cy, ny);
}
-
- if (ctx->write != NULL)
- ctx->write(ctx->data, TTY_DELETELINE, ny);
}
/* Clear line at cursor. */
@@ -303,10 +266,10 @@ screen_write_clearline(struct screen_write_ctx *ctx)
{
struct screen *s = ctx->s;
- grid_view_clear(s->grid, 0, s->cy, screen_size_x(s), 1);
-
if (ctx->write != NULL)
ctx->write(ctx->data, TTY_CLEARLINE);
+
+ grid_view_clear(s->grid, 0, s->cy, screen_size_x(s), 1);
}
/* Clear to end of line from cursor. */
@@ -318,11 +281,11 @@ screen_write_clearendofline(struct screen_write_ctx *ctx)
sx = screen_size_x(s);
- if (s->cx <= sx - 1)
- grid_view_clear(s->grid, s->cx, s->cy, sx - s->cx, 1);
-
if (ctx->write != NULL)
ctx->write(ctx->data, TTY_CLEARENDOFLINE);
+
+ if (s->cx <= sx - 1)
+ grid_view_clear(s->grid, s->cx, s->cy, sx - s->cx, 1);
}
/* Clear to start of line from cursor. */
@@ -334,13 +297,13 @@ screen_write_clearstartofline(struct screen_write_ctx *ctx)
sx = screen_size_x(s);
+ if (ctx->write != NULL)
+ ctx->write(ctx->data, TTY_CLEARSTARTOFLINE);
+
if (s->cx > sx - 1)
grid_view_clear(s->grid, 0, s->cy, sx, 1);
else
grid_view_clear(s->grid, 0, s->cy, s->cx + 1, 1);
-
- if (ctx->write != NULL)
- ctx->write(ctx->data, TTY_CLEARSTARTOFLINE);
}
/* Move cursor to px,py. */
@@ -356,9 +319,6 @@ screen_write_cursormove(struct screen_write_ctx *ctx, u_int px, u_int py)
s->cx = px;
s->cy = py;
-
- if (ctx->write != NULL)
- ctx->write(ctx->data, TTY_CURSORMOVE, px, py);
}
/* Set cursor mode. */
@@ -371,9 +331,6 @@ screen_write_cursormode(struct screen_write_ctx *ctx, int state)
s->mode |= MODE_CURSOR;
else
s->mode &= ~MODE_CURSOR;
-
- if (ctx->write != NULL)
- ctx->write(ctx->data, TTY_CURSORMODE, state);
}
/* Reverse index (up with scroll). */
@@ -382,13 +339,13 @@ screen_write_reverseindex(struct screen_write_ctx *ctx)
{
struct screen *s = ctx->s;
+ if (ctx->write != NULL)
+ ctx->write(ctx->data, TTY_REVERSEINDEX);
+
if (s->cy == s->rupper)
grid_view_scroll_region_down(s->grid, s->rupper, s->rlower);
else if (s->cy > 0)
s->cy--;
-
- if (ctx->write != NULL)
- ctx->write(ctx->data, TTY_REVERSEINDEX);
}
/* Set scroll region. */
@@ -411,9 +368,6 @@ screen_write_scrollregion(
s->rupper = rupper;
s->rlower = rlower;
-
- if (ctx->write != NULL)
- ctx->write(ctx->data, TTY_SCROLLREGION, rupper, rlower);
}
/* Set insert mode. */
@@ -422,13 +376,13 @@ screen_write_insertmode(struct screen_write_ctx *ctx, int state)
{
struct screen *s = ctx->s;
+ if (ctx->write != NULL)
+ ctx->write(ctx->data, TTY_INSERTMODE, state);
+
if (state)
s->mode |= MODE_INSERT;
else
s->mode &= ~MODE_INSERT;
-
- if (ctx->write != NULL)
- ctx->write(ctx->data, TTY_INSERTMODE, state);
}
/* Set mouse mode. */
@@ -437,13 +391,13 @@ screen_write_mousemode(struct screen_write_ctx *ctx, int state)
{
struct screen *s = ctx->s;
+ if (ctx->write != NULL)
+ ctx->write(ctx->data, TTY_MOUSEMODE, state);
+
if (state)
s->mode |= MODE_MOUSE;
else
s->mode &= ~MODE_MOUSE;
-
- if (ctx->write != NULL)
- ctx->write(ctx->data, TTY_MOUSEMODE, state);
}
/* Line feed (down with scroll). */
@@ -452,13 +406,13 @@ screen_write_linefeed(struct screen_write_ctx *ctx)
{
struct screen *s = ctx->s;
+ if (ctx->write != NULL)
+ ctx->write(ctx->data, TTY_LINEFEED);
+
if (s->cy == s->rlower)
grid_view_scroll_region_up(s->grid, s->rupper, s->rlower);
else if (s->cy < screen_size_x(s) - 1)
s->cy++;
-
- if (ctx->write != NULL)
- ctx->write(ctx->data, TTY_LINEFEED);
}
/* Carriage return (cursor to start of line). */
@@ -468,9 +422,6 @@ screen_write_carriagereturn(struct screen_write_ctx *ctx)
struct screen *s = ctx->s;
s->cx = 0;
-
- if (ctx->write != NULL)
- ctx->write(ctx->data, TTY_CARRIAGERETURN);
}
/* Set keypad cursor keys mode. */
@@ -479,13 +430,13 @@ screen_write_kcursormode(struct screen_write_ctx *ctx, int state)
{
struct screen *s = ctx->s;
+ if (ctx->write != NULL)
+ ctx->write(ctx->data, TTY_KCURSORMODE);
+
if (state)
s->mode |= MODE_KCURSOR;
else
s->mode &= ~MODE_KCURSOR;
-
- if (ctx->write != NULL)
- ctx->write(ctx->data, TTY_KCURSORMODE);
}
/* Set keypad number keys mode. */
@@ -494,13 +445,13 @@ screen_write_kkeypadmode(struct screen_write_ctx *ctx, int state)
{
struct screen *s = ctx->s;
+ if (ctx->write != NULL)
+ ctx->write(ctx->data, TTY_KKEYPADMODE);
+
if (state)
s->mode |= MODE_KKEYPAD;
else
s->mode &= ~MODE_KKEYPAD;
-
- if (ctx->write != NULL)
- ctx->write(ctx->data, TTY_KKEYPADMODE);
}
/* Clear to end of screen from cursor. */
@@ -513,12 +464,12 @@ screen_write_clearendofscreen(struct screen_write_ctx *ctx)
sx = screen_size_x(s);
sy = screen_size_y(s);
+ if (ctx->write != NULL)
+ ctx->write(ctx->data, TTY_CLEARENDOFSCREEN);
+
if (s->cx <= sx - 1)
grid_view_clear(s->grid, s->cx, s->cy, sx - s->cx, 1);
grid_view_clear(s->grid, 0, s->cy + 1, sx, sy - (s->cy + 1));
-
- if (ctx->write != NULL)
- ctx->write(ctx->data, TTY_CLEARENDOFSCREEN);
}
/* Clear to start of screen. */
@@ -530,15 +481,15 @@ screen_write_clearstartofscreen(struct screen_write_ctx *ctx)
sx = screen_size_x(s);
+ if (ctx->write != NULL)
+ ctx->write(ctx->data, TTY_CLEARSTARTOFSCREEN);
+
if (s->cy > 0)
grid_view_clear(s->grid, 0, 0, sx, s->cy - 1);
if (s->cx > sx - 1)
grid_view_clear(s->grid, 0, s->cy, sx, 1);
else
grid_view_clear(s->grid, 0, s->cy, s->cx, 1);
-
- if (ctx->write != NULL)
- ctx->write(ctx->data, TTY_CLEARSTARTOFSCREEN);
}
/* Clear entire screen. */
@@ -547,10 +498,10 @@ screen_write_clearscreen(struct screen_write_ctx *ctx)
{
struct screen *s = ctx->s;
- grid_view_clear(s->grid, 0, 0, screen_size_x(s), screen_size_y(s));
-
if (ctx->write != NULL)
ctx->write(ctx->data, TTY_CLEARSCREEN);
+
+ grid_view_clear(s->grid, 0, 0, screen_size_x(s), screen_size_y(s));
}
/* Write cell data. */
@@ -600,8 +551,8 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
* cells back to the character. Don't overwrite the current
* cell as that happens later anyway.
*/
- xx = s->cx;
- while (xx-- > 0) {
+ xx = s->cx + 1;
+ while (--xx > 0) {
hc = grid_view_peek_cell(gd, xx, s->cy);
if (!(hc->flags & GRID_FLAG_PADDING))
break;
@@ -643,14 +594,16 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
/* Write the actual cell. */
grid_view_set_cell(gd, s->cx, s->cy, gc);
- s->cx += width;
if (ctx->write != NULL) {
- if (screen_check_selection(ctx->s, s->cx, s->cy)) {
- memcpy(&tc, &ctx->s->sel.cell, sizeof tc);
+ if (screen_check_selection(s, s->cx, s->cy)) {
+ memcpy(&tc, &s->sel.cell, sizeof tc);
tc.data = gc->data;
ctx->write(ctx->data, TTY_CELL, &tc);
} else
ctx->write(ctx->data, TTY_CELL, gc);
}
+
+ /* Move the cursor. */
+ s->cx += width;
}
diff --git a/server-msg.c b/server-msg.c
index 1912a829..43293a13 100644
--- a/server-msg.c
+++ b/server-msg.c
@@ -1,4 +1,4 @@
-/* $Id: server-msg.c,v 1.56 2009-01-11 00:48:42 nicm Exp $ */
+/* $Id: server-msg.c,v 1.57 2009-01-11 23:31:46 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -21,6 +21,7 @@
#include <errno.h>
#include <stdlib.h>
#include <string.h>
+#include <time.h>
#include <unistd.h>
#include "tmux.h"
diff --git a/server.c b/server.c
index 1c617092..c9139ba9 100644
--- a/server.c
+++ b/server.c
@@ -1,4 +1,4 @@
-/* $Id: server.c,v 1.94 2009-01-11 00:48:42 nicm Exp $ */
+/* $Id: server.c,v 1.95 2009-01-11 23:31:46 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -49,12 +49,11 @@ void server_fill_clients(struct pollfd **);
void server_handle_clients(struct pollfd **);
struct client *server_accept_client(int);
void server_handle_client(struct client *);
-void server_handle_window(struct window *);
+void server_handle_window(struct window *, int);
void server_lost_client(struct client *);
-void server_lost_window(struct window *);
+int server_lost_window(struct window *, int);
void server_check_redraw(struct client *);
-void server_do_redraw_client(struct client *);
-void server_do_redraw_locked(struct client *);
+void server_redraw_locked(struct client *);
void server_check_timers(struct client *);
void server_second_timers(void);
int server_update_socket(const char *);
@@ -184,7 +183,9 @@ server_main(const char *srv_path, int srv_fd)
pfds = NULL;
while (!sigterm) {
/* Initialise pollfd array. */
- nfds = 1 + ARRAY_LENGTH(&windows) + ARRAY_LENGTH(&clients) * 2;
+ nfds = 1;
+ nfds += ARRAY_LENGTH(&windows) * 2;
+ nfds += ARRAY_LENGTH(&clients) * 2;
pfds = xrealloc(pfds, nfds, sizeof *pfds);
pfd = pfds;
@@ -279,19 +280,25 @@ server_main(const char *srv_path, int srv_fd)
void
server_fill_windows(struct pollfd **pfd)
{
- struct window *w;
- u_int i;
+ struct window *w;
+ struct window_pane *wp;
+ u_int i, j;
for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
- if ((w = ARRAY_ITEM(&windows, i)) == NULL || w->fd == -1)
- (*pfd)->fd = -1;
- else {
- (*pfd)->fd = w->fd;
- (*pfd)->events = POLLIN;
- if (BUFFER_USED(w->out) > 0)
- (*pfd)->events |= POLLOUT;
+ w = ARRAY_ITEM(&windows, i);
+ for (j = 0; j < 2; j++) {
+ if (w != NULL)
+ wp = w->panes[j];
+ if (w == NULL || wp == NULL || wp->fd == -1) {
+ (*pfd)->fd = -1;
+ } else {
+ (*pfd)->fd = wp->fd;
+ (*pfd)->events = POLLIN;
+ if (BUFFER_USED(wp->out) > 0)
+ (*pfd)->events |= POLLOUT;
+ }
+ (*pfd)++;
}
- (*pfd)++;
}
}
@@ -299,17 +306,24 @@ server_fill_windows(struct pollfd **pfd)
void
server_handle_windows(struct pollfd **pfd)
{
- struct window *w;
- u_int i;
+ struct window *w;
+ struct window_pane *wp;
+ u_int i, j;
for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
- if ((w = ARRAY_ITEM(&windows, i)) != NULL && w->fd != -1) {
- if (buffer_poll(*pfd, w->in, w->out) != 0)
- server_lost_window(w);
- else
- server_handle_window(w);
+ w = ARRAY_ITEM(&windows, i);
+ for (j = 0; j < 2; j++) {
+ if (w != NULL)
+ wp = w->panes[j];
+ if (w != NULL && wp != NULL && wp->fd != -1) {
+ if (buffer_poll(*pfd, wp->in, wp->out) != 0) {
+ if (server_lost_window(w, j) != 0)
+ break;
+ } else
+ server_handle_window(w, j);
+ }
+ (*pfd)++;
}
- (*pfd)++;
}
}
@@ -329,7 +343,7 @@ server_check_redraw(struct client *c)
c->tty.flags &= ~TTY_FREEZE;
if (options_get_number(&s->options, "set-titles")) {
- title = s->curw->window->base.title;
+ title = s->curw->window->active->screen->title;
if (c->title == NULL || strcmp(title, c->title) != 0) {
if (c->title != NULL)
xfree(c->title);
@@ -338,16 +352,7 @@ server_check_redraw(struct client *c)
}
}
- if (c->flags & CLIENT_REDRAW) {
- if (server_locked)
- server_do_redraw_locked(c);
- else
- server_do_redraw_client(c);
-
- c->flags |= CLIENT_STATUS;
- }
-
- if (c->flags & CLIENT_STATUS) {
+ if (c->flags & (CLIENT_REDRAW|CLIENT_STATUS)) {
if (c->message_string != NULL)
status_message_redraw(c);
else if (c->prompt_string != NULL)
@@ -356,78 +361,47 @@ server_check_redraw(struct client *c)
status_redraw(c);
}
- c->tty.flags |= flags;
+ if (c->flags & CLIENT_REDRAW) {
+ if (server_locked)
+ server_redraw_locked(c);
+ else
+ screen_redraw_screen(c, NULL);
+ }
- c->flags &= ~(CLIENT_REDRAW|CLIENT_STATUS);
-}
+ if (c->flags & CLIENT_STATUS)
+ screen_redraw_status(c);
-/* Redraw client normally. */
-void
-server_do_redraw_client(struct client *c)
-{
- struct session *s = c->session;
- struct screen_redraw_ctx ctx;
- struct screen screen;
- struct grid_cell gc;
- u_int xx, yy, sx, sy;
-
- xx = c->sx;
- yy = c->sy - 1;
+ c->tty.flags |= flags;
- sx = screen_size_x(s->curw->window->screen);
- sy = screen_size_y(s->curw->window->screen);
-
- if (sx < xx || sy < yy) {
- /*
- * Fake up a blank(ish) screen and use it to draw the empty
- * regions. NOTE: because this uses tty_write_client but
- * doesn't write the client's screen, this can't use anything
- * which relies on cursor position.
- */
-
- screen_init(&screen, xx, yy, 0);
- screen_redraw_start(&ctx, &screen, tty_write_client, c);
- if (sx < xx)
- screen_redraw_columns(&ctx, sx, xx - sx);
- if (sy < yy) {
- memcpy(&gc, &grid_default_cell, sizeof gc);
- gc.data = '-';
- grid_view_fill(screen.grid, &gc, 0, sy, xx, 1);
- screen_redraw_lines(&ctx, sy, yy - sy);
- }
- screen_redraw_stop(&ctx);
- screen_free(&screen);
- }
-
- screen_redraw_start_client(&ctx, c);
- screen_redraw_lines(&ctx, 0, screen_size_y(ctx.s));
- screen_redraw_stop(&ctx);
+ c->flags &= ~(CLIENT_REDRAW|CLIENT_STATUS);
}
/* Redraw client when locked. */
void
-server_do_redraw_locked(struct client *c)
+server_redraw_locked(struct client *c)
{
- struct session *s = c->session;
- struct window *w = s->curw->window;
- struct screen_write_ctx ctx;
- struct screen screen;
- u_int colour, xx, yy;
- int style;
+ struct screen_write_ctx ctx;
+ struct screen screen;
+ u_int colour, xx, yy;
+ int style;
xx = c->sx;
yy = c->sy - 1;
if (xx == 0 || yy == 0)
return;
- colour = options_get_number(&w->options, "clock-mode-colour");
- style = options_get_number(&w->options, "clock-mode-style");
+ colour = options_get_number(
+ &global_window_options, "clock-mode-colour");
+ style = options_get_number(
+ &global_window_options, "clock-mode-style");
screen_init(&screen, xx, yy, 0);
- screen_write_start(&ctx, &screen, tty_write_client, c);
+ screen_write_start(&ctx, NULL, &screen);
clock_draw(&ctx, colour, style);
screen_write_stop(&ctx);
+ screen_redraw_screen(c, &screen);
+
screen_free(&screen);
}
@@ -567,6 +541,7 @@ server_accept_client(int srv_fd)
c->session = NULL;
c->sx = 80;
c->sy = 25;
+ screen_init(&c->status, c->sx, 1, 0);
c->message_string = NULL;
@@ -588,9 +563,12 @@ server_accept_client(int srv_fd)
void
server_handle_client(struct client *c)
{
- struct window *w = c->session->curw->window;
- int key, prefix;
+ struct winlink *wl = c->session->curw;
+ struct window_pane *wp = wl->window->active;
+ int key, prefix;
+ u_int oy;
+ /* Process keys. */
prefix = options_get_number(&c->session->options, "prefix");
while (tty_keys_next(&c->tty, &key) == 0) {
server_activity = time(NULL);
@@ -610,8 +588,20 @@ server_handle_client(struct client *c)
} else if (key == prefix)
c->flags |= CLIENT_PREFIX;
else
- window_key(w, c, key);
+ window_pane_key(wp, c, key);
}
+
+ /* Ensure the cursor is in the right place and correctly on or off. */
+ if (c->prompt_string == NULL && c->message_string == NULL &&
+ !server_locked && wp->screen->mode & MODE_CURSOR) {
+ oy = 0;
+ if (wp == wl->window->panes[1])
+ oy = wp->window->sy / 2;
+
+ tty_write(&c->tty, wp->screen, 0, TTY_CURSORMODE, 1);
+ tty_cursor(&c->tty, wp->screen->cx, wp->screen->cy, oy);
+ } else
+ tty_write(&c->tty, wp->screen, 0, TTY_CURSORMODE, 0);
}
/* Lost a client. */
@@ -654,13 +644,14 @@ server_lost_client(struct client *c)
/* Handle window data. */
void
-server_handle_window(struct window *w)
+server_handle_window(struct window *w, int pane)
{
struct session *s;
+ struct client *c;
u_int i;
int action, update;
- window_parse(w);
+ window_pane_parse(w->panes[pane]);
if (!(w->flags & WINDOW_BELL) && !(w->flags & WINDOW_ACTIVITY))
return;
@@ -678,12 +669,22 @@ server_handle_window(struct window *w)
action = options_get_number(&s->options, "bell-action");
switch (action) {
case BELL_ANY:
- tty_write_session(s, TTY_BELL);
+ if (s->flags & SESSION_UNATTACHED)
+ break;
+ for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
+ c = ARRAY_ITEM(&clients, i);
+ if (c != NULL && c->session == s)
+ tty_putcode(&c->tty, TTYC_BEL);
+ }
break;
case BELL_CURRENT:
- if (s->curw->window != w)
+ if (w->active != w->panes[pane])
break;
- tty_write_session(s, TTY_BELL);
+ for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
+ c = ARRAY_ITEM(&clients, i);
+ if (c != NULL && c->session == s)
+ tty_putcode(&c->tty, TTYC_BEL);
+ }
break;
}
update = 1;
@@ -703,20 +704,27 @@ server_handle_window(struct window *w)
}
/* Lost window: move clients on to next window. */
-void
-server_lost_window(struct window *w)
+int
+server_lost_window(struct window *w, int pane)
{
- struct client *c;
- struct session *s;
- struct winlink *wl;
- u_int i, j;
- int destroyed;
-
- log_debug("lost window %d", w->fd);
+ struct client *c;
+ struct session *s;
+ struct winlink *wl;
+ struct window_pane *wp;
+ u_int i, j;
+ int destroyed;
+
+ wp = w->panes[pane];
+ log_debug("lost window %d (%s pane %d)", wp->fd, w->name, pane);
+
+ if (window_remove_pane(w, pane) == 0) {
+ server_redraw_window(w);
+ return (0);
+ }
if (options_get_number(&w->options, "remain-on-exit")) {
- w->fd = -1;
- return;
+ wp->fd = -1;
+ return (0);
}
for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
@@ -751,18 +759,20 @@ server_lost_window(struct window *w)
}
recalculate_sizes();
+ return (1);
}
/* Call any once-per-second timers. */
void
server_second_timers(void)
{
- struct window *w;
- u_int i;
- int xtimeout;
- struct tm now, then;
- static time_t last_t = 0;
- time_t t;
+ struct window *w;
+ struct window_pane *wp;
+ u_int i, j;
+ int xtimeout;
+ struct tm now, then;
+ static time_t last_t = 0;
+ time_t t;
t = time(NULL);
xtimeout = options_get_number(&global_options, "lock-after-time");
@@ -771,8 +781,15 @@ server_second_timers(void)
for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
w = ARRAY_ITEM(&windows, i);
- if (w->mode != NULL && w->mode->timer != NULL)
- w->mode->timer(w);
+ if (w == NULL)
+ continue;
+ for (j = 0; j < 2; j++) {
+ wp = w->panes[j];
+ if (wp == NULL)
+ continue;
+ if (wp->mode != NULL && wp->mode->timer != NULL)
+ wp->mode->timer(wp);
+ }
}
gmtime_r(&t, &now);
diff --git a/status.c b/status.c
index 2a8a7efa..6efe6f51 100644
--- a/status.c
+++ b/status.c
@@ -1,4 +1,4 @@
-/* $Id: status.c,v 1.59 2009-01-11 00:48:42 nicm Exp $ */
+/* $Id: status.c,v 1.60 2009-01-11 23:31:46 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -39,11 +39,12 @@ char *status_prompt_complete(const char *);
void
status_redraw(struct client *c)
{
- struct screen_redraw_ctx ctx;
+ struct screen_write_ctx ctx;
struct session *s = c->session;
struct winlink *wl;
+ struct window_pane *wp;
char *left, *right, *text, *ptr;
- size_t llen, rlen, offset, xx, yy;
+ size_t llen, rlen, offset, xx, yy, sy;
size_t size, start, width;
struct grid_cell gc;
int larrow, rarrow;
@@ -144,22 +145,28 @@ status_redraw(struct client *c)
width = xx;
draw:
+ /* Resize the target screen. */
+ if (screen_size_x(&c->status) != c->sx) {
+ screen_free(&c->status);
+ screen_init(&c->status, c->sx, 1, 0);
+ }
+
/* Bail here if anything is too small too. XXX. */
if (width == 0 || xx == 0)
goto blank;
/* Begin drawing and move to the starting position. */
- screen_redraw_start_client(&ctx, c);
+ screen_write_start(&ctx, NULL, &c->status);
if (llen != 0) {
- ctx.write(ctx.data, TTY_CURSORMOVE, 0, yy);
- screen_redraw_puts(&ctx, &gc, "%s ", left);
+ screen_write_cursormove(&ctx, 0, yy);
+ screen_write_puts(&ctx, &gc, "%s ", left);
if (larrow)
- screen_redraw_putc(&ctx, &gc, ' ');
+ screen_write_putc(&ctx, &gc, ' ');
} else {
if (larrow)
- ctx.write(ctx.data, TTY_CURSORMOVE, 1, yy);
+ screen_write_cursormove(&ctx, 1, yy);
else
- ctx.write(ctx.data, TTY_CURSORMOVE, 0, yy);
+ screen_write_cursormove(&ctx, 0, yy);
}
/* Draw each character in succession. */
@@ -176,7 +183,7 @@ draw:
for (ptr = text; *ptr != '\0'; ptr++) {
if (offset >= start && offset < start + width)
- screen_redraw_putc(&ctx, &gc, *ptr);
+ screen_write_putc(&ctx, &gc, *ptr);
offset++;
}
@@ -190,7 +197,7 @@ draw:
gc.attr &= ~GRID_ATTR_REVERSE;
if (offset < start + width) {
if (offset >= start) {
- screen_redraw_putc(&ctx, &gc, ' ');
+ screen_write_putc(&ctx, &gc, ' ');
}
offset++;
}
@@ -200,12 +207,12 @@ draw:
/* Fill the remaining space if any. */
while (offset++ < xx)
- screen_redraw_putc(&ctx, &gc, ' ');
+ screen_write_putc(&ctx, &gc, ' ');
/* Draw the last item. */
if (rlen != 0) {
- ctx.write(ctx.data, TTY_CURSORMOVE, c->sx - rlen - 1, yy);
- screen_redraw_puts(&ctx, &gc, " %s", right);
+ screen_write_cursormove(&ctx, c->sx - rlen - 1, yy);
+ screen_write_puts(&ctx, &gc, " %s", right);
}
/* Draw the arrows. */
@@ -215,10 +222,10 @@ draw:
else
gc.attr &= ~GRID_ATTR_REVERSE;
if (llen != 0)
- ctx.write(ctx.data, TTY_CURSORMOVE, llen + 1, yy);
+ screen_write_cursormove(&ctx, llen + 1, yy);
else
- ctx.write(ctx.data, TTY_CURSORMOVE, 0, yy);
- screen_redraw_putc(&ctx, &gc, '<');
+ screen_write_cursormove(&ctx, 0, yy);
+ screen_write_putc(&ctx, &gc, '<');
gc.attr &= ~GRID_ATTR_REVERSE;
}
if (rarrow != 0) {
@@ -226,12 +233,11 @@ draw:
gc.attr |= GRID_ATTR_REVERSE;
else
gc.attr &= ~GRID_ATTR_REVERSE;
- if (rlen != 0) {
- ctx.write(
- ctx.data, TTY_CURSORMOVE, c->sx - rlen - 2, yy);
- } else
- ctx.write(ctx.data, TTY_CURSORMOVE, c->sx - 1, yy);
- screen_redraw_putc(&ctx, &gc, '>');
+ if (rlen != 0)
+ screen_write_cursormove(&ctx, c->sx - rlen - 2, yy);
+ else
+ screen_write_cursormove(&ctx, c->sx - 1, yy);
+ screen_write_putc(&ctx, &gc, '>');
gc.attr &= ~GRID_ATTR_REVERSE;
}
@@ -239,10 +245,10 @@ draw:
blank:
/* Just draw the whole line as blank. */
- screen_redraw_start_client(&ctx, c);
- ctx.write(ctx.data, TTY_CURSORMOVE, 0, yy);
+ screen_write_start(&ctx, NULL, &c->status);
+ screen_write_cursormove(&ctx, 0, yy);
for (offset = 0; offset < c->sx; offset++)
- screen_redraw_putc(&ctx, &gc, ' ');
+ screen_write_putc(&ctx, &gc, ' ');
goto out;
@@ -251,17 +257,26 @@ off:
* Draw the real window last line. Necessary to wipe over message if
* status is off. Not sure this is the right place for this.
*/
- screen_redraw_start_client(&ctx, c);
- /* If the screen is too small, use blank. */
- if (screen_size_y(c->session->curw->window->screen) < c->sy) {
- ctx.write(ctx.data, TTY_CURSORMOVE, 0, c->sy - 1);
+ screen_write_start(&ctx, NULL, &c->status);
+ wp = s->curw->window->panes[1];
+ sy = c->sy - (c->sy / 2);
+ if (wp == NULL) {
+ wp = s->curw->window->panes[0];
+ sy = c->sy;
+ }
+ screen_write_cursormove(&ctx, 0, 0);
+ if (screen_size_y(wp->screen) < sy) {
+ /* If the screen is too small, use blank. */
for (offset = 0; offset < c->sx; offset++)
- screen_redraw_putc(&ctx, &gc, ' ');
- } else
- screen_redraw_lines(&ctx, c->sy - 1, 1);
+ screen_write_putc(&ctx, &gc, ' ');
+ abort();
+ } else {
+ screen_write_copy(&ctx, wp->screen, 0, wp->screen->grid->hsize +
+ screen_size_y(wp->screen) - 1, c->sx, 1);
+ }
out:
- screen_redraw_stop(&ctx);
+ screen_write_stop(&ctx);
if (left != NULL)
xfree(left);
@@ -272,6 +287,7 @@ out:
char *
status_replace(struct session *s, char *fmt, time_t t)
{
+ struct winlink *wl = s->curw;
static char out[BUFSIZ];
char in[BUFSIZ], ch, *iptr, *optr, *ptr, *endptr;
size_t len;
@@ -300,7 +316,7 @@ status_replace(struct session *s, char *fmt, time_t t)
switch (*iptr++) {
case 'T':
- ptr = s->curw->window->base.title;
+ ptr = wl->window->active->base.title;
len = strlen(ptr);
if ((size_t) n < len)
len = n;
@@ -333,7 +349,7 @@ status_width(struct winlink *wl)
return (xsnprintf(NULL, 0, "%d:%s ", wl->idx, wl->window->name));
#else
char *s;
- size_t n;
+ size_t n;
xasprintf(&s, "%d:%s ", wl->idx, wl->window->name);
n = strlen(s);
@@ -372,64 +388,68 @@ status_print(struct session *s, struct winlink *wl, struct grid_cell *gc)
void
status_message_redraw(struct client *c)
{
- struct screen_redraw_ctx ctx;
+ struct screen_write_ctx ctx;
struct session *s = c->session;
- size_t xx, yy;
+ size_t len;
struct grid_cell gc;
if (c->sx == 0 || c->sy == 0)
return;
+ if (screen_size_x(&c->status) != c->sx) {
+ screen_free(&c->status);
+ screen_init(&c->status, c->sx, 1, 0);
+ }
- xx = strlen(c->message_string);
- if (xx > c->sx)
- xx = c->sx;
- yy = c->sy - 1;
+ len = strlen(c->message_string);
+ if (len > c->sx)
+ len = c->sx;
memcpy(&gc, &grid_default_cell, sizeof gc);
gc.fg = options_get_number(&s->options, "message-fg");
gc.bg = options_get_number(&s->options, "message-bg");
- screen_redraw_start_client(&ctx, c);
+ screen_write_start(&ctx, NULL, &c->status);
- ctx.write(ctx.data, TTY_CURSORMOVE, 0, yy);
- screen_redraw_puts(&ctx, &gc, "%.*s", (int) xx, c->message_string);
- for (; xx < c->sx; xx++)
- screen_redraw_putc(&ctx, &gc, ' ');
+ screen_write_cursormove(&ctx, 0, 0);
+ screen_write_puts(&ctx, &gc, "%.*s", (int) len, c->message_string);
+ for (; len < c->sx; len++)
+ screen_write_putc(&ctx, &gc, ' ');
- screen_redraw_stop(&ctx);
-
- tty_write_client(c, TTY_CURSORMODE, 0);
+ screen_write_stop(&ctx);
}
/* Draw client prompt on status line of present else on last line. */
void
status_prompt_redraw(struct client *c)
{
- struct screen_redraw_ctx ctx;
+ struct screen_write_ctx ctx;
struct session *s = c->session;
- size_t i, xx, yy, left, size, offset, n;
+ size_t i, size, left, len, offset, n;
char ch;
struct grid_cell gc;
if (c->sx == 0 || c->sy == 0)
return;
+ if (screen_size_x(&c->status) != c->sx) {
+ screen_free(&c->status);
+ screen_init(&c->status, c->sx, 1, 0);
+ }
offset = 0;
- xx = strlen(c->prompt_string);
- if (xx > c->sx)
- xx = c->sx;
- yy = c->sy - 1;
+ len = strlen(c->prompt_string);
+ if (len > c->sx)
+ len = c->sx;
memcpy(&gc, &grid_default_cell, sizeof gc);
gc.fg = options_get_number(&s->options, "message-fg");
gc.bg = options_get_number(&s->options, "message-bg");
- screen_redraw_start_client(&ctx, c);
+ screen_write_start(&ctx, NULL, &c->status);
- ctx.write(ctx.data, TTY_CURSORMOVE, 0, yy);
- screen_redraw_puts(&ctx, &gc, "%.*s", (int) xx, c->prompt_string);
+ screen_write_cursormove(&ctx, 0, 0);
+ screen_write_puts(&ctx, &gc, "%.*s", (int) len, c->prompt_string);
- left = c->sx - xx;
+ left = c->sx - len;
if (left != 0) {
if (c->prompt_index < left)
size = strlen(c->prompt_buffer);
@@ -444,20 +464,18 @@ status_prompt_redraw(struct client *c)
if (n > left)
n = left;
for (i = 0; i < n; i++)
- screen_redraw_putc(&ctx, &gc, '*');
+ screen_write_putc(&ctx, &gc, '*');
} else {
- screen_redraw_puts(&ctx, &gc,
+ screen_write_puts(&ctx, &gc,
"%.*s", (int) left, c->prompt_buffer + offset);
}
- for (i = xx + size; i < c->sx; i++) {
- screen_redraw_putc(&ctx, &gc, ' ');
- ctx.s->cx++;
- }
+ for (i = len + size; i < c->sx; i++)
+ screen_write_putc(&ctx, &gc, ' ');
}
/* Draw a fake cursor. */
- ctx.write(ctx.data, TTY_CURSORMOVE, xx + c->prompt_index - offset, yy);
+ screen_write_cursormove(&ctx, len + c->prompt_index - offset, 0);
if (c->prompt_index == strlen(c->prompt_buffer))
ch = ' ';
else
@@ -466,11 +484,9 @@ status_prompt_redraw(struct client *c)
ch = ' ';
gc.bg = gc.fg;
gc.fg = options_get_number(&s->options, "message-bg");
- screen_redraw_putc(&ctx, &gc, ch);
-
- screen_redraw_stop(&ctx);
+ screen_write_putc(&ctx, &gc, ch);
- tty_write_client(c, TTY_CURSORMODE, 0);
+ screen_write_stop(&ctx);
}
/* Handle keys in prompt. */
diff --git a/tmux.h b/tmux.h
index 6725ddab..3a0d8b1e 100644
--- a/tmux.h
+++ b/tmux.h
@@ -1,4 +1,4 @@
-/* $Id: tmux.h,v 1.222 2009-01-11 23:14:57 nicm Exp $ */
+/* $Id: tmux.h,v 1.223 2009-01-11 23:31:46 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -330,8 +330,6 @@ struct tty_term_code_entry {
/* Output commands. */
enum tty_cmd {
- TTY_BELL,
- TTY_CARRIAGERETURN,
TTY_CELL,
TTY_CLEARENDOFLINE,
TTY_CLEARENDOFSCREEN,
@@ -339,12 +337,7 @@ enum tty_cmd {
TTY_CLEARSCREEN,
TTY_CLEARSTARTOFLINE,
TTY_CLEARSTARTOFSCREEN,
- TTY_CURSORDOWN,
- TTY_CURSORLEFT,
TTY_CURSORMODE,
- TTY_CURSORMOVE,
- TTY_CURSORRIGHT,
- TTY_CURSORUP,
TTY_DELETECHARACTER,
TTY_DELETELINE,
TTY_INSERTCHARACTER,
@@ -355,7 +348,6 @@ enum tty_cmd {
TTY_LINEFEED,
TTY_MOUSEMODE,
TTY_REVERSEINDEX,
- TTY_SCROLLREGION,
};
/* Message codes. */
@@ -514,17 +506,6 @@ struct screen {
struct screen_sel sel;
};
-/* Screen redraw context. */
-struct screen_redraw_ctx {
- void *data;
- void (*write)(void *, enum tty_cmd, ...);
-
- u_int saved_cx;
- u_int saved_cy;
-
- struct screen *s;
-};
-
/* Screen write context. */
struct screen_write_ctx {
void *data;
@@ -547,7 +528,7 @@ struct input_arg {
/* Input parser context. */
struct input_ctx {
- struct window *w;
+ struct window_pane *wp;
struct screen_write_ctx ctx;
u_char *buf;
@@ -584,17 +565,19 @@ struct input_ctx {
* right function to handle input and output.
*/
struct client;
+struct window;
struct window_mode {
- struct screen *(*init)(struct window *);
- void (*free)(struct window *);
- void (*resize)(struct window *, u_int, u_int);
- void (*key)(struct window *, struct client *, int);
- void (*timer)(struct window *);
+ struct screen *(*init)(struct window_pane *);
+ void (*free)(struct window_pane *);
+ void (*resize)(struct window_pane *, u_int, u_int);
+ void (*key)(struct window_pane *, struct client *, int);
+ void (*timer)(struct window_pane *);
};
-/* Window structure. */
-struct window {
- char *name;
+/* Child window structure. */
+struct window_pane {
+ struct window *window;
+
char *cmd;
char *cwd;
@@ -604,18 +587,29 @@ struct window {
struct input_ctx ictx;
- struct options options;
+ struct screen *screen;
+ struct screen base;
+
+ const struct window_mode *mode;
+ void *modedata;
+};
+
+/* Window structure. */
+struct window {
+ char *name;
+
+ struct window_pane *active;
+ struct window_pane *panes[2];
+
+ u_int sx;
+ u_int sy;
int flags;
#define WINDOW_BELL 0x1
#define WINDOW_HIDDEN 0x2
#define WINDOW_ACTIVITY 0x4
- struct screen *screen;
- struct screen base;
-
- const struct window_mode *mode;
- void *modedata;
+ struct options options;
u_int references;
};
@@ -698,6 +692,14 @@ SLIST_HEAD(tty_terms, tty_term);
struct tty {
char *path;
+ u_int cx;
+ u_int cy;
+
+ int cursor;
+
+ u_int rlower;
+ u_int rupper;
+
char *termname;
struct tty_term *term;
@@ -742,6 +744,8 @@ struct client {
u_int sx;
u_int sy;
+ struct screen status;
+
#define CLIENT_TERMINAL 0x1
#define CLIENT_PREFIX 0x2
#define CLIENT_MOUSE 0x4
@@ -973,14 +977,21 @@ void options_set_number(struct options *, const char *, long long);
long long options_get_number(struct options *, const char *);
/* tty.c */
+void tty_cursor(struct tty *, u_int, u_int, u_int);
+void tty_putcode(struct tty *, enum tty_code_code);
+void tty_putcode1(struct tty *, enum tty_code_code, int);
+void tty_putcode2(struct tty *, enum tty_code_code, int, int);
+void tty_puts(struct tty *, const char *);
+void tty_putc(struct tty *, char);
void tty_init(struct tty *, char *, char *);
void tty_set_title(struct tty *, const char *);
int tty_open(struct tty *, char **);
void tty_close(struct tty *);
void tty_free(struct tty *);
-void tty_write(struct tty *, struct screen *, enum tty_cmd, ...);
-void tty_vwrite(
- struct tty *, struct screen *s, enum tty_cmd, va_list);
+void tty_write(struct tty *,
+ struct screen *, u_int, enum tty_cmd, ...);
+void tty_vwrite(struct tty *,
+ struct screen *s, u_int, enum tty_cmd, va_list);
/* tty-term.c */
extern struct tty_terms tty_terms;
@@ -1003,12 +1014,8 @@ void tty_keys_free(struct tty *);
int tty_keys_next(struct tty *, int *);
/* tty-write.c */
-void tty_write_client(void *, enum tty_cmd, ...);
-void tty_vwrite_client(void *, enum tty_cmd, va_list);
void tty_write_window(void *, enum tty_cmd, ...);
void tty_vwrite_window(void *, enum tty_cmd, va_list);
-void tty_write_session(void *, enum tty_cmd, ...);
-void tty_vwrite_session(void *, enum tty_cmd, va_list);
/* options-cmd.c */
void set_option_string(struct cmd_ctx *,
@@ -1102,9 +1109,11 @@ extern const struct cmd_entry cmd_show_buffer_entry;
extern const struct cmd_entry cmd_show_options_entry;
extern const struct cmd_entry cmd_show_window_options_entry;
extern const struct cmd_entry cmd_source_file_entry;
+extern const struct cmd_entry cmd_split_window_entry;
extern const struct cmd_entry cmd_start_server_entry;
extern const struct cmd_entry cmd_swap_window_entry;
extern const struct cmd_entry cmd_switch_client_entry;
+extern const struct cmd_entry cmd_switch_pane_entry;
extern const struct cmd_entry cmd_unbind_key_entry;
extern const struct cmd_entry cmd_unlink_window_entry;
@@ -1200,12 +1209,13 @@ void server_set_client_prompt(struct client *,
void server_clear_client_prompt(struct client *);
struct session *server_extract_session(
struct msg_command_data *, char *, char **);
+void server_write(struct client *, enum hdrtype, const void *, size_t);
void server_write_client(
struct client *, enum hdrtype, const void *, size_t);
void server_write_session(
struct session *, enum hdrtype, const void *, size_t);
void server_write_window(
- struct window *, enum hdrtype, const void *, size_t);
+ struct window *, enum hdrtype, const void *, size_t);
void server_redraw_client(struct client *);
void server_status_client(struct client *);
void server_redraw_session(struct session *);
@@ -1225,12 +1235,12 @@ void status_prompt_key(struct client *, int);
void recalculate_sizes(void);
/* input.c */
-void input_init(struct window *);
-void input_free(struct window *);
-void input_parse(struct window *);
+void input_init(struct window_pane *);
+void input_free(struct window_pane *);
+void input_parse(struct window_pane *);
/* input-key.c */
-void input_key(struct window *, int);
+void input_key(struct window_pane *, int);
/* colour.c */
const char *colour_tostring(u_char);
@@ -1278,12 +1288,8 @@ void grid_view_insert_cells(struct grid_data *, u_int, u_int, u_int);
void grid_view_delete_cells(struct grid_data *, 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 *, enum tty_cmd, ...), void *);
+void screen_write_start(
+ struct screen_write_ctx *, struct window_pane *, struct screen *);
void screen_write_stop(struct screen_write_ctx *);
void printflike3 screen_write_puts(
struct screen_write_ctx *, struct grid_cell *, const char *, ...);
@@ -1318,20 +1324,8 @@ void screen_write_clearscreen(struct screen_write_ctx *);
void screen_write_cell(struct screen_write_ctx *, const struct grid_cell *);
/* 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 *, enum tty_cmd, ...), void *);
-void screen_redraw_stop(struct screen_redraw_ctx *);
-void printflike3 screen_redraw_puts(
- struct screen_redraw_ctx *, struct grid_cell *, const char *, ...);
-void screen_redraw_putc(
- struct screen_redraw_ctx *, struct grid_cell *, u_char);
-void screen_redraw_cell(struct screen_redraw_ctx *, u_int, u_int);
-void screen_redraw_lines(struct screen_redraw_ctx *, u_int, u_int);
-void screen_redraw_columns(struct screen_redraw_ctx *, u_int, u_int);
+void screen_redraw_screen(struct client *, struct screen *);
+void screen_redraw_status(struct client *);
/* screen.c */
void screen_init(struct screen *, u_int, u_int, u_int);
@@ -1364,14 +1358,19 @@ void winlink_stack_push(struct winlink_stack *, struct winlink *);
void winlink_stack_remove(struct winlink_stack *, struct winlink *);
struct window *window_create(const char *, const char *,
const char *, const char **, u_int, u_int, u_int);
-int window_spawn(struct window *,
- const char *, const char *, const char **);
void window_destroy(struct window *);
int window_resize(struct window *, u_int, u_int);
-int window_set_mode(struct window *, const struct window_mode *);
-void window_reset_mode(struct window *);
-void window_parse(struct window *);
-void window_key(struct window *, struct client *, int);
+int window_remove_pane(struct window *, int);
+struct window_pane *window_pane_create(struct window *, u_int, u_int, u_int);
+void window_pane_destroy(struct window_pane *);
+int window_pane_spawn(struct window_pane *,
+ const char *, const char *, const char **);
+int window_pane_resize(struct window_pane *, u_int, u_int);
+int window_pane_set_mode(
+ struct window_pane *, const struct window_mode *);
+void window_pane_reset_mode(struct window_pane *);
+void window_pane_parse(struct window_pane *);
+void window_pane_key(struct window_pane *, struct client *, int);
/* window-clock.c */
extern const struct window_mode window_clock_mode;
@@ -1384,8 +1383,8 @@ extern const struct window_mode window_scroll_mode;
/* window-more.c */
extern const struct window_mode window_more_mode;
-void window_more_vadd(struct window *, const char *, va_list);
-void printflike2 window_more_add(struct window *, const char *, ...);
+void window_more_vadd(struct window_pane *, const char *, va_list);
+void printflike2 window_more_add(struct window_pane *, const char *, ...);
/* session.c */
extern struct sessions sessions;
@@ -1399,7 +1398,7 @@ struct session *session_create(
void session_destroy(struct session *);
int session_index(struct session *, u_int *);
struct winlink *session_new(struct session *,
- const char *, const char *, const char *, int);
+ const char *, const char *, const char *, int);
struct winlink *session_attach(struct session *, struct window *, int);
int session_detach(struct session *, struct winlink *);
int session_has(struct session *, struct window *);
diff --git a/tty-write.c b/tty-write.c
index a8d22c0b..7151f895 100644
--- a/tty-write.c
+++ b/tty-write.c
@@ -1,4 +1,4 @@
-/* $Id: tty-write.c,v 1.3 2009-01-09 23:57:42 nicm Exp $ */
+/* $Id: tty-write.c,v 1.4 2009-01-11 23:31:46 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -21,26 +21,6 @@
#include "tmux.h"
void
-tty_write_client(void *ptr, enum tty_cmd cmd, ...)
-{
- struct client *c = ptr;
- va_list ap;
-
- va_start(ap, cmd);
- tty_vwrite_client(c, cmd, ap);
- va_end(ap);
-}
-
-void
-tty_vwrite_client(void *ptr, enum tty_cmd cmd, va_list ap)
-{
- struct client *c = ptr;
- struct screen *s = c->session->curw->window->screen;
-
- tty_vwrite(&c->tty, s, cmd, ap);
-}
-
-void
tty_write_window(void *ptr, enum tty_cmd cmd, ...)
{
va_list ap;
@@ -53,55 +33,28 @@ tty_write_window(void *ptr, enum tty_cmd cmd, ...)
void
tty_vwrite_window(void *ptr, enum tty_cmd cmd, va_list ap)
{
- struct window *w = ptr;
- struct client *c;
- va_list aq;
- u_int i;
+ struct window_pane *wp = ptr;
+ struct client *c;
+ va_list aq;
+ u_int i, oy;
- if (w->flags & WINDOW_HIDDEN)
+ if (wp->window->flags & WINDOW_HIDDEN)
return;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c == NULL || c->session == NULL)
continue;
- if (c->session->curw->window != w)
- continue;
-
- va_copy(aq, ap);
- tty_vwrite_client(c, cmd, aq);
- va_end(aq);
- }
-}
-void
-tty_write_session(void *ptr, enum tty_cmd cmd, ...)
-{
- va_list ap;
-
- va_start(ap, cmd);
- tty_vwrite_session(ptr, cmd, ap);
- va_end(ap);
-}
-
-void
-tty_vwrite_session(void *ptr, enum tty_cmd cmd, va_list ap)
-{
- struct session *s = ptr;
- struct client *c;
- va_list aq;
- u_int i;
-
- if (s->flags & SESSION_UNATTACHED)
- return;
-
- for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
- c = ARRAY_ITEM(&clients, i);
- if (c == NULL || c->session != s)
- continue;
+ if (c->session->curw->window == wp->window) {
+ if (wp == wp->window->panes[0])
+ oy = 0;
+ else
+ oy = wp->window->sy / 2;
- va_copy(aq, ap);
- tty_vwrite_client(c, cmd, aq);
- va_end(aq);
+ va_copy(aq, ap);
+ tty_vwrite(&c->tty, wp->screen, oy, cmd, aq);
+ va_end(aq);
+ }
}
}
diff --git a/tty.c b/tty.c
index c3ae5b5c..79f7a616 100644
--- a/tty.c
+++ b/tty.c
@@ -1,4 +1,4 @@
-/* $Id: tty.c,v 1.57 2009-01-10 22:28:40 nicm Exp $ */
+/* $Id: tty.c,v 1.58 2009-01-11 23:31:46 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -34,47 +34,35 @@ void tty_emulate_repeat(
struct tty *, enum tty_code_code, enum tty_code_code, u_int);
void tty_raw(struct tty *, const char *);
-void tty_putcode(struct tty *, enum tty_code_code);
-void tty_putcode1(struct tty *, enum tty_code_code, int);
-void tty_putcode2(struct tty *, enum tty_code_code, int, int);
-void tty_puts(struct tty *, const char *);
-void tty_putc(struct tty *, char);
void tty_reset(struct tty *);
+void tty_region(struct tty *, struct screen *, u_int);
void tty_attributes(struct tty *, const struct grid_cell *);
void tty_attributes_fg(struct tty *, const struct grid_cell *);
void tty_attributes_bg(struct tty *, const struct grid_cell *);
-void tty_cmd_bell(struct tty *, struct screen *, va_list);
-void tty_cmd_carriagereturn(struct tty *, struct screen *, va_list);
-void tty_cmd_cell(struct tty *, struct screen *, va_list);
-void tty_cmd_clearendofline(struct tty *, struct screen *, va_list);
-void tty_cmd_clearendofscreen(struct tty *, struct screen *, va_list);
-void tty_cmd_clearline(struct tty *, struct screen *, va_list);
-void tty_cmd_clearscreen(struct tty *, struct screen *, va_list);
-void tty_cmd_clearstartofline(struct tty *, struct screen *, va_list);
-void tty_cmd_clearstartofscreen(struct tty *, struct screen *, va_list);
-void tty_cmd_cursordown(struct tty *, struct screen *, va_list);
-void tty_cmd_cursorleft(struct tty *, struct screen *, va_list);
-void tty_cmd_cursormode(struct tty *, struct screen *, va_list);
-void tty_cmd_cursormove(struct tty *, struct screen *, va_list);
-void tty_cmd_cursorright(struct tty *, struct screen *, va_list);
-void tty_cmd_cursorup(struct tty *, struct screen *, va_list);
-void tty_cmd_deletecharacter(struct tty *, struct screen *, va_list);
-void tty_cmd_deleteline(struct tty *, struct screen *, va_list);
-void tty_cmd_insertcharacter(struct tty *, struct screen *, va_list);
-void tty_cmd_insertline(struct tty *, struct screen *, va_list);
-void tty_cmd_insertmode(struct tty *, struct screen *, va_list);
-void tty_cmd_kcursormode(struct tty *, struct screen *, va_list);
-void tty_cmd_kkeypadmode(struct tty *, struct screen *, va_list);
-void tty_cmd_linefeed(struct tty *, struct screen *, va_list);
-void tty_cmd_mousemode(struct tty *, struct screen *, va_list);
-void tty_cmd_reverseindex(struct tty *, struct screen *, va_list);
-void tty_cmd_scrollregion(struct tty *, struct screen *, va_list);
-
-void (*tty_cmds[])(struct tty *, struct screen *, va_list) = {
- tty_cmd_bell,
- tty_cmd_carriagereturn,
+void tty_cmd_bell(struct tty *, struct screen *, u_int, va_list);
+void tty_cmd_carriagereturn(struct tty *, struct screen *, u_int, va_list);
+void tty_cmd_cell(struct tty *, struct screen *, u_int, va_list);
+void tty_cmd_clearendofline(struct tty *, struct screen *, u_int, va_list);
+void tty_cmd_clearendofscreen(struct tty *, struct screen *, u_int, va_list);
+void tty_cmd_clearline(struct tty *, struct screen *, u_int, va_list);
+void tty_cmd_clearscreen(struct tty *, struct screen *, u_int, va_list);
+void tty_cmd_clearstartofline(struct tty *, struct screen *, u_int, va_list);
+void tty_cmd_clearstartofscreen(struct tty *, struct screen *, u_int, va_list);
+void tty_cmd_cursormode(struct tty *, struct screen *, u_int, va_list);
+void tty_cmd_deletecharacter(struct tty *, struct screen *, u_int, va_list);
+void tty_cmd_deleteline(struct tty *, struct screen *, u_int, va_list);
+void tty_cmd_insertcharacter(struct tty *, struct screen *, u_int, va_list);
+void tty_cmd_insertline(struct tty *, struct screen *, u_int, va_list);
+void tty_cmd_insertmode(struct tty *, struct screen *, u_int, va_list);
+void tty_cmd_kcursormode(struct tty *, struct screen *, u_int, va_list);
+void tty_cmd_kkeypadmode(struct tty *, struct screen *, u_int, va_list);
+void tty_cmd_linefeed(struct tty *, struct screen *, u_int, va_list);
+void tty_cmd_mousemode(struct tty *, struct screen *, u_int, va_list);
+void tty_cmd_reverseindex(struct tty *, struct screen *, u_int, va_list);
+
+void (*tty_cmds[])(struct tty *, struct screen *, u_int, va_list) = {
tty_cmd_cell,
tty_cmd_clearendofline,
tty_cmd_clearendofscreen,
@@ -82,12 +70,7 @@ void (*tty_cmds[])(struct tty *, struct screen *, va_list) = {
tty_cmd_clearscreen,
tty_cmd_clearstartofline,
tty_cmd_clearstartofscreen,
- tty_cmd_cursordown,
- tty_cmd_cursorleft,
tty_cmd_cursormode,
- tty_cmd_cursormove,
- tty_cmd_cursorright,
- tty_cmd_cursorup,
tty_cmd_deletecharacter,
tty_cmd_deleteline,
tty_cmd_insertcharacter,
@@ -98,7 +81,6 @@ void (*tty_cmds[])(struct tty *, struct screen *, va_list) = {
tty_cmd_linefeed,
tty_cmd_mousemode,
tty_cmd_reverseindex,
- tty_cmd_scrollregion,
};
void
@@ -138,6 +120,9 @@ tty_open(struct tty *tty, char **cause)
else
tty->log_fd = -1;
+ tty->cx = UINT_MAX;
+ tty->cy = UINT_MAX;
+
if ((tty->term = tty_term_find(tty->termname, tty->fd, cause)) == NULL)
goto error;
@@ -314,6 +299,8 @@ tty_putc(struct tty *tty, char ch)
ch = tty_get_acs(tty, ch);
buffer_write8(tty->out, ch);
+ tty->cx++; /* This is right most of the time. */
+
if (tty->log_fd != -1)
write(tty->log_fd, &ch, 1);
}
@@ -344,72 +331,35 @@ tty_emulate_repeat(
}
void
-tty_write(struct tty *tty, struct screen *s, enum tty_cmd cmd, ...)
+tty_write(struct tty *tty, struct screen *s, u_int oy, enum tty_cmd cmd, ...)
{
va_list ap;
va_start(ap, cmd);
- tty_vwrite(tty, s, cmd, ap);
+ tty_vwrite(tty, s, oy, cmd, ap);
va_end(ap);
}
void
-tty_vwrite(struct tty *tty, struct screen *s, enum tty_cmd cmd, va_list ap)
+tty_vwrite(
+ struct tty *tty, struct screen *s, u_int oy, enum tty_cmd cmd, va_list ap)
{
if (tty->flags & TTY_FREEZE || tty->term == NULL)
return;
if (tty_cmds[cmd] != NULL)
- tty_cmds[cmd](tty, s, ap);
-}
-
-void
-tty_cmd_cursorup(struct tty *tty, unused struct screen *s, va_list ap)
-{
- u_int ua;
-
- ua = va_arg(ap, u_int);
-
- tty_emulate_repeat(tty, TTYC_CUU, TTYC_CUU1, ua);
+ tty_cmds[cmd](tty, s, oy, ap);
}
void
-tty_cmd_cursordown(struct tty *tty, unused struct screen *s, va_list ap)
-{
- u_int ua;
-
- ua = va_arg(ap, u_int);
-
- tty_emulate_repeat(tty, TTYC_CUD, TTYC_CUD1, ua);
-}
-
-void
-tty_cmd_cursorright(struct tty *tty, unused struct screen *s, va_list ap)
-{
- u_int ua;
-
- ua = va_arg(ap, u_int);
-
- tty_emulate_repeat(tty, TTYC_CUF, TTYC_CUF1, ua);
-}
-
-void
-tty_cmd_cursorleft(struct tty *tty, unused struct screen *s, va_list ap)
-{
- u_int ua;
-
- ua = va_arg(ap, u_int);
-
- tty_emulate_repeat(tty, TTYC_CUB, TTYC_CUB1, ua);
-}
-
-void
-tty_cmd_insertcharacter(struct tty *tty, unused struct screen *s, va_list ap)
+tty_cmd_insertcharacter(
+ struct tty *tty, unused struct screen *s, u_int oy, va_list ap)
{
u_int ua;
ua = va_arg(ap, u_int);
tty_reset(tty);
+ tty_cursor(tty, s->cx, s->cy, oy);
if (tty_term_has(tty->term, TTYC_ICH) ||
tty_term_has(tty->term, TTYC_ICH1))
@@ -419,117 +369,125 @@ tty_cmd_insertcharacter(struct tty *tty, unused struct screen *s, va_list ap)
while (ua-- > 0)
tty_putc(tty, ' ');
tty_putcode(tty, TTYC_RMIR);
- tty_putcode2(tty, TTYC_CUP, s->cy, s->cx);
+ tty_putcode2(tty, TTYC_CUP, oy + s->cy, s->cx);
}
}
void
-tty_cmd_deletecharacter(struct tty *tty, unused struct screen *s, va_list ap)
+tty_cmd_deletecharacter(
+ struct tty *tty, unused struct screen *s, u_int oy, va_list ap)
{
u_int ua;
ua = va_arg(ap, u_int);
tty_reset(tty);
+ tty_cursor(tty, s->cx, s->cy, oy);
tty_emulate_repeat(tty, TTYC_DCH, TTYC_DCH1, ua);
}
void
-tty_cmd_insertline(struct tty *tty, unused struct screen *s, va_list ap)
+tty_cmd_insertline(
+ struct tty *tty, unused struct screen *s, u_int oy, va_list ap)
{
u_int ua;
ua = va_arg(ap, u_int);
tty_reset(tty);
+ tty_region(tty, s, oy);
+ tty_cursor(tty, s->cx, s->cy, oy);
tty_emulate_repeat(tty, TTYC_IL, TTYC_IL1, ua);
}
void
-tty_cmd_deleteline(struct tty *tty, unused struct screen *s, va_list ap)
+tty_cmd_deleteline(
+ struct tty *tty, unused struct screen *s, u_int oy, va_list ap)
{
u_int ua;
ua = va_arg(ap, u_int);
tty_reset(tty);
+ tty_region(tty, s, oy);
+ tty_cursor(tty, s->cx, s->cy, oy);
tty_emulate_repeat(tty, TTYC_DL, TTYC_DL1, ua);
}
void
-tty_cmd_clearline(struct tty *tty, struct screen *s, unused va_list ap)
+tty_cmd_clearline(
+ struct tty *tty, struct screen *s, u_int oy, unused va_list ap)
{
u_int i;
tty_reset(tty);
+ tty_cursor(tty, s->cx, s->cy, oy);
if (tty_term_has(tty->term, TTYC_EL)) {
- tty_putcode2(tty, TTYC_CUP, s->cy, 0);
+ tty_putcode2(tty, TTYC_CUP, oy + s->cy, 0);
tty_putcode(tty, TTYC_EL);
- tty_putcode2(tty, TTYC_CUP, s->cy, s->cx);
+ tty_putcode2(tty, TTYC_CUP, oy + s->cy, s->cx);
} else {
- tty_putcode2(tty, TTYC_CUP, s->cy, 0);
+ tty_putcode2(tty, TTYC_CUP, oy + s->cy, 0);
for (i = 0; i < screen_size_x(s); i++)
tty_putc(tty, ' ');
- tty_putcode2(tty, TTYC_CUP, s->cy, s->cx);
+ tty_putcode2(tty, TTYC_CUP, oy + s->cy, s->cx);
}
}
void
-tty_cmd_clearendofline(struct tty *tty, struct screen *s, unused va_list ap)
+tty_cmd_clearendofline(
+ struct tty *tty, struct screen *s, u_int oy, unused va_list ap)
{
u_int i;
tty_reset(tty);
+ tty_cursor(tty, s->cx, s->cy, oy);
if (tty_term_has(tty->term, TTYC_EL))
tty_putcode(tty, TTYC_EL);
else {
- tty_putcode2(tty, TTYC_CUP, s->cy, s->cx);
+ tty_putcode2(tty, TTYC_CUP, oy + s->cy, s->cx);
for (i = s->cx; i < screen_size_x(s); i++)
tty_putc(tty, ' ');
- tty_putcode2(tty, TTYC_CUP, s->cy, s->cx);
+ tty_putcode2(tty, TTYC_CUP, oy + s->cy, s->cx);
}
}
void
-tty_cmd_clearstartofline(struct tty *tty, struct screen *s, unused va_list ap)
+tty_cmd_clearstartofline(
+ struct tty *tty, struct screen *s, u_int oy, unused va_list ap)
{
u_int i;
tty_reset(tty);
+ tty_cursor(tty, s->cx, s->cy, oy);
if (tty_term_has(tty->term, TTYC_EL1))
tty_putcode(tty, TTYC_EL1);
else {
- tty_putcode2(tty, TTYC_CUP, s->cy, 0);
+ tty_putcode2(tty, TTYC_CUP, oy + s->cy, 0);
for (i = 0; i < s->cx + 1; i++)
tty_putc(tty, ' ');
- tty_putcode2(tty, TTYC_CUP, s->cy, s->cx);
+ tty_putcode2(tty, TTYC_CUP, oy + s->cy, s->cx);
}
}
void
-tty_cmd_cursormove(struct tty *tty, unused struct screen *s, va_list ap)
-{
- u_int ua, ub;
-
- ua = va_arg(ap, u_int);
- ub = va_arg(ap, u_int);
-
- tty_putcode2(tty, TTYC_CUP, ub, ua);
-}
-
-void
-tty_cmd_cursormode(struct tty *tty, unused struct screen *s, va_list ap)
+tty_cmd_cursormode(
+ struct tty *tty, unused struct screen *s, unused u_int oy, va_list ap)
{
- u_int ua;
+ int ua;
ua = va_arg(ap, int);
+ if (tty->cursor == ua)
+ return;
+ tty->cursor = ua;
+
if (ua && !(tty->flags & TTY_NOCURSOR))
tty_putcode(tty, TTYC_CNORM);
else
@@ -538,28 +496,21 @@ tty_cmd_cursormode(struct tty *tty, unused struct screen *s, va_list ap)
void
tty_cmd_reverseindex(
- struct tty *tty, unused struct screen *s, unused va_list ap)
+ struct tty *tty, struct screen *s, u_int oy, unused va_list ap)
{
tty_reset(tty);
+ tty_region(tty, s, oy);
+ tty_cursor(tty, s->cx, s->cy, oy);
tty_putcode(tty, TTYC_RI);
+
}
void
-tty_cmd_scrollregion(struct tty *tty, unused struct screen *s, va_list ap)
-{
- u_int ua, ub;
-
- ua = va_arg(ap, u_int);
- ub = va_arg(ap, u_int);
-
- tty_putcode2(tty, TTYC_CSR, ua, ub);
-}
-
-void
-tty_cmd_insertmode(unused struct tty *tty, unused struct screen *s, va_list ap)
+tty_cmd_insertmode(unused struct tty *tty,
+ unused struct screen *s, unused u_int oy, va_list ap)
{
- u_int ua;
+ int ua;
ua = va_arg(ap, int);
@@ -573,9 +524,10 @@ tty_cmd_insertmode(unused struct tty *tty, unused struct screen *s, va_list ap)
}
void
-tty_cmd_mousemode(struct tty *tty, unused struct screen *s, va_list ap)
+tty_cmd_mousemode(
+ struct tty *tty, unused struct screen *s, unused u_int oy, va_list ap)
{
- u_int ua;
+ int ua;
if (!tty_term_has(tty->term, TTYC_KMOUS))
return;
@@ -589,52 +541,45 @@ tty_cmd_mousemode(struct tty *tty, unused struct screen *s, va_list ap)
}
void
-tty_cmd_kcursormode(
- unused struct tty *tty, unused struct screen *s, unused va_list ap)
+tty_cmd_kcursormode(unused struct tty *tty,
+ unused struct screen *s, unused u_int oy, unused va_list ap)
{
}
void
-tty_cmd_kkeypadmode(
- unused struct tty *tty, unused struct screen *s, unused va_list ap)
+tty_cmd_kkeypadmode(unused struct tty *tty,
+ unused struct screen *s, unused u_int oy, unused va_list ap)
{
}
void
-tty_cmd_linefeed(struct tty *tty, unused struct screen *s, unused va_list ap)
+tty_cmd_linefeed(struct tty *tty, struct screen *s, u_int oy, unused va_list ap)
{
tty_reset(tty);
+ tty_region(tty, s, oy);
+ tty_cursor(tty, s->cx, s->cy, oy);
tty_putc(tty, '\n');
}
void
-tty_cmd_carriagereturn(
- struct tty *tty, unused struct screen *s, unused va_list ap)
-{
- tty_reset(tty);
-
- if (tty_term_has(tty->term, TTYC_CR))
- tty_putcode(tty, TTYC_CR);
- else
- tty_putc(tty, '\r');
-}
-
-void
-tty_cmd_bell(struct tty *tty, unused struct screen *s, unused va_list ap)
+tty_cmd_bell(struct tty *tty,
+ unused struct screen *s, unused u_int oy, unused va_list ap)
{
tty_putcode(tty, TTYC_BEL);
}
void
-tty_cmd_clearendofscreen(struct tty *tty, struct screen *s, unused va_list ap)
+tty_cmd_clearendofscreen(
+ struct tty *tty, struct screen *s, u_int oy, unused va_list ap)
{
u_int i, j;
tty_reset(tty);
+ tty_cursor(tty, s->cx, s->cy, oy);
if (tty_term_has(tty->term, TTYC_EL)) {
- for (i = s->cy; i < screen_size_y(s); i++) {
+ for (i = oy + s->cy; i < oy + screen_size_y(s); i++) {
tty_putcode(tty, TTYC_EL);
if (i != screen_size_y(s) - 1)
tty_emulate_repeat(tty, TTYC_CUD, TTYC_CUD1, 1);
@@ -642,47 +587,51 @@ tty_cmd_clearendofscreen(struct tty *tty, struct screen *s, unused va_list ap)
} else {
for (i = s->cx; i < screen_size_y(s); i++)
tty_putc(tty, ' ');
- for (j = s->cy; j < screen_size_y(s); j++) {
+ for (j = oy + s->cy; j < oy + screen_size_y(s); j++) {
for (i = 0; i < screen_size_x(s); i++)
tty_putc(tty, ' ');
}
}
- tty_putcode2(tty, TTYC_CUP, s->cy, s->cx);
+ tty_putcode2(tty, TTYC_CUP, oy + s->cy, s->cx);
}
void
-tty_cmd_clearstartofscreen(struct tty *tty, struct screen *s, unused va_list ap)
+tty_cmd_clearstartofscreen(
+ struct tty *tty, struct screen *s, u_int oy, unused va_list ap)
{
u_int i, j;
tty_reset(tty);
+ tty_cursor(tty, s->cx, s->cy, oy);
- tty_putcode2(tty, TTYC_CUP, 0, 0);
+ tty_putcode2(tty, TTYC_CUP, oy, 0);
if (tty_term_has(tty->term, TTYC_EL)) {
- for (i = 0; i < s->cy; i++) {
+ for (i = 0; i < oy + s->cy; i++) {
tty_putcode(tty, TTYC_EL);
tty_emulate_repeat(tty, TTYC_CUD, TTYC_CUD1, 1);
}
- tty_putcode2(tty, TTYC_CUP, s->cy, 0);
+ tty_putcode2(tty, TTYC_CUP, oy + s->cy, 0);
} else {
- for (j = 0; j < s->cy; j++) {
+ for (j = 0; j < oy + s->cy; j++) {
for (i = 0; i < screen_size_x(s); i++)
tty_putc(tty, ' ');
}
}
for (i = 0; i < s->cx; i++)
tty_putc(tty, ' ');
- tty_putcode2(tty, TTYC_CUP, s->cy, s->cx);
+ tty_putcode2(tty, TTYC_CUP, oy + s->cy, s->cx);
}
void
-tty_cmd_clearscreen(struct tty *tty, struct screen *s, unused va_list ap)
+tty_cmd_clearscreen(
+ struct tty *tty, struct screen *s, u_int oy, unused va_list ap)
{
u_int i, j;
tty_reset(tty);
+ tty_cursor(tty, s->cx, s->cy, oy);
- tty_putcode2(tty, TTYC_CUP, 0, 0);
+ tty_putcode2(tty, TTYC_CUP, oy, 0);
if (tty_term_has(tty->term, TTYC_EL)) {
for (i = 0; i < screen_size_y(s); i++) {
tty_putcode(tty, TTYC_EL);
@@ -695,16 +644,18 @@ tty_cmd_clearscreen(struct tty *tty, struct screen *s, unused va_list ap)
tty_putc(tty, ' ');
}
}
- tty_putcode2(tty, TTYC_CUP, s->cy, s->cx);
+ tty_putcode2(tty, TTYC_CUP, oy + s->cy, s->cx);
}
void
-tty_cmd_cell(struct tty *tty, unused struct screen *s, va_list ap)
+tty_cmd_cell(struct tty *tty, struct screen *s, u_int oy, va_list ap)
{
struct grid_cell *gc;
u_int i, width;
u_char out[4];
+ tty_cursor(tty, s->cx, s->cy, oy);
+
gc = va_arg(ap, struct grid_cell *);
/* If this is a padding character, do nothing. */
@@ -757,6 +708,28 @@ tty_reset(struct tty *tty)
}
void
+tty_region(struct tty *tty, struct screen *s, u_int oy)
+{
+ if (tty->rlower != oy + s->rlower || tty->rupper != oy + s->rupper) {
+ tty->rlower = oy + s->rlower;
+ tty->rupper = oy + s->rupper;
+ tty->cx = 0;
+ tty->cy = 0;
+ tty_putcode2(tty, TTYC_CSR, tty->rupper, tty->rlower);
+ }
+}
+
+void
+tty_cursor(struct tty *tty, u_int cx, u_int cy, u_int oy)
+{
+ if (tty->cx != cx || tty->cy != oy + cy) {
+ tty->cx = cx;
+ tty->cy = oy + cy;
+ tty_putcode2(tty, TTYC_CUP, tty->cy, tty->cx);
+ }
+}
+
+void
tty_attributes(struct tty *tty, const struct grid_cell *gc)
{
struct grid_cell *tc = &tty->cell;
diff --git a/window-clock.c b/window-clock.c
index 0462142d..84435396 100644
--- a/window-clock.c
+++ b/window-clock.c
@@ -1,4 +1,4 @@
-/* $Id: window-clock.c,v 1.3 2009-01-11 00:48:42 nicm Exp $ */
+/* $Id: window-clock.c,v 1.4 2009-01-11 23:31:46 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -23,13 +23,13 @@
#include "tmux.h"
-struct screen *window_clock_init(struct window *);
-void window_clock_free(struct window *);
-void window_clock_resize(struct window *, u_int, u_int);
-void window_clock_key(struct window *, struct client *, int);
-void window_clock_timer(struct window *);
+struct screen *window_clock_init(struct window_pane *);
+void window_clock_free(struct window_pane *);
+void window_clock_resize(struct window_pane *, u_int, u_int);
+void window_clock_key(struct window_pane *, struct client *, int);
+void window_clock_timer(struct window_pane *);
-void window_clock_draw_screen(struct window *);
+void window_clock_draw_screen(struct window_pane *);
const struct window_mode window_clock_mode = {
window_clock_init,
@@ -45,52 +45,53 @@ struct window_clock_mode_data {
};
struct screen *
-window_clock_init(struct window *w)
+window_clock_init(struct window_pane *wp)
{
struct window_clock_mode_data *data;
struct screen *s;
- w->modedata = data = xmalloc(sizeof *data);
+ wp->modedata = data = xmalloc(sizeof *data);
data->tim = time(NULL);
s = &data->screen;
- screen_init(s, screen_size_x(&w->base), screen_size_y(&w->base), 0);
+ screen_init(s, screen_size_x(&wp->base), screen_size_y(&wp->base), 0);
s->mode &= ~MODE_CURSOR;
- window_clock_draw_screen(w);
+ window_clock_draw_screen(wp);
return (s);
}
void
-window_clock_free(struct window *w)
+window_clock_free(struct window_pane *wp)
{
- struct window_clock_mode_data *data = w->modedata;
+ struct window_clock_mode_data *data = wp->modedata;
screen_free(&data->screen);
xfree(data);
}
void
-window_clock_resize(struct window *w, u_int sx, u_int sy)
+window_clock_resize(struct window_pane *wp, u_int sx, u_int sy)
{
- struct window_clock_mode_data *data = w->modedata;
+ struct window_clock_mode_data *data = wp->modedata;
struct screen *s = &data->screen;
screen_resize(s, sx, sy);
- window_clock_draw_screen(w);
+ window_clock_draw_screen(wp);
}
void
-window_clock_key(struct window *w, unused struct client *c, unused int key)
+window_clock_key(
+ struct window_pane *wp, unused struct client *c, unused int key)
{
- window_reset_mode(w);
+ window_pane_reset_mode(wp);
}
void
-window_clock_timer(struct window *w)
+window_clock_timer(struct window_pane *wp)
{
- struct window_clock_mode_data *data = w->modedata;
+ struct window_clock_mode_data *data = wp->modedata;
struct tm *now, *then;
time_t t;
@@ -101,22 +102,22 @@ window_clock_timer(struct window *w)
return;
data->tim = t;
- window_clock_draw_screen(w);
- server_redraw_window(w);
+ window_clock_draw_screen(wp);
+ server_redraw_window(wp->window);
}
void
-window_clock_draw_screen(struct window *w)
+window_clock_draw_screen(struct window_pane *wp)
{
- struct window_clock_mode_data *data = w->modedata;
+ struct window_clock_mode_data *data = wp->modedata;
struct screen_write_ctx ctx;
u_int colour;
int style;
- colour = options_get_number(&w->options, "clock-mode-colour");
- style = options_get_number(&w->options, "clock-mode-style");
+ colour = options_get_number(&wp->window->options, "clock-mode-colour");
+ style = options_get_number(&wp->window->options, "clock-mode-style");
- screen_write_start(&ctx, &data->screen, NULL, NULL);
+ screen_write_start(&ctx, NULL, &data->screen);
clock_draw(&ctx, colour, style);
screen_write_stop(&ctx);
}
diff --git a/window-copy.c b/window-copy.c
index c23ca07e..bdafbce2 100644
--- a/window-copy.c
+++ b/window-copy.c
@@ -1,4 +1,4 @@
-/* $Id: window-copy.c,v 1.37 2009-01-10 19:35:40 nicm Exp $ */
+/* $Id: window-copy.c,v 1.38 2009-01-11 23:31:46 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -22,42 +22,42 @@
#include "tmux.h"
-struct screen *window_copy_init(struct window *);
-void window_copy_free(struct window *);
-void window_copy_resize(struct window *, u_int, u_int);
-void window_copy_key(struct window *, struct client *, int);
+struct screen *window_copy_init(struct window_pane *);
+void window_copy_free(struct window_pane *);
+void window_copy_resize(struct window_pane *, u_int, u_int);
+void window_copy_key(struct window_pane *, struct client *, int);
-void window_copy_redraw_lines(struct window *, u_int, u_int);
-void window_copy_redraw_screen(struct window *);
+void window_copy_redraw_lines(struct window_pane *, u_int, u_int);
+void window_copy_redraw_screen(struct window_pane *);
void window_copy_write_line(
- struct window *, struct screen_write_ctx *, u_int);
+ struct window_pane *, struct screen_write_ctx *, u_int);
void window_copy_write_lines(
- struct window *, struct screen_write_ctx *, u_int, u_int);
+ struct window_pane *, struct screen_write_ctx *, u_int, u_int);
void window_copy_write_column(
- struct window *, struct screen_write_ctx *, u_int);
+ struct window_pane *, struct screen_write_ctx *, u_int);
void window_copy_write_columns(
- struct window *, struct screen_write_ctx *, u_int, u_int);
+ struct window_pane *, 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 *, struct client *);
+void window_copy_update_cursor(struct window_pane *);
+void window_copy_start_selection(struct window_pane *);
+int window_copy_update_selection(struct window_pane *);
+void window_copy_copy_selection(struct window_pane *, struct client *);
void window_copy_copy_line(
- struct window *, char **, size_t *, u_int, u_int, u_int);
-int window_copy_is_space(struct window *, u_int, u_int);
-u_int window_copy_find_length(struct window *, u_int);
-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_cursor_next_word(struct window *);
-void window_copy_cursor_previous_word(struct window *);
-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);
-void window_copy_scroll_down(struct window *, u_int);
+ struct window_pane *, char **, size_t *, u_int, u_int, u_int);
+int window_copy_is_space(struct window_pane *, u_int, u_int);
+u_int window_copy_find_length(struct window_pane *, u_int);
+void window_copy_cursor_start_of_line(struct window_pane *);
+void window_copy_cursor_end_of_line(struct window_pane *);
+void window_copy_cursor_left(struct window_pane *);
+void window_copy_cursor_right(struct window_pane *);
+void window_copy_cursor_up(struct window_pane *);
+void window_copy_cursor_down(struct window_pane *);
+void window_copy_cursor_next_word(struct window_pane *);
+void window_copy_cursor_previous_word(struct window_pane *);
+void window_copy_scroll_left(struct window_pane *, u_int);
+void window_copy_scroll_right(struct window_pane *, u_int);
+void window_copy_scroll_up(struct window_pane *, u_int);
+void window_copy_scroll_down(struct window_pane *, u_int);
const struct window_mode window_copy_mode = {
window_copy_init,
@@ -81,27 +81,27 @@ struct window_copy_mode_data {
};
struct screen *
-window_copy_init(struct window *w)
+window_copy_init(struct window_pane *wp)
{
struct window_copy_mode_data *data;
struct screen *s;
struct screen_write_ctx ctx;
u_int i;
- w->modedata = data = xmalloc(sizeof *data);
+ wp->modedata = data = xmalloc(sizeof *data);
data->ox = 0;
data->oy = 0;
- data->cx = w->base.cx;
- data->cy = w->base.cy;
+ data->cx = wp->base.cx;
+ data->cy = wp->base.cy;
s = &data->screen;
- screen_init(s, screen_size_x(&w->base), screen_size_y(&w->base), 0);
+ screen_init(s, screen_size_x(&wp->base), screen_size_y(&wp->base), 0);
s->cx = data->cx;
s->cy = data->cy;
- screen_write_start(&ctx, s, NULL, NULL);
+ screen_write_start(&ctx, NULL, s);
for (i = 0; i < screen_size_y(s); i++)
- window_copy_write_line(w, &ctx, i);
+ window_copy_write_line(wp, &ctx, i);
screen_write_cursormove(&ctx, data->cx, data->cy);
screen_write_stop(&ctx);
@@ -109,92 +109,92 @@ window_copy_init(struct window *w)
}
void
-window_copy_free(struct window *w)
+window_copy_free(struct window_pane *wp)
{
- struct window_copy_mode_data *data = w->modedata;
+ struct window_copy_mode_data *data = wp->modedata;
screen_free(&data->screen);
xfree(data);
}
void
-window_copy_resize(struct window *w, u_int sx, u_int sy)
+window_copy_resize(struct window_pane *wp, u_int sx, u_int sy)
{
- struct window_copy_mode_data *data = w->modedata;
+ struct window_copy_mode_data *data = wp->modedata;
struct screen *s = &data->screen;
struct screen_write_ctx ctx;
screen_resize(s, sx, sy);
- screen_write_start(&ctx, s, NULL, NULL);
- window_copy_write_lines(w, &ctx, 0, screen_size_y(s) - 1);
+ screen_write_start(&ctx, NULL, s);
+ window_copy_write_lines(wp, &ctx, 0, screen_size_y(s) - 1);
screen_write_stop(&ctx);
- window_copy_update_selection(w);
+ window_copy_update_selection(wp);
}
void
-window_copy_key(struct window *w, struct client *c, int key)
+window_copy_key(struct window_pane *wp, struct client *c, int key)
{
- struct window_copy_mode_data *data = w->modedata;
+ struct window_copy_mode_data *data = wp->modedata;
struct screen *s = &data->screen;
int table;
- table = options_get_number(&w->options, "mode-keys");
+ table = options_get_number(&wp->window->options, "mode-keys");
switch (mode_key_lookup(table, key)) {
case MODEKEY_QUIT:
- window_reset_mode(w);
+ window_pane_reset_mode(wp);
break;
case MODEKEY_LEFT:
- window_copy_cursor_left(w);
+ window_copy_cursor_left(wp);
return;
case MODEKEY_RIGHT:
- window_copy_cursor_right(w);
+ window_copy_cursor_right(wp);
return;
case MODEKEY_UP:
- window_copy_cursor_up(w);
+ window_copy_cursor_up(wp);
return;
case MODEKEY_DOWN:
- window_copy_cursor_down(w);
+ window_copy_cursor_down(wp);
return;
case MODEKEY_PPAGE:
- if (data->oy + screen_size_y(s) > screen_hsize(&w->base))
- data->oy = screen_hsize(&w->base);
+ if (data->oy + screen_size_y(s) > screen_hsize(&wp->base))
+ data->oy = screen_hsize(&wp->base);
else
data->oy += screen_size_y(s);
- window_copy_update_selection(w);
- window_copy_redraw_screen(w);
+ window_copy_update_selection(wp);
+ window_copy_redraw_screen(wp);
break;
case MODEKEY_NPAGE:
if (data->oy < screen_size_y(s))
data->oy = 0;
else
data->oy -= screen_size_y(s);
- window_copy_update_selection(w);
- window_copy_redraw_screen(w);
+ window_copy_update_selection(wp);
+ window_copy_redraw_screen(wp);
break;
case MODEKEY_STARTSEL:
- window_copy_start_selection(w);
+ window_copy_start_selection(wp);
break;
case MODEKEY_CLEARSEL:
screen_clear_selection(&data->screen);
- window_copy_redraw_screen(w);
+ window_copy_redraw_screen(wp);
break;
case MODEKEY_COPYSEL:
if (c != NULL && c->session != NULL) {
- window_copy_copy_selection(w, c);
- window_reset_mode(w);
+ window_copy_copy_selection(wp, c);
+ window_pane_reset_mode(wp);
}
break;
case MODEKEY_BOL:
- window_copy_cursor_start_of_line(w);
+ window_copy_cursor_start_of_line(wp);
break;
case MODEKEY_EOL:
- window_copy_cursor_end_of_line(w);
+ window_copy_cursor_end_of_line(wp);
break;
case MODEKEY_NWORD:
- window_copy_cursor_next_word(w);
+ window_copy_cursor_next_word(wp);
break;
case MODEKEY_PWORD:
- window_copy_cursor_previous_word(w);
+ window_copy_cursor_previous_word(wp);
break;
default:
break;
@@ -202,9 +202,9 @@ window_copy_key(struct window *w, struct client *c, int key)
}
void
-window_copy_write_line(struct window *w, struct screen_write_ctx *ctx, u_int py)
+window_copy_write_line(struct window_pane *wp, struct screen_write_ctx *ctx, u_int py)
{
- struct window_copy_mode_data *data = w->modedata;
+ struct window_copy_mode_data *data = wp->modedata;
struct screen *s = &data->screen;
struct grid_cell gc;
char hdr[32];
@@ -213,9 +213,9 @@ window_copy_write_line(struct window *w, struct screen_write_ctx *ctx, u_int py)
if (py == 0) {
memcpy(&gc, &grid_default_cell, sizeof gc);
size = xsnprintf(hdr, sizeof hdr,
- "[%u,%u/%u]", data->ox, data->oy, screen_hsize(&w->base));
- gc.fg = options_get_number(&w->options, "mode-fg");
- gc.bg = options_get_number(&w->options, "mode-bg");
+ "[%u,%u/%u]", data->ox, data->oy, screen_hsize(&wp->base));
+ gc.fg = options_get_number(&wp->window->options, "mode-fg");
+ gc.bg = options_get_number(&wp->window->options, "mode-bg");
screen_write_cursormove(ctx, screen_size_x(s) - size, 0);
screen_write_puts(ctx, &gc, "%s", hdr);
screen_write_puts(ctx, &gc, "%s", hdr);
@@ -223,92 +223,92 @@ window_copy_write_line(struct window *w, struct screen_write_ctx *ctx, u_int py)
size = 0;
screen_write_cursormove(ctx, 0, py);
- screen_write_copy(ctx, &w->base, data->ox, (screen_hsize(&w->base) -
+ screen_write_copy(ctx, &wp->base, data->ox, (screen_hsize(&wp->base) -
data->oy) + py, screen_size_x(s) - size, 1);
}
void
window_copy_write_lines(
- struct window *w, struct screen_write_ctx *ctx, u_int py, u_int ny)
+ struct window_pane *wp, struct screen_write_ctx *ctx, u_int py, u_int ny)
{
u_int yy;
for (yy = py; yy < py + ny; yy++)
- window_copy_write_line(w, ctx, py);
+ window_copy_write_line(wp, ctx, py);
}
void
window_copy_write_column(
- struct window *w, struct screen_write_ctx *ctx, u_int px)
+ struct window_pane *wp, struct screen_write_ctx *ctx, u_int px)
{
- struct window_copy_mode_data *data = w->modedata;
+ struct window_copy_mode_data *data = wp->modedata;
struct screen *s = &data->screen;
screen_write_cursormove(ctx, px, 0);
- screen_write_copy(ctx, &w->base,
- data->ox, screen_hsize(&w->base) - data->oy, 1, screen_size_y(s));
+ screen_write_copy(ctx, &wp->base,
+ data->ox, screen_hsize(&wp->base) - data->oy, 1, screen_size_y(s));
}
void
window_copy_write_columns(
- struct window *w, struct screen_write_ctx *ctx, u_int px, u_int nx)
+ struct window_pane *wp, struct screen_write_ctx *ctx, u_int px, u_int nx)
{
u_int xx;
for (xx = px; xx < px + nx; xx++)
- window_copy_write_column(w, ctx, px);
+ window_copy_write_column(wp, ctx, px);
}
void
-window_copy_redraw_lines(struct window *w, u_int py, u_int ny)
+window_copy_redraw_lines(struct window_pane *wp, u_int py, u_int ny)
{
- struct window_copy_mode_data *data = w->modedata;
+ struct window_copy_mode_data *data = wp->modedata;
struct screen_write_ctx ctx;
u_int i;
- screen_write_start_window(&ctx, w);
+ screen_write_start(&ctx, wp, NULL);
for (i = py; i < py + ny; i++)
- window_copy_write_line(w, &ctx, i);
+ window_copy_write_line(wp, &ctx, i);
screen_write_cursormove(&ctx, data->cx, data->cy);
screen_write_stop(&ctx);
}
void
-window_copy_redraw_screen(struct window *w)
+window_copy_redraw_screen(struct window_pane *wp)
{
- struct window_copy_mode_data *data = w->modedata;
+ struct window_copy_mode_data *data = wp->modedata;
- window_copy_redraw_lines(w, 0, screen_size_y(&data->screen));
+ window_copy_redraw_lines(wp, 0, screen_size_y(&data->screen));
}
void
-window_copy_update_cursor(struct window *w)
+window_copy_update_cursor(struct window_pane *wp)
{
- struct window_copy_mode_data *data = w->modedata;
+ struct window_copy_mode_data *data = wp->modedata;
struct screen_write_ctx ctx;
- screen_write_start_window(&ctx, w);
+ screen_write_start(&ctx, wp, NULL);
screen_write_cursormove(&ctx, data->cx, data->cy);
screen_write_stop(&ctx);
}
void
-window_copy_start_selection(struct window *w)
+window_copy_start_selection(struct window_pane *wp)
{
- struct window_copy_mode_data *data = w->modedata;
+ struct window_copy_mode_data *data = wp->modedata;
struct screen *s = &data->screen;
data->selx = data->cx + data->ox;
- data->sely = screen_hsize(&w->base) + data->cy - data->oy;
+ data->sely = screen_hsize(&wp->base) + data->cy - data->oy;
s->sel.flag = 1;
- window_copy_update_selection(w);
+ window_copy_update_selection(wp);
}
int
-window_copy_update_selection(struct window *w)
+window_copy_update_selection(struct window_pane *wp)
{
- struct window_copy_mode_data *data = w->modedata;
+ struct window_copy_mode_data *data = wp->modedata;
struct screen *s = &data->screen;
struct grid_cell gc;
u_int sx, sy, tx, ty;
@@ -318,12 +318,12 @@ window_copy_update_selection(struct window *w)
/* Set colours. */
memcpy(&gc, &grid_default_cell, sizeof gc);
- gc.fg = options_get_number(&w->options, "mode-fg");
- gc.bg = options_get_number(&w->options, "mode-bg");
+ gc.fg = options_get_number(&wp->window->options, "mode-fg");
+ gc.bg = options_get_number(&wp->window->options, "mode-bg");
/* Find top-left of screen. */
tx = data->ox;
- ty = screen_hsize(&w->base) - data->oy;
+ ty = screen_hsize(&wp->base) - data->oy;
/* Adjust the selection. */
sx = data->selx;
@@ -357,9 +357,9 @@ window_copy_update_selection(struct window *w)
}
void
-window_copy_copy_selection(struct window *w, struct client *c)
+window_copy_copy_selection(struct window_pane *wp, struct client *c)
{
- struct window_copy_mode_data *data = w->modedata;
+ struct window_copy_mode_data *data = wp->modedata;
struct screen *s = &data->screen;
char *buf;
size_t off;
@@ -380,7 +380,7 @@ window_copy_copy_selection(struct window *w, struct client *c)
/* Find start and end. */
xx = data->cx + data->ox;
- yy = screen_hsize(&w->base) + data->cy - data->oy;
+ yy = screen_hsize(&wp->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;
@@ -390,23 +390,23 @@ window_copy_copy_selection(struct window *w, struct client *c)
}
/* Trim ex to end of line. */
- xx = window_copy_find_length(w, ey);
+ xx = window_copy_find_length(wp, ey);
if (ex > xx)
ex = xx;
/* Copy the lines. */
if (sy == ey)
- window_copy_copy_line(w, &buf, &off, sy, sx, ex);
+ window_copy_copy_line(wp, &buf, &off, sy, sx, ex);
else {
- xx = window_copy_find_length(w, sy);
- window_copy_copy_line(w, &buf, &off, sy, sx, xx);
+ xx = window_copy_find_length(wp, sy);
+ window_copy_copy_line(wp, &buf, &off, sy, sx, xx);
if (ey - sy > 1) {
for (i = sy + 1; i < ey - 1; i++) {
- xx = window_copy_find_length(w, i);
- window_copy_copy_line(w, &buf, &off, i, 0, xx);
+ xx = window_copy_find_length(wp, i);
+ window_copy_copy_line(wp, &buf, &off, i, 0, xx);
}
}
- window_copy_copy_line(w, &buf, &off, ey, 0, ex);
+ window_copy_copy_line(wp, &buf, &off, ey, 0, ex);
}
/* Terminate buffer, overwriting final \n. */
@@ -421,7 +421,7 @@ window_copy_copy_selection(struct window *w, struct client *c)
void
window_copy_copy_line(
- struct window *w, char **buf, size_t *off, u_int sy, u_int sx, u_int ex)
+ struct window_pane *wp, char **buf, size_t *off, u_int sy, u_int sx, u_int ex)
{
const struct grid_cell *gc;
u_char i, j, xx, data[4];
@@ -429,7 +429,7 @@ window_copy_copy_line(
if (sx > ex)
return;
- xx = window_copy_find_length(w, sy);
+ xx = window_copy_find_length(wp, sy);
if (ex > xx)
ex = xx;
if (sx > xx)
@@ -437,7 +437,7 @@ window_copy_copy_line(
if (sx < ex) {
for (i = sx; i < ex; i++) {
- gc = grid_peek_cell(w->base.grid, i, sy);
+ gc = grid_peek_cell(wp->base.grid, i, sy);
utf8_split(gc->data, data);
*buf = xrealloc(*buf, 1, (*off) + 4);
@@ -455,12 +455,12 @@ window_copy_copy_line(
}
int
-window_copy_is_space(struct window *w, u_int px, u_int py)
+window_copy_is_space(struct window_pane *wp, u_int px, u_int py)
{
const struct grid_cell *gc;
const char *spaces = " -_@";
- gc = grid_peek_cell(w->base.grid, px, py);
+ gc = grid_peek_cell(wp->base.grid, px, py);
if (gc->flags & GRID_FLAG_PADDING)
return (0);
if (gc->data == 0x00 || gc->data > 0xff)
@@ -469,14 +469,14 @@ window_copy_is_space(struct window *w, u_int px, u_int py)
}
u_int
-window_copy_find_length(struct window *w, u_int py)
+window_copy_find_length(struct window_pane *wp, u_int py)
{
const struct grid_cell *gc;
u_int px;
- px = w->base.grid->size[py];
+ px = wp->base.grid->size[py];
while (px > 0) {
- gc = grid_peek_cell(w->base.grid, px - 1, py);
+ gc = grid_peek_cell(wp->base.grid, px - 1, py);
if (gc->data != 0x20)
break;
px--;
@@ -485,29 +485,29 @@ window_copy_find_length(struct window *w, u_int py)
}
void
-window_copy_cursor_start_of_line(struct window *w)
+window_copy_cursor_start_of_line(struct window_pane *wp)
{
- struct window_copy_mode_data *data = w->modedata;
+ struct window_copy_mode_data *data = wp->modedata;
if (data->ox != 0)
- window_copy_scroll_right(w, data->ox);
+ window_copy_scroll_right(wp, data->ox);
data->cx = 0;
- if (window_copy_update_selection(w))
- window_copy_redraw_lines(w, data->cy, 1);
+ if (window_copy_update_selection(wp))
+ window_copy_redraw_lines(wp, data->cy, 1);
else
- window_copy_update_cursor(w);
+ window_copy_update_cursor(wp);
}
void
-window_copy_cursor_end_of_line(struct window *w)
+window_copy_cursor_end_of_line(struct window_pane *wp)
{
- struct window_copy_mode_data *data = w->modedata;
+ struct window_copy_mode_data *data = wp->modedata;
struct screen *s = &data->screen;
u_int px, py;
- py = screen_hsize(&w->base) + data->cy - data->oy;
- px = window_copy_find_length(w, py);
+ py = screen_hsize(&wp->base) + data->cy - data->oy;
+ px = window_copy_find_length(wp, py);
/* On screen. */
if (px > data->ox && px <= data->ox + screen_size_x(s) - 1)
@@ -517,7 +517,7 @@ window_copy_cursor_end_of_line(struct window *w)
if (px > data->ox + screen_size_x(s) - 1) {
/* Move cursor to last and scroll screen. */
window_copy_scroll_left(
- w, px - data->ox - (screen_size_x(s) - 1));
+ wp, px - data->ox - (screen_size_x(s) - 1));
data->cx = screen_size_x(s) - 1;
}
@@ -525,132 +525,132 @@ window_copy_cursor_end_of_line(struct window *w)
if (px <= data->ox) {
if (px < screen_size_x(s) - 1) {
/* Short enough to fit on screen. */
- window_copy_scroll_right(w, data->ox);
+ window_copy_scroll_right(wp, data->ox);
data->cx = px;
} else {
/* Too long to fit on screen. */
window_copy_scroll_right(
- w, data->ox - (px - (screen_size_x(s) - 1)));
+ wp, data->ox - (px - (screen_size_x(s) - 1)));
data->cx = screen_size_x(s) - 1;
}
}
- if (window_copy_update_selection(w))
- window_copy_redraw_lines(w, data->cy, 1);
+ if (window_copy_update_selection(wp))
+ window_copy_redraw_lines(wp, data->cy, 1);
else
- window_copy_update_cursor(w);
+ window_copy_update_cursor(wp);
}
void
-window_copy_cursor_left(struct window *w)
+window_copy_cursor_left(struct window_pane *wp)
{
- struct window_copy_mode_data *data = w->modedata;
+ struct window_copy_mode_data *data = wp->modedata;
if (data->cx == 0) {
if (data->ox > 0)
- window_copy_scroll_right(w, 1);
+ window_copy_scroll_right(wp, 1);
else {
- window_copy_cursor_up(w);
- window_copy_cursor_end_of_line(w);
+ window_copy_cursor_up(wp);
+ window_copy_cursor_end_of_line(wp);
}
} else {
data->cx--;
- if (window_copy_update_selection(w))
- window_copy_redraw_lines(w, data->cy, 1);
+ if (window_copy_update_selection(wp))
+ window_copy_redraw_lines(wp, data->cy, 1);
else
- window_copy_update_cursor(w);
+ window_copy_update_cursor(wp);
}
}
void
-window_copy_cursor_right(struct window *w)
+window_copy_cursor_right(struct window_pane *wp)
{
- struct window_copy_mode_data *data = w->modedata;
+ struct window_copy_mode_data *data = wp->modedata;
u_int px, py;
- py = screen_hsize(&w->base) + data->cy - data->oy;
- px = window_copy_find_length(w, py);
+ py = screen_hsize(&wp->base) + data->cy - data->oy;
+ px = window_copy_find_length(wp, py);
if (data->cx >= px) {
- window_copy_cursor_start_of_line(w);
- window_copy_cursor_down(w);
+ window_copy_cursor_start_of_line(wp);
+ window_copy_cursor_down(wp);
} else {
data->cx++;
- if (window_copy_update_selection(w))
- window_copy_redraw_lines(w, data->cy, 1);
+ if (window_copy_update_selection(wp))
+ window_copy_redraw_lines(wp, data->cy, 1);
else
- window_copy_update_cursor(w);
+ window_copy_update_cursor(wp);
}
}
void
-window_copy_cursor_up(struct window *w)
+window_copy_cursor_up(struct window_pane *wp)
{
- struct window_copy_mode_data *data = w->modedata;
+ struct window_copy_mode_data *data = wp->modedata;
u_int ox, oy, px, py;
- oy = screen_hsize(&w->base) + data->cy - data->oy;
- ox = window_copy_find_length(w, oy);
+ oy = screen_hsize(&wp->base) + data->cy - data->oy;
+ ox = window_copy_find_length(wp, oy);
if (data->cy == 0)
- window_copy_scroll_down(w, 1);
+ window_copy_scroll_down(wp, 1);
else {
data->cy--;
- if (window_copy_update_selection(w))
- window_copy_redraw_lines(w, data->cy, 2);
+ if (window_copy_update_selection(wp))
+ window_copy_redraw_lines(wp, data->cy, 2);
else
- window_copy_update_cursor(w);
+ window_copy_update_cursor(wp);
}
- py = screen_hsize(&w->base) + data->cy - data->oy;
- px = window_copy_find_length(w, py);
+ py = screen_hsize(&wp->base) + data->cy - data->oy;
+ px = window_copy_find_length(wp, py);
if (data->cx + data->ox >= px || data->cx + data->ox >= ox)
- window_copy_cursor_end_of_line(w);
+ window_copy_cursor_end_of_line(wp);
}
void
-window_copy_cursor_down(struct window *w)
+window_copy_cursor_down(struct window_pane *wp)
{
- struct window_copy_mode_data *data = w->modedata;
+ struct window_copy_mode_data *data = wp->modedata;
struct screen *s = &data->screen;
u_int ox, oy, px, py;
- oy = screen_hsize(&w->base) + data->cy - data->oy;
- ox = window_copy_find_length(w, oy);
+ oy = screen_hsize(&wp->base) + data->cy - data->oy;
+ ox = window_copy_find_length(wp, oy);
if (data->cy == screen_size_y(s) - 1)
- window_copy_scroll_up(w, 1);
+ window_copy_scroll_up(wp, 1);
else {
data->cy++;
- if (window_copy_update_selection(w))
- window_copy_redraw_lines(w, data->cy - 1, 2);
+ if (window_copy_update_selection(wp))
+ window_copy_redraw_lines(wp, data->cy - 1, 2);
else
- window_copy_update_cursor(w);
+ window_copy_update_cursor(wp);
}
- py = screen_hsize(&w->base) + data->cy - data->oy;
- px = window_copy_find_length(w, py);
+ py = screen_hsize(&wp->base) + data->cy - data->oy;
+ px = window_copy_find_length(wp, py);
if (data->cx + data->ox >= px || data->cx + data->ox >= ox)
- window_copy_cursor_end_of_line(w);
+ window_copy_cursor_end_of_line(wp);
}
void
-window_copy_cursor_next_word(struct window *w)
+window_copy_cursor_next_word(struct window_pane *wp)
{
- struct window_copy_mode_data *data = w->modedata;
+ struct window_copy_mode_data *data = wp->modedata;
struct screen *s = &data->screen;
u_int px, py, xx, skip;
px = data->ox + data->cx;
- py = screen_hsize(&w->base) + data->cy - data->oy;
- xx = window_copy_find_length(w, py);
+ py = screen_hsize(&wp->base) + data->cy - data->oy;
+ xx = window_copy_find_length(wp, py);
skip = 1;
if (px < xx) {
/* If currently on a space, skip space. */
- if (window_copy_is_space(w, px, py))
+ if (window_copy_is_space(wp, px, py))
skip = 0;
} else
skip = 0;
@@ -668,21 +668,21 @@ window_copy_cursor_next_word(struct window *w)
}
px = 0;
- window_copy_cursor_down(w);
+ window_copy_cursor_down(wp);
py =screen_hsize(
- &w->base) + data->cy - data->oy;
- xx = window_copy_find_length(w, py);
+ &wp->base) + data->cy - data->oy;
+ xx = window_copy_find_length(wp, py);
}
}
if (skip) {
/* Currently skipping non-space (until space). */
- if (window_copy_is_space(w, px, py))
+ if (window_copy_is_space(wp, px, py))
break;
} else {
/* Currently skipping space (until non-space). */
- if (!window_copy_is_space(w, px, py))
+ if (!window_copy_is_space(wp, px, py))
skip = 1;
}
@@ -698,7 +698,7 @@ out:
if (px > data->ox + screen_size_x(s) - 1) {
/* Move cursor to last and scroll screen. */
window_copy_scroll_left(
- w, px - data->ox - (screen_size_x(s) - 1));
+ wp, px - data->ox - (screen_size_x(s) - 1));
data->cx = screen_size_x(s) - 1;
}
@@ -706,36 +706,36 @@ out:
if (px <= data->ox) {
if (px < screen_size_x(s) - 1) {
/* Short enough to fit on screen. */
- window_copy_scroll_right(w, data->ox);
+ window_copy_scroll_right(wp, data->ox);
data->cx = px;
} else {
/* Too long to fit on screen. */
window_copy_scroll_right(
- w, data->ox - (px - (screen_size_x(s) - 1)));
+ wp, data->ox - (px - (screen_size_x(s) - 1)));
data->cx = screen_size_x(s) - 1;
}
}
- if (window_copy_update_selection(w))
- window_copy_redraw_lines(w, data->cy, 1);
+ if (window_copy_update_selection(wp))
+ window_copy_redraw_lines(wp, data->cy, 1);
else
- window_copy_update_cursor(w);
+ window_copy_update_cursor(wp);
}
void
-window_copy_cursor_previous_word(struct window *w)
+window_copy_cursor_previous_word(struct window_pane *wp)
{
- struct window_copy_mode_data *data = w->modedata;
+ struct window_copy_mode_data *data = wp->modedata;
struct screen *s = &data->screen;
u_int ox, px, py, skip;
ox = px = data->ox + data->cx;
- py = screen_hsize(&w->base) + data->cy - data->oy;
+ py = screen_hsize(&wp->base) + data->cy - data->oy;
skip = 1;
if (px != 0) {
/* If currently on a space, skip space. */
- if (window_copy_is_space(w, px - 1, py))
+ if (window_copy_is_space(wp, px - 1, py))
skip = 0;
}
for (;;) {
@@ -745,26 +745,26 @@ window_copy_cursor_previous_word(struct window *w)
while (px == 0) {
if (data->cy == 0 &&
- (screen_hsize(&w->base) == 0 ||
- data->oy >= screen_hsize(&w->base) - 1))
+ (screen_hsize(&wp->base) == 0 ||
+ data->oy >= screen_hsize(&wp->base) - 1))
goto out;
- window_copy_cursor_up(w);
+ window_copy_cursor_up(wp);
py = screen_hsize(
- &w->base) + data->cy - data->oy;
- px = window_copy_find_length(w, py);
+ &wp->base) + data->cy - data->oy;
+ px = window_copy_find_length(wp, py);
}
goto out;
}
if (skip) {
/* Currently skipping non-space (until space). */
- if (window_copy_is_space(w, px - 1, py))
+ if (window_copy_is_space(wp, px - 1, py))
skip = 0;
} else {
/* Currently skipping space (until non-space). */
- if (!window_copy_is_space(w, px - 1, py))
+ if (!window_copy_is_space(wp, px - 1, py))
break;
}
@@ -780,7 +780,7 @@ out:
if (px > data->ox + screen_size_x(s) - 1) {
/* Move cursor to last and scroll screen. */
window_copy_scroll_left(
- w, px - data->ox - (screen_size_x(s) - 1));
+ wp, px - data->ox - (screen_size_x(s) - 1));
data->cx = screen_size_x(s) - 1;
}
@@ -788,26 +788,26 @@ out:
if (px <= data->ox) {
if (px < screen_size_x(s) - 1) {
/* Short enough to fit on screen. */
- window_copy_scroll_right(w, data->ox);
+ window_copy_scroll_right(wp, data->ox);
data->cx = px;
} else {
/* Too long to fit on screen. */
window_copy_scroll_right(
- w, data->ox - (px - (screen_size_x(s) - 1)));
+ wp, data->ox - (px - (screen_size_x(s) - 1)));
data->cx = screen_size_x(s) - 1;
}
}
- if (window_copy_update_selection(w))
- window_copy_redraw_lines(w, data->cy, 1);
+ if (window_copy_update_selection(wp))
+ window_copy_redraw_lines(wp, data->cy, 1);
else
- window_copy_update_cursor(w);
+ window_copy_update_cursor(wp);
}
void
-window_copy_scroll_left(struct window *w, u_int nx)
+window_copy_scroll_left(struct window_pane *wp, u_int nx)
{
- struct window_copy_mode_data *data = w->modedata;
+ struct window_copy_mode_data *data = wp->modedata;
struct screen *s = &data->screen;
struct screen_write_ctx ctx;
u_int i;
@@ -817,27 +817,27 @@ window_copy_scroll_left(struct window *w, u_int nx)
if (nx == 0)
return;
data->ox += nx;
- window_copy_update_selection(w);
+ window_copy_update_selection(wp);
- screen_write_start_window(&ctx, w);
+ screen_write_start(&ctx, wp, NULL);
for (i = 1; i < screen_size_y(s); i++) {
screen_write_cursormove(&ctx, 0, i);
screen_write_deletecharacter(&ctx, nx);
}
- window_copy_write_columns(w, &ctx, screen_size_x(s) - nx, nx);
- window_copy_write_line(w, &ctx, 0);
+ window_copy_write_columns(wp, &ctx, screen_size_x(s) - nx, nx);
+ window_copy_write_line(wp, &ctx, 0);
if (s->sel.flag) {
- window_copy_update_selection(w);
- window_copy_write_lines(w, &ctx, data->cy, 1);
+ window_copy_update_selection(wp);
+ window_copy_write_lines(wp, &ctx, data->cy, 1);
}
screen_write_cursormove(&ctx, data->cx, data->cy);
screen_write_stop(&ctx);
}
void
-window_copy_scroll_right(struct window *w, u_int nx)
+window_copy_scroll_right(struct window_pane *wp, u_int nx)
{
- struct window_copy_mode_data *data = w->modedata;
+ struct window_copy_mode_data *data = wp->modedata;
struct screen *s = &data->screen;
struct screen_write_ctx ctx;
u_int i;
@@ -847,25 +847,25 @@ window_copy_scroll_right(struct window *w, u_int nx)
if (nx == 0)
return;
data->ox -= nx;
- window_copy_update_selection(w);
+ window_copy_update_selection(wp);
- screen_write_start_window(&ctx, w);
+ screen_write_start(&ctx, wp, NULL);
for (i = 1; i < screen_size_y(s); i++) {
screen_write_cursormove(&ctx, 0, i);
screen_write_insertcharacter(&ctx, nx);
}
- window_copy_write_columns(w, &ctx, 0, nx);
- window_copy_write_line(w, &ctx, 0);
+ window_copy_write_columns(wp, &ctx, 0, nx);
+ window_copy_write_line(wp, &ctx, 0);
if (s->sel.flag)
- window_copy_write_line(w, &ctx, data->cy);
+ window_copy_write_line(wp, &ctx, data->cy);
screen_write_cursormove(&ctx, data->cx, data->cy);
screen_write_stop(&ctx);
}
void
-window_copy_scroll_up(struct window *w, u_int ny)
+window_copy_scroll_up(struct window_pane *wp, u_int ny)
{
- struct window_copy_mode_data *data = w->modedata;
+ struct window_copy_mode_data *data = wp->modedata;
struct screen *s = &data->screen;
struct screen_write_ctx ctx;
@@ -874,45 +874,45 @@ window_copy_scroll_up(struct window *w, u_int ny)
if (ny == 0)
return;
data->oy -= ny;
- window_copy_update_selection(w);
+ window_copy_update_selection(wp);
- screen_write_start_window(&ctx, w);
+ screen_write_start(&ctx, wp, NULL);
screen_write_cursormove(&ctx, 0, 0);
screen_write_deleteline(&ctx, ny);
- window_copy_write_lines(w, &ctx, screen_size_y(s) - ny, ny);
- window_copy_write_line(w, &ctx, 0);
- window_copy_write_line(w, &ctx, 1);
+ window_copy_write_lines(wp, &ctx, screen_size_y(s) - ny, ny);
+ window_copy_write_line(wp, &ctx, 0);
+ window_copy_write_line(wp, &ctx, 1);
if (s->sel.flag && screen_size_y(s) > ny)
- window_copy_write_line(w, &ctx, screen_size_y(s) - ny - 1);
+ window_copy_write_line(wp, &ctx, screen_size_y(s) - ny - 1);
screen_write_cursormove(&ctx, data->cx, data->cy);
screen_write_stop(&ctx);
}
void
-window_copy_scroll_down(struct window *w, u_int ny)
+window_copy_scroll_down(struct window_pane *wp, u_int ny)
{
- struct window_copy_mode_data *data = w->modedata;
+ struct window_copy_mode_data *data = wp->modedata;
struct screen *s = &data->screen;
struct screen_write_ctx ctx;
- if (ny > screen_hsize(&w->base))
+ if (ny > screen_hsize(&wp->base))
return;
- if (data->oy > screen_hsize(&w->base) - ny)
- ny = screen_hsize(&w->base) - data->oy;
+ if (data->oy > screen_hsize(&wp->base) - ny)
+ ny = screen_hsize(&wp->base) - data->oy;
if (ny == 0)
return;
data->oy += ny;
- window_copy_update_selection(w);
+ window_copy_update_selection(wp);
- screen_write_start_window(&ctx, w);
+ screen_write_start(&ctx, wp, NULL);
screen_write_cursormove(&ctx, 0, 0);
screen_write_insertline(&ctx, ny);
- window_copy_write_lines(w, &ctx, 0, ny);
+ window_copy_write_lines(wp, &ctx, 0, ny);
if (s->sel.flag && screen_size_y(s) > ny)
- window_copy_write_line(w, &ctx, ny);
+ window_copy_write_line(wp, &ctx, ny);
else if (ny == 1) /* nuke position */
- window_copy_write_line(w, &ctx, 1);
+ window_copy_write_line(wp, &ctx, 1);
screen_write_cursormove(&ctx, data->cx, data->cy);
screen_write_stop(&ctx);
}
diff --git a/window-more.c b/window-more.c
index 25eeca4b..7a586386 100644
--- a/window-more.c
+++ b/window-more.c
@@ -1,4 +1,4 @@
-/* $Id: window-more.c,v 1.23 2009-01-10 19:35:40 nicm Exp $ */
+/* $Id: window-more.c,v 1.24 2009-01-11 23:31:46 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -22,17 +22,17 @@
#include "tmux.h"
-struct screen *window_more_init(struct window *);
-void window_more_free(struct window *);
-void window_more_resize(struct window *, u_int, u_int);
-void window_more_key(struct window *, struct client *, int);
+struct screen *window_more_init(struct window_pane *);
+void window_more_free(struct window_pane *);
+void window_more_resize(struct window_pane *, u_int, u_int);
+void window_more_key(struct window_pane *, struct client *, int);
-void window_more_redraw_screen(struct window *);
+void window_more_redraw_screen(struct window_pane *);
void window_more_write_line(
- struct window *, struct screen_write_ctx *, u_int);
+ struct window_pane *, struct screen_write_ctx *, u_int);
-void window_more_scroll_up(struct window *);
-void window_more_scroll_down(struct window *);
+void window_more_scroll_up(struct window_pane *);
+void window_more_scroll_down(struct window_pane *);
const struct window_mode window_more_mode = {
window_more_init,
@@ -50,9 +50,9 @@ struct window_more_mode_data {
};
void
-window_more_vadd(struct window *w, const char *fmt, va_list ap)
+window_more_vadd(struct window_pane *wp, const char *fmt, va_list ap)
{
- struct window_more_mode_data *data = w->modedata;
+ struct window_more_mode_data *data = wp->modedata;
struct screen *s = &data->screen;
struct screen_write_ctx ctx;
char *msg;
@@ -61,48 +61,48 @@ window_more_vadd(struct window *w, const char *fmt, va_list ap)
xvasprintf(&msg, fmt, ap);
ARRAY_ADD(&data->list, msg);
- screen_write_start_window(&ctx, w);
+ screen_write_start(&ctx, wp, NULL);
size = ARRAY_LENGTH(&data->list) - 1;
if (size >= data->top && size <= data->top + screen_size_y(s) - 1) {
- window_more_write_line(w, &ctx, size - data->top);
+ window_more_write_line(wp, &ctx, size - data->top);
if (size != data->top)
- window_more_write_line(w, &ctx, 0);
+ window_more_write_line(wp, &ctx, 0);
} else
- window_more_write_line(w, &ctx, 0);
+ window_more_write_line(wp, &ctx, 0);
screen_write_stop(&ctx);
}
void
-window_more_add(struct window *w, const char *fmt, ...)
+window_more_add(struct window_pane *wp, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
- window_more_vadd(w, fmt, ap);
+ window_more_vadd(wp, fmt, ap);
va_end(ap);
}
struct screen *
-window_more_init(struct window *w)
+window_more_init(struct window_pane *wp)
{
struct window_more_mode_data *data;
struct screen *s;
- w->modedata = data = xmalloc(sizeof *data);
+ wp->modedata = data = xmalloc(sizeof *data);
ARRAY_INIT(&data->list);
data->top = 0;
s = &data->screen;
- screen_init(s, screen_size_x(&w->base), screen_size_y(&w->base), 0);
+ screen_init(s, screen_size_x(&wp->base), screen_size_y(&wp->base), 0);
s->mode &= ~MODE_CURSOR;
return (s);
}
void
-window_more_free(struct window *w)
+window_more_free(struct window_pane *wp)
{
- struct window_more_mode_data *data = w->modedata;
+ struct window_more_mode_data *data = wp->modedata;
u_int i;
for (i = 0; i < ARRAY_LENGTH(&data->list); i++)
@@ -114,39 +114,39 @@ window_more_free(struct window *w)
}
void
-window_more_resize(struct window *w, u_int sx, u_int sy)
+window_more_resize(struct window_pane *wp, u_int sx, u_int sy)
{
- struct window_more_mode_data *data = w->modedata;
+ struct window_more_mode_data *data = wp->modedata;
struct screen *s = &data->screen;
screen_resize(s, sx, sy);
- window_more_redraw_screen(w);
+ window_more_redraw_screen(wp);
}
void
-window_more_key(struct window *w, unused struct client *c, int key)
+window_more_key(struct window_pane *wp, unused struct client *c, int key)
{
- struct window_more_mode_data *data = w->modedata;
+ struct window_more_mode_data *data = wp->modedata;
struct screen *s = &data->screen;
int table;
- table = options_get_number(&w->options, "mode-keys");
+ table = options_get_number(&wp->window->options, "mode-keys");
switch (mode_key_lookup(table, key)) {
case MODEKEY_QUIT:
- window_reset_mode(w);
+ window_pane_reset_mode(wp);
break;
case MODEKEY_UP:
- window_more_scroll_up(w);
+ window_more_scroll_up(wp);
break;
case MODEKEY_DOWN:
- window_more_scroll_down(w);
+ window_more_scroll_down(wp);
break;
case MODEKEY_PPAGE:
if (data->top < screen_size_y(s))
data->top = 0;
else
data->top -= screen_size_y(s);
- window_more_redraw_screen(w);
+ window_more_redraw_screen(wp);
break;
case MODEKEY_NONE:
if (key != ' ')
@@ -157,7 +157,7 @@ window_more_key(struct window *w, unused struct client *c, int key)
data->top = ARRAY_LENGTH(&data->list);
else
data->top += screen_size_y(s);
- window_more_redraw_screen(w);
+ window_more_redraw_screen(wp);
break;
default:
break;
@@ -165,9 +165,9 @@ window_more_key(struct window *w, unused struct client *c, int key)
}
void
-window_more_write_line(struct window *w, struct screen_write_ctx *ctx, u_int py)
+window_more_write_line(struct window_pane *wp, struct screen_write_ctx *ctx, u_int py)
{
- struct window_more_mode_data *data = w->modedata;
+ struct window_more_mode_data *data = wp->modedata;
struct screen *s = &data->screen;
struct grid_cell gc;
char *msg, hdr[32];
@@ -179,8 +179,8 @@ window_more_write_line(struct window *w, struct screen_write_ctx *ctx, u_int py)
size = xsnprintf(hdr, sizeof hdr,
"[%u/%u]", data->top, ARRAY_LENGTH(&data->list));
screen_write_cursormove(ctx, screen_size_x(s) - size, 0);
- gc.fg = options_get_number(&w->options, "mode-fg");
- gc.bg = options_get_number(&w->options, "mode-bg");
+ gc.fg = options_get_number(&wp->window->options, "mode-fg");
+ gc.bg = options_get_number(&wp->window->options, "mode-bg");
screen_write_puts(ctx, &gc, "%s", hdr);
memcpy(&gc, &grid_default_cell, sizeof gc);
} else
@@ -197,41 +197,41 @@ window_more_write_line(struct window *w, struct screen_write_ctx *ctx, u_int py)
}
void
-window_more_redraw_screen(struct window *w)
+window_more_redraw_screen(struct window_pane *wp)
{
- struct window_more_mode_data *data = w->modedata;
+ struct window_more_mode_data *data = wp->modedata;
struct screen *s = &data->screen;
struct screen_write_ctx ctx;
u_int i;
- screen_write_start_window(&ctx, w);
+ screen_write_start(&ctx, wp, NULL);
for (i = 0; i < screen_size_y(s); i++)
- window_more_write_line(w, &ctx, i);
+ window_more_write_line(wp, &ctx, i);
screen_write_stop(&ctx);
}
void
-window_more_scroll_up(struct window *w)
+window_more_scroll_up(struct window_pane *wp)
{
- struct window_more_mode_data *data = w->modedata;
+ struct window_more_mode_data *data = wp->modedata;
struct screen_write_ctx ctx;
if (data->top == 0)
return;
data->top--;
- screen_write_start_window(&ctx, w);
+ screen_write_start(&ctx, wp, NULL);
screen_write_cursormove(&ctx, 0, 0);
screen_write_insertline(&ctx, 1);
- window_more_write_line(w, &ctx, 0);
- window_more_write_line(w, &ctx, 1);
+ window_more_write_line(wp, &ctx, 0);
+ window_more_write_line(wp, &ctx, 1);
screen_write_stop(&ctx);
}
void
-window_more_scroll_down(struct window *w)
+window_more_scroll_down(struct window_pane *wp)
{
- struct window_more_mode_data *data = w->modedata;
+ struct window_more_mode_data *data = wp->modedata;
struct screen *s = &data->screen;
struct screen_write_ctx ctx;
@@ -239,10 +239,10 @@ window_more_scroll_down(struct window *w)
return;
data->top++;
- screen_write_start_window(&ctx, w);
+ screen_write_start(&ctx, wp, NULL);
screen_write_cursormove(&ctx, 0, 0);
screen_write_deleteline(&ctx, 1);
- window_more_write_line(w, &ctx, screen_size_y(s) - 1);
- window_more_write_line(w, &ctx, 0);
+ window_more_write_line(wp, &ctx, screen_size_y(s) - 1);
+ window_more_write_line(wp, &ctx, 0);
screen_write_stop(&ctx);
}
diff --git a/window-scroll.c b/window-scroll.c
index 7d49036c..d3f7d244 100644
--- a/window-scroll.c
+++ b/window-scroll.c
@@ -1,4 +1,4 @@
-/* $Id: window-scroll.c,v 1.26 2009-01-10 19:35:40 nicm Exp $ */
+/* $Id: window-scroll.c,v 1.27 2009-01-11 23:31:46 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -22,21 +22,21 @@
#include "tmux.h"
-struct screen *window_scroll_init(struct window *);
-void window_scroll_free(struct window *);
-void window_scroll_resize(struct window *, u_int, u_int);
-void window_scroll_key(struct window *, struct client *, int);
+struct screen *window_scroll_init(struct window_pane *);
+void window_scroll_free(struct window_pane *);
+void window_scroll_resize(struct window_pane *, u_int, u_int);
+void window_scroll_key(struct window_pane *, struct client *, int);
-void window_scroll_redraw_screen(struct window *);
+void window_scroll_redraw_screen(struct window_pane *);
void window_scroll_write_line(
- struct window *, struct screen_write_ctx *, u_int);
+ struct window_pane *, struct screen_write_ctx *, u_int);
void window_scroll_write_column(
- struct window *, struct screen_write_ctx *, u_int);
+ struct window_pane *, struct screen_write_ctx *, u_int);
-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 *);
+void window_scroll_scroll_up(struct window_pane *);
+void window_scroll_scroll_down(struct window_pane *);
+void window_scroll_scroll_left(struct window_pane *);
+void window_scroll_scroll_right(struct window_pane *);
const struct window_mode window_scroll_mode = {
window_scroll_init,
@@ -54,90 +54,90 @@ struct window_scroll_mode_data {
};
struct screen *
-window_scroll_init(struct window *w)
+window_scroll_init(struct window_pane *wp)
{
struct window_scroll_mode_data *data;
struct screen *s;
struct screen_write_ctx ctx;
u_int i;
- w->modedata = data = xmalloc(sizeof *data);
+ wp->modedata = data = xmalloc(sizeof *data);
data->ox = 0;
data->oy = 0;
s = &data->screen;
- screen_init(s, screen_size_x(&w->base), screen_size_y(&w->base), 0);
+ screen_init(s, screen_size_x(&wp->base), screen_size_y(&wp->base), 0);
s->mode &= ~MODE_CURSOR;
- screen_write_start(&ctx, s, NULL, NULL);
+ screen_write_start(&ctx, NULL, s);
for (i = 0; i < screen_size_y(s); i++)
- window_scroll_write_line(w, &ctx, i);
+ window_scroll_write_line(wp, &ctx, i);
screen_write_stop(&ctx);
return (s);
}
void
-window_scroll_free(struct window *w)
+window_scroll_free(struct window_pane *wp)
{
- struct window_scroll_mode_data *data = w->modedata;
+ struct window_scroll_mode_data *data = wp->modedata;
screen_free(&data->screen);
xfree(data);
}
void
-window_scroll_resize(struct window *w, u_int sx, u_int sy)
+window_scroll_resize(struct window_pane *wp, u_int sx, u_int sy)
{
- struct window_scroll_mode_data *data = w->modedata;
+ struct window_scroll_mode_data *data = wp->modedata;
struct screen *s = &data->screen;
struct screen_write_ctx ctx;
u_int i;
screen_resize(s, sx, sy);
- screen_write_start(&ctx, s, NULL, NULL);
+ screen_write_start(&ctx, NULL, s);
for (i = 0; i < screen_size_y(s); i++)
- window_scroll_write_line(w, &ctx, i);
+ window_scroll_write_line(wp, &ctx, i);
screen_write_stop(&ctx);
}
void
-window_scroll_key(struct window *w, unused struct client *c, int key)
+window_scroll_key(struct window_pane *wp, unused struct client *c, int key)
{
- struct window_scroll_mode_data *data = w->modedata;
+ struct window_scroll_mode_data *data = wp->modedata;
struct screen *s = &data->screen;
int table;
- table = options_get_number(&w->options, "mode-keys");
+ table = options_get_number(&wp->window->options, "mode-keys");
switch (mode_key_lookup(table, key)) {
case MODEKEY_QUIT:
- window_reset_mode(w);
+ window_pane_reset_mode(wp);
break;
case MODEKEY_LEFT:
- window_scroll_scroll_left(w);
+ window_scroll_scroll_left(wp);
break;
case MODEKEY_RIGHT:
- window_scroll_scroll_right(w);
+ window_scroll_scroll_right(wp);
break;
case MODEKEY_UP:
- window_scroll_scroll_up(w);
+ window_scroll_scroll_up(wp);
break;
case MODEKEY_DOWN:
- window_scroll_scroll_down(w);
+ window_scroll_scroll_down(wp);
break;
case MODEKEY_PPAGE:
- if (data->oy + screen_size_y(s) > screen_hsize(&w->base))
- data->oy = screen_hsize(&w->base);
+ if (data->oy + screen_size_y(s) > screen_hsize(&wp->base))
+ data->oy = screen_hsize(&wp->base);
else
data->oy += screen_size_y(s);
- window_scroll_redraw_screen(w);
+ window_scroll_redraw_screen(wp);
break;
case MODEKEY_NPAGE:
if (data->oy < screen_size_y(s))
data->oy = 0;
else
data->oy -= screen_size_y(s);
- window_scroll_redraw_screen(w);
+ window_scroll_redraw_screen(wp);
break;
default:
break;
@@ -146,9 +146,9 @@ window_scroll_key(struct window *w, unused struct client *c, int key)
void
window_scroll_write_line(
- struct window *w, struct screen_write_ctx *ctx, u_int py)
+ struct window_pane *wp, struct screen_write_ctx *ctx, u_int py)
{
- struct window_scroll_mode_data *data = w->modedata;
+ struct window_scroll_mode_data *data = wp->modedata;
struct screen *s = &data->screen;
struct grid_cell gc;
char hdr[32];
@@ -157,9 +157,9 @@ window_scroll_write_line(
if (py == 0) {
memcpy(&gc, &grid_default_cell, sizeof gc);
size = xsnprintf(hdr, sizeof hdr,
- "[%u,%u/%u]", data->ox, data->oy, screen_hsize(&w->base));
- gc.fg = options_get_number(&w->options, "mode-fg");
- gc.bg = options_get_number(&w->options, "mode-bg");
+ "[%u,%u/%u]", data->ox, data->oy, screen_hsize(&wp->base));
+ gc.fg = options_get_number(&wp->window->options, "mode-fg");
+ gc.bg = options_get_number(&wp->window->options, "mode-bg");
screen_write_cursormove(ctx, screen_size_x(s) - size, 0);
screen_write_puts(ctx, &gc, "%s", hdr);
memcpy(&gc, &grid_default_cell, sizeof gc);
@@ -167,58 +167,58 @@ window_scroll_write_line(
size = 0;
screen_write_cursormove(ctx, 0, py);
- screen_write_copy(ctx, &w->base, data->ox, (screen_hsize(&w->base) -
+ screen_write_copy(ctx, &wp->base, data->ox, (screen_hsize(&wp->base) -
data->oy) + py, screen_size_x(s) - size, 1);
}
void
window_scroll_write_column(
- struct window *w, struct screen_write_ctx *ctx, u_int px)
+ struct window_pane *wp, struct screen_write_ctx *ctx, u_int px)
{
- struct window_scroll_mode_data *data = w->modedata;
+ struct window_scroll_mode_data *data = wp->modedata;
struct screen *s = &data->screen;
screen_write_cursormove(ctx, px, 0);
- screen_write_copy(ctx, &w->base, data->ox + px,
- screen_hsize(&w->base) - data->oy, 1, screen_size_y(s));
+ screen_write_copy(ctx, &wp->base, data->ox + px,
+ screen_hsize(&wp->base) - data->oy, 1, screen_size_y(s));
}
void
-window_scroll_redraw_screen(struct window *w)
+window_scroll_redraw_screen(struct window_pane *wp)
{
- struct window_scroll_mode_data *data = w->modedata;
+ struct window_scroll_mode_data *data = wp->modedata;
struct screen *s = &data->screen;
struct screen_write_ctx ctx;
u_int i;
- screen_write_start_window(&ctx, w);
+ screen_write_start(&ctx, wp, NULL);
for (i = 0; i < screen_size_y(s); i++)
- window_scroll_write_line(w, &ctx, i);
+ window_scroll_write_line(wp, &ctx, i);
screen_write_stop(&ctx);
}
void
-window_scroll_scroll_up(struct window *w)
+window_scroll_scroll_up(struct window_pane *wp)
{
- struct window_scroll_mode_data *data = w->modedata;
+ struct window_scroll_mode_data *data = wp->modedata;
struct screen_write_ctx ctx;
- if (data->oy >= screen_hsize(&w->base))
+ if (data->oy >= screen_hsize(&wp->base))
return;
data->oy++;
- screen_write_start_window(&ctx, w);
+ screen_write_start(&ctx, wp, NULL);
screen_write_cursormove(&ctx, 0, 0);
screen_write_insertline(&ctx, 1);
- window_scroll_write_line(w, &ctx, 0);
- window_scroll_write_line(w, &ctx, 1);
+ window_scroll_write_line(wp, &ctx, 0);
+ window_scroll_write_line(wp, &ctx, 1);
screen_write_stop(&ctx);
}
void
-window_scroll_scroll_down(struct window *w)
+window_scroll_scroll_down(struct window_pane *wp)
{
- struct window_scroll_mode_data *data = w->modedata;
+ struct window_scroll_mode_data *data = wp->modedata;
struct screen *s = &data->screen;
struct screen_write_ctx ctx;
@@ -226,18 +226,18 @@ window_scroll_scroll_down(struct window *w)
return;
data->oy--;
- screen_write_start_window(&ctx, w);
+ screen_write_start(&ctx, wp, NULL);
screen_write_cursormove(&ctx, 0, 0);
screen_write_deleteline(&ctx, 1);
- window_scroll_write_line(w, &ctx, screen_size_y(s) - 1);
- window_scroll_write_line(w, &ctx, 0);
+ window_scroll_write_line(wp, &ctx, screen_size_y(s) - 1);
+ window_scroll_write_line(wp, &ctx, 0);
screen_write_stop(&ctx);
}
void
-window_scroll_scroll_right(struct window *w)
+window_scroll_scroll_right(struct window_pane *wp)
{
- struct window_scroll_mode_data *data = w->modedata;
+ struct window_scroll_mode_data *data = wp->modedata;
struct screen *s = &data->screen;
struct screen_write_ctx ctx;
u_int i;
@@ -246,20 +246,20 @@ window_scroll_scroll_right(struct window *w)
return;
data->ox++;
- screen_write_start_window(&ctx, w);
+ screen_write_start(&ctx, wp, NULL);
for (i = 1; i < screen_size_y(s); i++) {
screen_write_cursormove(&ctx, 0, i);
screen_write_deletecharacter(&ctx, 1);
}
- window_scroll_write_column(w, &ctx, screen_size_x(s) - 1);
- window_scroll_write_line(w, &ctx, 0);
+ window_scroll_write_column(wp, &ctx, screen_size_x(s) - 1);
+ window_scroll_write_line(wp, &ctx, 0);
screen_write_stop(&ctx);
}
void
-window_scroll_scroll_left(struct window *w)
+window_scroll_scroll_left(struct window_pane *wp)
{
- struct window_scroll_mode_data *data = w->modedata;
+ struct window_scroll_mode_data *data = wp->modedata;
struct screen *s = &data->screen;
struct screen_write_ctx ctx;
u_int i;
@@ -268,12 +268,12 @@ window_scroll_scroll_left(struct window *w)
return;
data->ox--;
- screen_write_start_window(&ctx, w);
+ screen_write_start(&ctx, wp, NULL);
for (i = 1; i < screen_size_y(s); i++) {
screen_write_cursormove(&ctx, 0, i);
screen_write_insertcharacter(&ctx, 1);
}
- window_scroll_write_column(w, &ctx, 0);
- window_scroll_write_line(w, &ctx, 0);
+ window_scroll_write_column(wp, &ctx, 0);
+ window_scroll_write_line(wp, &ctx, 0);
screen_write_stop(&ctx);
}
diff --git a/window.c b/window.c
index 8d4bd496..9f7cdf43 100644
--- a/window.c
+++ b/window.c
@@ -1,4 +1,4 @@
-/* $Id: window.c,v 1.54 2009-01-10 19:37:35 nicm Exp $ */
+/* $Id: window.c,v 1.55 2009-01-11 23:31:46 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -46,16 +46,17 @@
#include "tmux.h"
/*
- * Each window is attached to a pty. This file contains code to handle them.
+ * Each window is attached to one or two panes, each of which is a pty. This
+ * file contains code to handle them.
*
- * A window has two buffers attached, these are filled and emptied by the main
+ * A pane has two buffers attached, these are filled and emptied by the main
* server poll loop. Output data is received from pty's in screen format,
* translated and returned as a series of escape sequences and strings via
* input_parse (in input.c). Input data is received as key codes and written
* directly via input_key.
*
- * Each window also has a "virtual" screen (screen.c) which contains the
- * current state and is redisplayed when the window is reattached to a client.
+ * Each pane also has a "virtual" screen (screen.c) which contains the current
+ * state and is redisplayed when the window is reattached to a client.
*
* Windows are stored directly on a global array and wrapped in any number of
* winlink structs to be linked onto local session RB trees. A reference count
@@ -211,20 +212,15 @@ window_create(const char *name, const char *cmd,
char *ptr, *copy;
w = xmalloc(sizeof *w);
- w->cmd = NULL;
- w->cwd = NULL;
-
- w->fd = -1;
- w->in = buffer_create(BUFSIZ);
- w->out = buffer_create(BUFSIZ);
-
- w->mode = NULL;
w->flags = 0;
+ w->panes[0] = window_pane_create(w, sx, sy, hlimit);
+ w->panes[1] = NULL;
+
+ w->sx = sx;
+ w->sy = sy;
- screen_init(&w->base, sx, sy, hlimit);
- w->screen = &w->base;
+ w->active = w->panes[0];
- input_init(w);
options_init(&w->options, &global_window_options);
if (name == NULL) {
@@ -253,152 +249,225 @@ window_create(const char *name, const char *cmd,
ARRAY_ADD(&windows, w);
w->references = 0;
- if (window_spawn(w, cmd, cwd, envp) != 0) {
+ if (window_pane_spawn(w->active, cmd, cwd, envp) != 0) {
window_destroy(w);
return (NULL);
}
return (w);
}
+void
+window_destroy(struct window *w)
+{
+ u_int i;
+
+ for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
+ if (ARRAY_ITEM(&windows, i) == w)
+ break;
+ }
+ ARRAY_REMOVE(&windows, i);
+
+ options_free(&w->options);
+
+ window_pane_destroy(w->panes[0]);
+ if (w->panes[1] != NULL)
+ window_pane_destroy(w->panes[1]);
+
+ xfree(w->name);
+ xfree(w);
+}
+
+int
+window_resize(struct window *w, u_int sx, u_int sy)
+{
+ if (w->panes[1] != NULL) {
+ window_pane_resize(w->panes[0], sx, sy / 2 - 1);
+ window_pane_resize(w->panes[1], sx, sy - (sy / 2));
+ } else
+ window_pane_resize(w->panes[0], sx, sy);
+
+ w->sx = sx;
+ w->sy = sy;
+
+ return (0);
+}
+
int
-window_spawn(
- struct window *w, const char *cmd, const char *cwd, const char **envp)
+window_remove_pane(struct window *w, int pane)
+{
+ if (w->panes[1] != NULL) {
+ window_pane_destroy(w->panes[pane]);
+ w->panes[pane] = NULL;
+ if (pane == 0) {
+ w->panes[0] = w->panes[1];
+ w->panes[1] = NULL;
+ }
+ window_resize(w, w->sx, w->sy);
+ w->active = w->panes[0];
+ return (0);
+ }
+ return (1);
+}
+
+struct window_pane *
+window_pane_create(struct window *w, u_int sx, u_int sy, u_int hlimit)
+{
+ struct window_pane *wp;
+
+ wp = xmalloc(sizeof *wp);
+ wp->window = w;
+
+ wp->cmd = NULL;
+ wp->cwd = NULL;
+
+ wp->fd = -1;
+ wp->in = buffer_create(BUFSIZ);
+ wp->out = buffer_create(BUFSIZ);
+
+ wp->mode = NULL;
+
+ screen_init(&wp->base, sx, sy, hlimit);
+ wp->screen = &wp->base;
+
+ input_init(wp);
+
+ return (wp);
+}
+
+void
+window_pane_destroy(struct window_pane *wp)
+{
+ if (wp->fd != -1)
+ close(wp->fd);
+
+ input_free(wp);
+
+ window_pane_reset_mode(wp);
+ screen_free(&wp->base);
+
+ buffer_destroy(wp->in);
+ buffer_destroy(wp->out);
+
+ if (wp->cwd != NULL)
+ xfree(wp->cwd);
+ if (wp->cmd != NULL)
+ xfree(wp->cmd);
+ xfree(wp);
+}
+
+int
+window_pane_spawn(struct window_pane *wp,
+ const char *cmd, const char *cwd, const char **envp)
{
struct winsize ws;
int mode;
const char **envq;
- if (w->fd != -1)
- close(w->fd);
- if (w->cmd != NULL)
- xfree(w->cmd);
- w->cmd = xstrdup(cmd);
- w->cwd = xstrdup(cwd);
+ if (wp->fd != -1)
+ close(wp->fd);
+ if (cmd != NULL) {
+ if (wp->cmd != NULL)
+ xfree(wp->cmd);
+ wp->cmd = xstrdup(cmd);
+ }
+ if (cwd != NULL) {
+ if (wp->cwd != NULL)
+ xfree(wp->cwd);
+ wp->cwd = xstrdup(cwd);
+ }
memset(&ws, 0, sizeof ws);
- ws.ws_col = screen_size_x(&w->base);
- ws.ws_row = screen_size_y(&w->base);
+ ws.ws_col = screen_size_x(&wp->base);
+ ws.ws_row = screen_size_y(&wp->base);
- switch (forkpty(&w->fd, NULL, NULL, &ws)) {
+ switch (forkpty(&wp->fd, NULL, NULL, &ws)) {
case -1:
return (1);
case 0:
- if (chdir(cwd) != 0)
+ if (chdir(wp->cwd) != 0)
chdir("/");
for (envq = envp; *envq != NULL; envq++) {
if (putenv(*envq) != 0)
fatal("putenv failed");
}
sigreset();
- log_debug("new child: cmd=%s pid=%ld", w->cmd, (long) getpid());
log_close();
- execl(_PATH_BSHELL, "sh", "-c", w->cmd, (char *) NULL);
+ execl(_PATH_BSHELL, "sh", "-c", wp->cmd, (char *) NULL);
fatal("execl failed");
}
- if ((mode = fcntl(w->fd, F_GETFL)) == -1)
+ if ((mode = fcntl(wp->fd, F_GETFL)) == -1)
fatal("fcntl failed");
- if (fcntl(w->fd, F_SETFL, mode|O_NONBLOCK) == -1)
+ if (fcntl(wp->fd, F_SETFL, mode|O_NONBLOCK) == -1)
fatal("fcntl failed");
- if (fcntl(w->fd, F_SETFD, FD_CLOEXEC) == -1)
+ if (fcntl(wp->fd, F_SETFD, FD_CLOEXEC) == -1)
fatal("fcntl failed");
return (0);
}
-void
-window_destroy(struct window *w)
-{
- u_int i;
-
- for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
- if (ARRAY_ITEM(&windows, i) == w)
- break;
- }
- ARRAY_REMOVE(&windows, i);
-
- if (w->fd != -1)
- close(w->fd);
-
- input_free(w);
-
- window_reset_mode(w);
- options_free(&w->options);
- screen_free(&w->base);
-
- buffer_destroy(w->in);
- buffer_destroy(w->out);
-
- if (w->cwd != NULL)
- xfree(w->cwd);
- if (w->cmd != NULL)
- xfree(w->cmd);
- xfree(w->name);
- xfree(w);
-}
-
int
-window_resize(struct window *w, u_int sx, u_int sy)
+window_pane_resize(struct window_pane *wp, u_int sx, u_int sy)
{
struct winsize ws;
- if (sx == screen_size_x(&w->base) && sy == screen_size_y(&w->base))
+ if (sx == screen_size_x(&wp->base) && sy == screen_size_y(&wp->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(&wp->base, sx, sy);
+ if (wp->mode != NULL)
+ wp->mode->resize(wp, sx, sy);
- if (w->fd != -1 && ioctl(w->fd, TIOCSWINSZ, &ws) == -1)
+ if (wp->fd != -1 && ioctl(wp->fd, TIOCSWINSZ, &ws) == -1)
fatal("ioctl failed");
return (0);
}
int
-window_set_mode(struct window *w, const struct window_mode *mode)
+window_pane_set_mode(struct window_pane *wp, const struct window_mode *mode)
{
struct screen *s;
- if (w->mode != NULL || w->mode == mode)
+ if (wp->mode != NULL || wp->mode == mode)
return (1);
- w->mode = mode;
+ wp->mode = mode;
- if ((s = w->mode->init(w)) != NULL)
- w->screen = s;
- server_redraw_window(w);
+ if ((s = wp->mode->init(wp)) != NULL)
+ wp->screen = s;
+ server_redraw_window(wp->window);
return (0);
}
void
-window_reset_mode(struct window *w)
+window_pane_reset_mode(struct window_pane *wp)
{
- if (w->mode == NULL)
+ if (wp->mode == NULL)
return;
- w->mode->free(w);
- w->mode = NULL;
+ wp->mode->free(wp);
+ wp->mode = NULL;
- w->screen = &w->base;
- server_redraw_window(w);
+ wp->screen = &wp->base;
+ server_redraw_window(wp->window);
}
void
-window_parse(struct window *w)
+window_pane_parse(struct window_pane *wp)
{
- input_parse(w);
+ input_parse(wp);
}
void
-window_key(struct window *w, struct client *c, int key)
+window_pane_key(struct window_pane *wp, struct client *c, int key)
{
- if (w->mode != NULL)
- w->mode->key(w, c, key);
+ if (wp->mode != NULL)
+ wp->mode->key(wp, c, key);
else
- input_key(w, key);
+ input_key(wp, key);
}