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).

This commit is contained in:
Nicholas Marriott 2009-01-11 23:31:46 +00:00
parent d78bc5dfc4
commit 162bacdcd9
32 changed files with 1608 additions and 1305 deletions

17
CHANGES
View File

@ -1,5 +1,20 @@
11 January 2009 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. * save-buffer command, from Tiago Cunha.
10 January 2009 10 January 2009
@ -859,7 +874,7 @@
(including mutt, emacs). No status bar yet and no key remapping or other (including mutt, emacs). No status bar yet and no key remapping or other
customisation. 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: showw utf UTF fulvio ciriaco joshe OSC APC gettime abc DEF OA clr
LocalWords: rivo nurges lscm Erdely eol smysession mysession ek dstname RB LocalWords: rivo nurges lscm Erdely eol smysession mysession ek dstname RB

View File

@ -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 .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-list-commands.c cmd-move-window.c cmd-select-prompt.c \
cmd-respawn-window.c cmd-source-file.c cmd-server-info.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-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 \ 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 \ options.c options-cmd.c paste.c colour.c utf8.c clock.c \
tty.c tty-term.c tty-keys.c tty-write.c tty.c tty-term.c tty-keys.c tty-write.c

View File

@ -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 .SUFFIXES: .c .o .y .h
.PHONY: clean update-index.html upload-index.html .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-list-commands.c cmd-move-window.c cmd-select-prompt.c \
cmd-respawn-window.c cmd-source-file.c cmd-server-info.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-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 \ 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 \ options.c options-cmd.c paste.c colour.c utf8.c clock.c \
tty.c tty-term.c tty-keys.c tty-write.c tty.c tty-term.c tty-keys.c tty-write.c

21
TODO
View File

@ -13,7 +13,7 @@
- status-fg/status-bg should be able to set attributes: bold, etc - status-fg/status-bg should be able to set attributes: bold, etc
- refer to windows by name etc (duplicates? fnmatch?) - refer to windows by name etc (duplicates? fnmatch?)
- commands: - 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 command to purge window history
extend list-clients to list clients attached to a session (-a for all?) extend list-clients to list clients attached to a session (-a for all?)
bring back detach-session to detach all clients on a session? bring back detach-session to detach all clients on a session?
@ -42,7 +42,7 @@
session not being watched? session not being watched?
- tidy up window modes - tidy up window modes
- problems with force-width when wrapping line in emacs? - 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? to support vi. is there something could use for this? editline(3)/readline?
- many more info() displays for various things - many more info() displays for various things
- vi half page scroll - 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 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/ maybe)? a single flag is insufficient as can't then tell when to /stop/
unwrapping unwrapping
- OPTIONS section in man page with description of new option handling - document OPTIONS section in man page with description of new option handling
- update set/setw in man page with -g and -u flags - document update set/setw in man page with -g and -u flags
- more # commands in status-left,right eg #H for hostname. others? - more # commands in status-left,right eg #H for hostname. others?
- input.c is too complicated. simplify? - input.c is too complicated. simplify?
- try change from pass-though model to redraw model (use updated screen - try change from pass-though model to redraw model (use updated screen
@ -66,7 +66,9 @@
- document clock-mode - document clock-mode
- document password/locking commands - document password/locking commands
- document lock-after-time - 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 - 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?? - 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 < NicM> tmux new then eg tmux linkw -s0:0
17:06 < simmel> NicM link-window? 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> or kills it if it is only linked to one
17:09 < NicM> unlinkw only unlinks it 17:09 < NicM> unlinkw only unlinks it
- clone session command - 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

View File

@ -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> * 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) if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return; return;
window_set_mode(wl->window, &window_clock_mode); window_pane_set_mode(wl->window->active, &window_clock_mode);
if (ctx->cmdclient != NULL) if (ctx->cmdclient != NULL)
server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0); server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0);

View File

@ -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> * 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) if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return; return;
window_set_mode(wl->window, &window_copy_mode); window_pane_set_mode(wl->window->active, &window_copy_mode);
if (ctx->cmdclient != NULL) if (ctx->cmdclient != NULL)
server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0); server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0);

View File

@ -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> * 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 session *s;
struct winlink *wl; struct winlink *wl;
struct window *w; struct window *w;
struct window_pane *wp;
struct grid_data *gd; struct grid_data *gd;
u_int i; u_int i, j;
unsigned long long size; unsigned long long size;
const char *name; const char *name;
@ -58,23 +59,31 @@ cmd_list_windows_exec(struct cmd *self, struct cmd_ctx *ctx)
RB_FOREACH(wl, winlinks, &s->windows) { RB_FOREACH(wl, winlinks, &s->windows) {
w = wl->window; 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, ctx->print(ctx,
"%d: %s \"%s\" (%s) [%ux%u] [history %u/%u, %llu bytes]", "%d: %s [%ux%u]", wl->idx, w->name, w->sx, w->sy);
wl->idx, w->name, w->base.title, name, for (i = 0; i < 2; i++) {
screen_size_x(&w->base), screen_size_y(&w->base), wp = w->panes[i];
gd->hsize, gd->hlimit, size); 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) if (ctx->cmdclient != NULL)

View File

@ -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> * 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 cmd_buffer_data *data = self->data;
struct winlink *wl; struct winlink *wl;
struct window *w;
struct session *s; struct session *s;
struct paste_buffer *pb; struct paste_buffer *pb;
if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL) if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL)
return; return;
w = wl->window;
if (data->buffer == -1) if (data->buffer == -1)
pb = paste_get_top(&s->buffers); pb = paste_get_top(&s->buffers);
@ -60,7 +62,7 @@ cmd_paste_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
} }
if (pb != NULL) 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. */ /* Delete the buffer if -d. */
if (data->flags & CMD_DFLAG) { if (data->flags & CMD_DFLAG) {

View File

@ -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> * 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 cmd_target_data *data = self->data;
struct winlink *wl; struct winlink *wl;
struct window *w;
struct session *s; struct session *s;
const char *env[] = { const char *env[] = {
NULL /* TMUX= */, "TERM=screen", NULL 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) if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL)
return; 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); ctx->error(ctx, "window still active: %s:%d", s->name, wl->idx);
return; 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); xsnprintf(buf, sizeof buf, "TMUX=%ld,%u", (long) getpid(), i);
env[0] = buf; 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); ctx->error(ctx, "respawn failed: %s:%d", s->name, wl->idx);
return; return;
} }
screen_reinit(&wl->window->base); screen_reinit(&w->panes[0]->base);
recalculate_sizes(); recalculate_sizes();
server_redraw_window(wl->window); server_redraw_window(w);
if (ctx->cmdclient != NULL) if (ctx->cmdclient != NULL)
server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0); server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0);

View File

@ -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> * 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) if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return; return;
window_set_mode(wl->window, &window_scroll_mode); window_pane_set_mode(wl->window->active, &window_scroll_mode);
if (ctx->cmdclient != NULL) if (ctx->cmdclient != NULL)
server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0); server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0);

View File

@ -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> * 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) if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return; return;
for (i = 0; i < data->nkeys; i++) for (i = 0; i < data->nkeys; i++) {
window_key(wl->window, ctx->curclient, data->keys[i]); window_pane_key(
wl->window->active, ctx->curclient, data->keys[i]);
}
if (ctx->cmdclient != NULL) if (ctx->cmdclient != NULL)
server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0); server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0);

View File

@ -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> * 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; return;
key = options_get_number(&s->options, "prefix"); 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) if (ctx->cmdclient != NULL)
server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0); server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0);

211
cmd-split-window.c Normal file
View File

@ -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);
}

61
cmd-switch-pane.c Normal file
View File

@ -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);
}

4
cmd.c
View File

@ -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> * 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_options_entry,
&cmd_show_window_options_entry, &cmd_show_window_options_entry,
&cmd_source_file_entry, &cmd_source_file_entry,
&cmd_split_window_entry,
&cmd_start_server_entry, &cmd_start_server_entry,
&cmd_swap_window_entry, &cmd_swap_window_entry,
&cmd_switch_client_entry, &cmd_switch_client_entry,
&cmd_switch_pane_entry,
&cmd_unbind_key_entry, &cmd_unbind_key_entry,
&cmd_unlink_window_entry, &cmd_unlink_window_entry,
NULL NULL

View File

@ -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> * 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. */ /* Translate a key code from client into an output key sequence. */
void void
input_key(struct window *w, int key) input_key(struct window_pane *wp, int key)
{ {
struct input_key_ent *ike; struct input_key_ent *ike;
u_int i; u_int i;
@ -115,8 +115,8 @@ input_key(struct window *w, int key)
if (key != KEYC_NONE && KEYC_REMOVEESC(key) < KEYC_OFFSET) { if (key != KEYC_NONE && KEYC_REMOVEESC(key) < KEYC_OFFSET) {
if (KEYC_ISESC(key)) if (KEYC_ISESC(key))
buffer_write8(w->out, '\033'); buffer_write8(wp->out, '\033');
buffer_write8(w->out, (uint8_t) KEYC_REMOVEESC(key)); buffer_write8(wp->out, (uint8_t) KEYC_REMOVEESC(key));
return; return;
} }
@ -124,10 +124,10 @@ input_key(struct window *w, int key)
ike = &input_keys[i]; ike = &input_keys[i];
if ((ike->flags & INPUTKEY_KEYPAD) && if ((ike->flags & INPUTKEY_KEYPAD) &&
!(w->screen->mode & MODE_KKEYPAD)) !(wp->screen->mode & MODE_KKEYPAD))
continue; continue;
if ((ike->flags & INPUTKEY_CURSOR) && if ((ike->flags & INPUTKEY_CURSOR) &&
!(w->screen->mode & MODE_KCURSOR)) !(wp->screen->mode & MODE_KCURSOR))
continue; continue;
if (ike->flags & INPUTKEY_MODIFIER) { 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); log_debug2("found key 0x%x: \"%s\"", key, ike->data);
if (ike->flags & INPUTKEY_XTERM && 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. */ /* In xterm keys mode, append modifier argument. */
ch = '\0'; ch = '\0';
if (KEYC_ISSFT(key) && KEYC_ISESC(key) && KEYC_ISCTL(key)) if (KEYC_ISSFT(key) && KEYC_ISESC(key) && KEYC_ISCTL(key))
@ -169,12 +169,12 @@ input_key(struct window *w, int key)
ch = '2'; ch = '2';
if (ch != '\0') { if (ch != '\0') {
log_debug("output argument is: %c", ch); log_debug("output argument is: %c", ch);
buffer_write(w->out, ike->data, dlen - 1); buffer_write(wp->out, ike->data, dlen - 1);
buffer_write8(w->out, ';'); buffer_write8(wp->out, ';');
buffer_write8(w->out, ch); buffer_write8(wp->out, ch);
buffer_write8(w->out, ike->data[dlen - 1]); buffer_write8(wp->out, ike->data[dlen - 1]);
} else } else
buffer_write(w->out, ike->data, dlen); buffer_write(wp->out, ike->data, dlen);
return; return;
} }
if (ike->flags & INPUTKEY_MODIFIER) { if (ike->flags & INPUTKEY_MODIFIER) {
@ -183,15 +183,15 @@ input_key(struct window *w, int key)
* control (shift not supported). * control (shift not supported).
*/ */
if (KEYC_ISESC(key)) if (KEYC_ISESC(key))
buffer_write8(w->out, '\033'); buffer_write8(wp->out, '\033');
if (!KEYC_ISCTL(key)) { if (!KEYC_ISCTL(key)) {
buffer_write(w->out, ike->data, dlen); buffer_write(wp->out, ike->data, dlen);
return; return;
} }
buffer_write(w->out, ike->data, dlen - 1); buffer_write(wp->out, ike->data, dlen - 1);
buffer_write8(w->out, ike->data[dlen - 1] ^ 0x20); buffer_write8(wp->out, ike->data[dlen - 1] ^ 0x20);
return; return;
} }
buffer_write(w->out, ike->data, dlen); buffer_write(wp->out, ike->data, dlen);
} }

54
input.c
View File

@ -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> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -217,9 +217,9 @@ input_state(struct input_ctx *ictx, void *state)
} }
void 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); ARRAY_INIT(&ictx->args);
@ -236,38 +236,38 @@ input_init(struct window *w)
} }
void void
input_free(struct window *w) input_free(struct window_pane *wp)
{ {
if (w->ictx.string_buf != NULL) if (wp->ictx.string_buf != NULL)
xfree(w->ictx.string_buf); xfree(wp->ictx.string_buf);
ARRAY_FREE(&w->ictx.args); ARRAY_FREE(&wp->ictx.args);
} }
void 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; u_char ch;
if (BUFFER_USED(w->in) == 0) if (BUFFER_USED(wp->in) == 0)
return; return;
ictx->buf = BUFFER_OUT(w->in); ictx->buf = BUFFER_OUT(wp->in);
ictx->len = BUFFER_USED(w->in); ictx->len = BUFFER_USED(wp->in);
ictx->off = 0; ictx->off = 0;
ictx->w = w; ictx->wp = wp;
log_debug2("entry; buffer=%zu", ictx->len); log_debug2("entry; buffer=%zu", ictx->len);
if (w->mode == NULL) if (wp->mode == NULL)
screen_write_start(&ictx->ctx, &w->base, tty_write_window, w); screen_write_start(&ictx->ctx, wp, &wp->base);
else else
screen_write_start(&ictx->ctx, &w->base, NULL, NULL); screen_write_start(&ictx->ctx, NULL, &wp->base);
if (ictx->off != ictx->len) if (ictx->off != ictx->len)
w->flags |= WINDOW_ACTIVITY; wp->window->flags |= WINDOW_ACTIVITY;
while (ictx->off < ictx->len) { while (ictx->off < ictx->len) {
ch = ictx->buf[ictx->off++]; ch = ictx->buf[ictx->off++];
ictx->state(ch, ictx); ictx->state(ch, ictx);
@ -275,7 +275,7 @@ input_parse(struct window *w)
screen_write_stop(&ictx->ctx); screen_write_stop(&ictx->ctx);
buffer_remove(w->in, ictx->len); buffer_remove(wp->in, ictx->len);
} }
void void
@ -499,7 +499,7 @@ input_state_string_escape(u_char ch, struct input_ctx *ictx)
return; return;
} }
screen_set_title(ictx->ctx.s, s + 2); screen_set_title(ictx->ctx.s, s + 2);
server_status_window(ictx->w); server_status_window(ictx->wp->window);
xfree(s); xfree(s);
break; break;
case STRING_APPLICATION: case STRING_APPLICATION:
@ -507,15 +507,15 @@ input_state_string_escape(u_char ch, struct input_ctx *ictx)
return; return;
s = input_get_string(ictx); s = input_get_string(ictx);
screen_set_title(ictx->ctx.s, s); screen_set_title(ictx->ctx.s, s);
server_status_window(ictx->w); server_status_window(ictx->wp->window);
xfree(s); xfree(s);
break; break;
case STRING_NAME: case STRING_NAME:
if (ch != '\\') if (ch != '\\')
return; return;
xfree(ictx->w->name); xfree(ictx->wp->window->name);
ictx->w->name = input_get_string(ictx); ictx->wp->window->name = input_get_string(ictx);
server_status_window(ictx->w); server_status_window(ictx->wp->window);
break; break;
} }
return; return;
@ -548,7 +548,9 @@ input_state_utf8(u_char ch, struct input_ctx *ictx)
void void
input_handle_character(u_char ch, struct input_ctx *ictx) 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. * UTF-8 sequence.
* *
@ -602,7 +604,7 @@ input_handle_c0_control(u_char ch, struct input_ctx *ictx)
screen_write_carriagereturn(&ictx->ctx); screen_write_carriagereturn(&ictx->ctx);
break; break;
case '\007': /* BELL */ case '\007': /* BELL */
ictx->w->flags |= WINDOW_BELL; ictx->wp->window->flags |= WINDOW_BELL;
break; break;
case '\010': /* BS */ case '\010': /* BS */
screen_write_cursorleft(&ictx->ctx, 1); screen_write_cursorleft(&ictx->ctx, 1);
@ -1128,7 +1130,7 @@ input_handle_sequence_dsr(struct input_ctx *ictx)
xsnprintf(reply, sizeof reply, xsnprintf(reply, sizeof reply,
"\033[%u;%uR", s->cy + 1, s->cx + 1); "\033[%u;%uR", s->cy + 1, s->cx + 1);
log_debug("cursor request, reply: %s", reply); log_debug("cursor request, reply: %s", reply);
buffer_write(ictx->w->out, reply, strlen(reply)); buffer_write(ictx->wp->out, reply, strlen(reply));
break; break;
} }
} }

View File

@ -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> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -77,6 +77,7 @@ key_bindings_init(void)
int key; int key;
const struct cmd_entry *entry; const struct cmd_entry *entry;
} table[] = { } table[] = {
{ '"', &cmd_split_window_entry },
{ '#', &cmd_list_buffers_entry }, { '#', &cmd_list_buffers_entry },
{ '&', &cmd_kill_window_entry }, { '&', &cmd_kill_window_entry },
{ '-', &cmd_delete_buffer_entry }, { '-', &cmd_delete_buffer_entry },
@ -94,17 +95,18 @@ key_bindings_init(void)
{ '=', &cmd_scroll_mode_entry }, { '=', &cmd_scroll_mode_entry },
{ '?', &cmd_list_keys_entry }, { '?', &cmd_list_keys_entry },
{ '[', &cmd_copy_mode_entry }, { '[', &cmd_copy_mode_entry },
{ '\'', &cmd_select_prompt_entry },
{ ']', &cmd_paste_buffer_entry }, { ']', &cmd_paste_buffer_entry },
{ 'c', &cmd_new_window_entry }, { 'c', &cmd_new_window_entry },
{ 'd', &cmd_detach_client_entry }, { 'd', &cmd_detach_client_entry },
{ 'l', &cmd_last_window_entry }, { 'l', &cmd_last_window_entry },
{ 'n', &cmd_next_window_entry }, { 'n', &cmd_next_window_entry },
{ 'o', &cmd_switch_pane_entry },
{ 'p', &cmd_previous_window_entry }, { 'p', &cmd_previous_window_entry },
{ 'r', &cmd_refresh_client_entry }, { 'r', &cmd_refresh_client_entry },
{ 's', &cmd_list_sessions_entry }, { 's', &cmd_list_sessions_entry },
{ 't', &cmd_clock_mode_entry }, { 't', &cmd_clock_mode_entry },
{ 'w', &cmd_list_windows_entry }, { 'w', &cmd_list_windows_entry },
{ '\'', &cmd_select_prompt_entry },
{ META, &cmd_send_prefix_entry }, { META, &cmd_send_prefix_entry },
}; };
u_int i; u_int i;
@ -152,13 +154,13 @@ key_bindings_error(struct cmd_ctx *ctx, const char *fmt, ...)
void printflike2 void printflike2
key_bindings_print(struct cmd_ctx *ctx, const char *fmt, ...) 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; va_list ap;
window_set_mode(w, &window_more_mode); window_pane_set_mode(wl->window->active, &window_more_mode);
va_start(ap, fmt); va_start(ap, fmt);
window_more_vadd(w, fmt, ap); window_more_vadd(wl->window->active, fmt, ap);
va_end(ap); va_end(ap);
} }

View File

@ -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> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -125,12 +125,11 @@ recalculate_sizes(void)
if (limit != 0 && ssy > limit) if (limit != 0 && ssy > limit)
ssy = limit; ssy = limit;
if (screen_size_x(&w->base) == ssx && if (w->sx == ssx && w->sy == ssy)
screen_size_y(&w->base) == ssy)
continue; continue;
log_debug("window size %u,%u (was %u,%u)", ssx, ssy, log_debug(
screen_size_x(&w->base), screen_size_y(&w->base)); "window size %u,%u (was %u,%u)", ssx, ssy, w->sx, w->sy);
window_resize(w, ssx, ssy); window_resize(w, ssx, ssy);
server_redraw_window(w); server_redraw_window(w);

View File

@ -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> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -22,146 +22,143 @@
#include "tmux.h" #include "tmux.h"
/* Initialise redrawing with a window. */ 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);
/* Redraw entire screen.. */
void void
screen_redraw_start_window(struct screen_redraw_ctx *ctx, struct window *w) screen_redraw_screen(struct client *c, struct screen *s)
{ {
struct screen *t = w->screen; struct winlink *wl = c->session->curw;
u_int i, cx, cy, sy;
int status;
screen_redraw_start(ctx, t, tty_write_window, w); status = options_get_number(&c->session->options, "status");
}
/* Initialise redrawing with a client. */ /* Override the normal screen if one is given. */
void if (s != NULL) {
screen_redraw_start_client(struct screen_redraw_ctx *ctx, struct client *c) for (i = 0; i < screen_size_y(s); i++)
{ screen_redraw_line(c, s, 0, i);
struct screen *t = c->session->curw->window->screen; return;
}
screen_redraw_start(ctx, t, tty_write_client, c); /*
} * 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
/* Initialise redrawing with a session. */ * off; the status line is always drawn.
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;
/*
* 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.
*/ */
ctx->saved_cx = s->cx;
ctx->saved_cy = s->cy;
ctx->write(ctx->data, TTY_SCROLLREGION, 0, screen_size_y(s) - 1); /* Draw the top window. */
ctx->write(ctx->data, TTY_CURSORMOVE, s->cx, s->cy); s = wl->window->panes[0]->screen;
ctx->write(ctx->data, TTY_CURSORMODE, 0); sy = screen_size_y(s);
ctx->write(ctx->data, TTY_MOUSEMODE, 0); 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;
}
/* 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);
}
/* 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);
/* Draw the status line. */
screen_redraw_status(c);
} }
/* Finish redrawing. */ /* Draw the status line. */
void void
screen_redraw_stop(struct screen_redraw_ctx *ctx) screen_redraw_status(struct client *c)
{ {
struct screen *s = ctx->s; screen_redraw_line(c, &c->status, c->sy - 1, 0);
s->cx = ctx->saved_cx;
s->cy = ctx->saved_cy;
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);
} }
/* Write character. */ /* Draw blank columns. */
void void
screen_redraw_putc( screen_redraw_blankx(struct client *c, u_int ox, u_int nx)
struct screen_redraw_ctx *ctx, struct grid_cell *gc, u_char ch)
{ {
gc->data = ch; u_int i, j;
ctx->write(ctx->data, TTY_CELL, gc);
ctx->s->cx++; 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, ' ');
}
c->tty.cx = UINT_MAX;
c->tty.cy = UINT_MAX;
memcpy(&c->tty.cell, &grid_default_cell, sizeof c->tty.cell);
} }
/* Write string. */ /* Draw blank lines. */
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);
}
/* Redraw single cell. */
void void
screen_redraw_cell(struct screen_redraw_ctx *ctx, u_int px, u_int py) screen_redraw_blanky(struct client *c, u_int oy, u_int ny)
{
u_int 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 a line. */
void
screen_redraw_line(struct client *c, struct screen *s, u_int oy, u_int py)
{ {
const struct grid_cell *gc; const struct grid_cell *gc;
struct grid_cell tc; struct grid_cell tc;
u_int i;
if (px != ctx->s->cx || py != ctx->s->cy) { for (i = 0; i < screen_size_x(s); i++) {
ctx->s->cx = px; s->cx = i;
ctx->s->cy = py; s->cy = py;
ctx->write(ctx->data, TTY_CURSORMOVE, ctx->s->cx, ctx->s->cy);
}
gc = grid_view_peek_cell(ctx->s->grid, px, py); gc = grid_view_peek_cell(s->grid, i, py);
if (screen_check_selection(ctx->s, px, py)) { if (screen_check_selection(s, i, py)) {
memcpy(&tc, &ctx->s->sel.cell, sizeof tc); memcpy(&tc, &s->sel.cell, sizeof tc);
tc.data = gc->data; tc.data = gc->data;
ctx->write(ctx->data, TTY_CELL, &tc); tty_write(&c->tty, s, oy, TTY_CELL, &tc);
} else } else
ctx->write(ctx->data, TTY_CELL, gc); tty_write(&c->tty, s, oy, TTY_CELL, gc);
ctx->s->cx++;
}
/* Draw set of lines. */
void
screen_redraw_lines(struct screen_redraw_ctx *ctx, u_int py, 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);
}
}
/* Draw set of columns. */
void
screen_redraw_columns(struct screen_redraw_ctx *ctx, u_int px, u_int nx)
{
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);
} }
} }

View File

@ -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> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -24,53 +24,28 @@
/* Initialise writing with a window. */ /* Initialise writing with a window. */
void 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; 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) if (ctx->write != NULL)
ctx->write(ctx->data, TTY_CURSORMODE, 0); ctx->write(ctx->data, TTY_CURSORMODE, 0);
} }
/* Finish writing. */ /* Finish writing. */
void 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. */ /* Write character. */
@ -140,9 +115,6 @@ screen_write_cursorup(struct screen_write_ctx *ctx, u_int ny)
return; return;
s->cy -= ny; s->cy -= ny;
if (ctx->write != NULL)
ctx->write(ctx->data, TTY_CURSORUP, ny);
} }
/* Cursor down by ny. */ /* Cursor down by ny. */
@ -160,9 +132,6 @@ screen_write_cursordown(struct screen_write_ctx *ctx, u_int ny)
return; return;
s->cy += ny; s->cy += ny;
if (ctx->write != NULL)
ctx->write(ctx->data, TTY_CURSORDOWN, ny);
} }
/* Cursor right by nx. */ /* Cursor right by nx. */
@ -180,9 +149,6 @@ screen_write_cursorright(struct screen_write_ctx *ctx, u_int nx)
return; return;
s->cx += nx; s->cx += nx;
if (ctx->write != NULL)
ctx->write(ctx->data, TTY_CURSORRIGHT, nx);
} }
/* Cursor left by nx. */ /* Cursor left by nx. */
@ -200,9 +166,6 @@ screen_write_cursorleft(struct screen_write_ctx *ctx, u_int nx)
return; return;
s->cx -= nx; s->cx -= nx;
if (ctx->write != NULL)
ctx->write(ctx->data, TTY_CURSORLEFT, nx);
} }
/* Insert nx characters. */ /* Insert nx characters. */
@ -219,11 +182,11 @@ screen_write_insertcharacter(struct screen_write_ctx *ctx, u_int nx)
if (nx == 0) if (nx == 0)
return; return;
if (s->cx <= screen_size_x(s) - 1)
grid_view_insert_cells(s->grid, s->cx, s->cy, nx);
if (ctx->write != NULL) if (ctx->write != NULL)
ctx->write(ctx->data, TTY_INSERTCHARACTER, nx); 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. */ /* Delete nx characters. */
@ -240,11 +203,11 @@ screen_write_deletecharacter(struct screen_write_ctx *ctx, u_int nx)
if (nx == 0) if (nx == 0)
return; return;
if (s->cx <= screen_size_x(s) - 1)
grid_view_delete_cells(s->grid, s->cx, s->cy, nx);
if (ctx->write != NULL) if (ctx->write != NULL)
ctx->write(ctx->data, TTY_DELETECHARACTER, nx); 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. */ /* Insert ny lines. */
@ -261,15 +224,15 @@ screen_write_insertline(struct screen_write_ctx *ctx, u_int ny)
if (ny == 0) if (ny == 0)
return; return;
if (ctx->write != NULL)
ctx->write(ctx->data, TTY_INSERTLINE, ny);
if (s->cy < s->rupper || s->cy > s->rlower) if (s->cy < s->rupper || s->cy > s->rlower)
grid_view_insert_lines(s->grid, s->cy, ny); grid_view_insert_lines(s->grid, s->cy, ny);
else { else {
grid_view_insert_lines_region( grid_view_insert_lines_region(
s->grid, s->rupper, s->rlower, s->cy, ny); s->grid, s->rupper, s->rlower, s->cy, ny);
} }
if (ctx->write != NULL)
ctx->write(ctx->data, TTY_INSERTLINE, ny);
} }
/* Delete ny lines. */ /* Delete ny lines. */
@ -286,15 +249,15 @@ screen_write_deleteline(struct screen_write_ctx *ctx, u_int ny)
if (ny == 0) if (ny == 0)
return; return;
if (ctx->write != NULL)
ctx->write(ctx->data, TTY_DELETELINE, ny);
if (s->cy < s->rupper || s->cy > s->rlower) if (s->cy < s->rupper || s->cy > s->rlower)
grid_view_delete_lines(s->grid, s->cy, ny); grid_view_delete_lines(s->grid, s->cy, ny);
else { else {
grid_view_delete_lines_region( grid_view_delete_lines_region(
s->grid, s->rupper, s->rlower, s->cy, ny); s->grid, s->rupper, s->rlower, s->cy, ny);
} }
if (ctx->write != NULL)
ctx->write(ctx->data, TTY_DELETELINE, ny);
} }
/* Clear line at cursor. */ /* Clear line at cursor. */
@ -303,10 +266,10 @@ screen_write_clearline(struct screen_write_ctx *ctx)
{ {
struct screen *s = ctx->s; struct screen *s = ctx->s;
grid_view_clear(s->grid, 0, s->cy, screen_size_x(s), 1);
if (ctx->write != NULL) if (ctx->write != NULL)
ctx->write(ctx->data, TTY_CLEARLINE); 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. */ /* Clear to end of line from cursor. */
@ -318,11 +281,11 @@ screen_write_clearendofline(struct screen_write_ctx *ctx)
sx = screen_size_x(s); 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) if (ctx->write != NULL)
ctx->write(ctx->data, TTY_CLEARENDOFLINE); 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. */ /* Clear to start of line from cursor. */
@ -334,13 +297,13 @@ screen_write_clearstartofline(struct screen_write_ctx *ctx)
sx = screen_size_x(s); sx = screen_size_x(s);
if (ctx->write != NULL)
ctx->write(ctx->data, TTY_CLEARSTARTOFLINE);
if (s->cx > sx - 1) if (s->cx > sx - 1)
grid_view_clear(s->grid, 0, s->cy, sx, 1); grid_view_clear(s->grid, 0, s->cy, sx, 1);
else else
grid_view_clear(s->grid, 0, s->cy, s->cx + 1, 1); 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. */ /* 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->cx = px;
s->cy = py; s->cy = py;
if (ctx->write != NULL)
ctx->write(ctx->data, TTY_CURSORMOVE, px, py);
} }
/* Set cursor mode. */ /* Set cursor mode. */
@ -371,9 +331,6 @@ screen_write_cursormode(struct screen_write_ctx *ctx, int state)
s->mode |= MODE_CURSOR; s->mode |= MODE_CURSOR;
else else
s->mode &= ~MODE_CURSOR; s->mode &= ~MODE_CURSOR;
if (ctx->write != NULL)
ctx->write(ctx->data, TTY_CURSORMODE, state);
} }
/* Reverse index (up with scroll). */ /* Reverse index (up with scroll). */
@ -382,13 +339,13 @@ screen_write_reverseindex(struct screen_write_ctx *ctx)
{ {
struct screen *s = ctx->s; struct screen *s = ctx->s;
if (ctx->write != NULL)
ctx->write(ctx->data, TTY_REVERSEINDEX);
if (s->cy == s->rupper) if (s->cy == s->rupper)
grid_view_scroll_region_down(s->grid, s->rupper, s->rlower); grid_view_scroll_region_down(s->grid, s->rupper, s->rlower);
else if (s->cy > 0) else if (s->cy > 0)
s->cy--; s->cy--;
if (ctx->write != NULL)
ctx->write(ctx->data, TTY_REVERSEINDEX);
} }
/* Set scroll region. */ /* Set scroll region. */
@ -411,9 +368,6 @@ screen_write_scrollregion(
s->rupper = rupper; s->rupper = rupper;
s->rlower = rlower; s->rlower = rlower;
if (ctx->write != NULL)
ctx->write(ctx->data, TTY_SCROLLREGION, rupper, rlower);
} }
/* Set insert mode. */ /* Set insert mode. */
@ -422,13 +376,13 @@ screen_write_insertmode(struct screen_write_ctx *ctx, int state)
{ {
struct screen *s = ctx->s; struct screen *s = ctx->s;
if (ctx->write != NULL)
ctx->write(ctx->data, TTY_INSERTMODE, state);
if (state) if (state)
s->mode |= MODE_INSERT; s->mode |= MODE_INSERT;
else else
s->mode &= ~MODE_INSERT; s->mode &= ~MODE_INSERT;
if (ctx->write != NULL)
ctx->write(ctx->data, TTY_INSERTMODE, state);
} }
/* Set mouse mode. */ /* Set mouse mode. */
@ -437,13 +391,13 @@ screen_write_mousemode(struct screen_write_ctx *ctx, int state)
{ {
struct screen *s = ctx->s; struct screen *s = ctx->s;
if (ctx->write != NULL)
ctx->write(ctx->data, TTY_MOUSEMODE, state);
if (state) if (state)
s->mode |= MODE_MOUSE; s->mode |= MODE_MOUSE;
else else
s->mode &= ~MODE_MOUSE; s->mode &= ~MODE_MOUSE;
if (ctx->write != NULL)
ctx->write(ctx->data, TTY_MOUSEMODE, state);
} }
/* Line feed (down with scroll). */ /* Line feed (down with scroll). */
@ -452,13 +406,13 @@ screen_write_linefeed(struct screen_write_ctx *ctx)
{ {
struct screen *s = ctx->s; struct screen *s = ctx->s;
if (ctx->write != NULL)
ctx->write(ctx->data, TTY_LINEFEED);
if (s->cy == s->rlower) if (s->cy == s->rlower)
grid_view_scroll_region_up(s->grid, s->rupper, s->rlower); grid_view_scroll_region_up(s->grid, s->rupper, s->rlower);
else if (s->cy < screen_size_x(s) - 1) else if (s->cy < screen_size_x(s) - 1)
s->cy++; s->cy++;
if (ctx->write != NULL)
ctx->write(ctx->data, TTY_LINEFEED);
} }
/* Carriage return (cursor to start of line). */ /* Carriage return (cursor to start of line). */
@ -468,9 +422,6 @@ screen_write_carriagereturn(struct screen_write_ctx *ctx)
struct screen *s = ctx->s; struct screen *s = ctx->s;
s->cx = 0; s->cx = 0;
if (ctx->write != NULL)
ctx->write(ctx->data, TTY_CARRIAGERETURN);
} }
/* Set keypad cursor keys mode. */ /* Set keypad cursor keys mode. */
@ -479,13 +430,13 @@ screen_write_kcursormode(struct screen_write_ctx *ctx, int state)
{ {
struct screen *s = ctx->s; struct screen *s = ctx->s;
if (ctx->write != NULL)
ctx->write(ctx->data, TTY_KCURSORMODE);
if (state) if (state)
s->mode |= MODE_KCURSOR; s->mode |= MODE_KCURSOR;
else else
s->mode &= ~MODE_KCURSOR; s->mode &= ~MODE_KCURSOR;
if (ctx->write != NULL)
ctx->write(ctx->data, TTY_KCURSORMODE);
} }
/* Set keypad number keys mode. */ /* Set keypad number keys mode. */
@ -494,13 +445,13 @@ screen_write_kkeypadmode(struct screen_write_ctx *ctx, int state)
{ {
struct screen *s = ctx->s; struct screen *s = ctx->s;
if (ctx->write != NULL)
ctx->write(ctx->data, TTY_KKEYPADMODE);
if (state) if (state)
s->mode |= MODE_KKEYPAD; s->mode |= MODE_KKEYPAD;
else else
s->mode &= ~MODE_KKEYPAD; s->mode &= ~MODE_KKEYPAD;
if (ctx->write != NULL)
ctx->write(ctx->data, TTY_KKEYPADMODE);
} }
/* Clear to end of screen from cursor. */ /* Clear to end of screen from cursor. */
@ -513,12 +464,12 @@ screen_write_clearendofscreen(struct screen_write_ctx *ctx)
sx = screen_size_x(s); sx = screen_size_x(s);
sy = screen_size_y(s); sy = screen_size_y(s);
if (ctx->write != NULL)
ctx->write(ctx->data, TTY_CLEARENDOFSCREEN);
if (s->cx <= sx - 1) if (s->cx <= sx - 1)
grid_view_clear(s->grid, s->cx, s->cy, sx - s->cx, 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)); 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. */ /* Clear to start of screen. */
@ -530,15 +481,15 @@ screen_write_clearstartofscreen(struct screen_write_ctx *ctx)
sx = screen_size_x(s); sx = screen_size_x(s);
if (ctx->write != NULL)
ctx->write(ctx->data, TTY_CLEARSTARTOFSCREEN);
if (s->cy > 0) if (s->cy > 0)
grid_view_clear(s->grid, 0, 0, sx, s->cy - 1); grid_view_clear(s->grid, 0, 0, sx, s->cy - 1);
if (s->cx > sx - 1) if (s->cx > sx - 1)
grid_view_clear(s->grid, 0, s->cy, sx, 1); grid_view_clear(s->grid, 0, s->cy, sx, 1);
else else
grid_view_clear(s->grid, 0, s->cy, s->cx, 1); grid_view_clear(s->grid, 0, s->cy, s->cx, 1);
if (ctx->write != NULL)
ctx->write(ctx->data, TTY_CLEARSTARTOFSCREEN);
} }
/* Clear entire screen. */ /* Clear entire screen. */
@ -547,10 +498,10 @@ screen_write_clearscreen(struct screen_write_ctx *ctx)
{ {
struct screen *s = ctx->s; struct screen *s = ctx->s;
grid_view_clear(s->grid, 0, 0, screen_size_x(s), screen_size_y(s));
if (ctx->write != NULL) if (ctx->write != NULL)
ctx->write(ctx->data, TTY_CLEARSCREEN); ctx->write(ctx->data, TTY_CLEARSCREEN);
grid_view_clear(s->grid, 0, 0, screen_size_x(s), screen_size_y(s));
} }
/* Write cell data. */ /* 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 * cells back to the character. Don't overwrite the current
* cell as that happens later anyway. * cell as that happens later anyway.
*/ */
xx = s->cx; xx = s->cx + 1;
while (xx-- > 0) { while (--xx > 0) {
hc = grid_view_peek_cell(gd, xx, s->cy); hc = grid_view_peek_cell(gd, xx, s->cy);
if (!(hc->flags & GRID_FLAG_PADDING)) if (!(hc->flags & GRID_FLAG_PADDING))
break; break;
@ -643,14 +594,16 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
/* Write the actual cell. */ /* Write the actual cell. */
grid_view_set_cell(gd, s->cx, s->cy, gc); grid_view_set_cell(gd, s->cx, s->cy, gc);
s->cx += width;
if (ctx->write != NULL) { if (ctx->write != NULL) {
if (screen_check_selection(ctx->s, s->cx, s->cy)) { if (screen_check_selection(s, s->cx, s->cy)) {
memcpy(&tc, &ctx->s->sel.cell, sizeof tc); memcpy(&tc, &s->sel.cell, sizeof tc);
tc.data = gc->data; tc.data = gc->data;
ctx->write(ctx->data, TTY_CELL, &tc); ctx->write(ctx->data, TTY_CELL, &tc);
} else } else
ctx->write(ctx->data, TTY_CELL, gc); ctx->write(ctx->data, TTY_CELL, gc);
} }
/* Move the cursor. */
s->cx += width;
} }

View File

@ -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> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -21,6 +21,7 @@
#include <errno.h> #include <errno.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <time.h>
#include <unistd.h> #include <unistd.h>
#include "tmux.h" #include "tmux.h"

245
server.c
View File

@ -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> * 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 **); void server_handle_clients(struct pollfd **);
struct client *server_accept_client(int); struct client *server_accept_client(int);
void server_handle_client(struct client *); 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_client(struct client *);
void server_lost_window(struct window *); int server_lost_window(struct window *, int);
void server_check_redraw(struct client *); void server_check_redraw(struct client *);
void server_do_redraw_client(struct client *); void server_redraw_locked(struct client *);
void server_do_redraw_locked(struct client *);
void server_check_timers(struct client *); void server_check_timers(struct client *);
void server_second_timers(void); void server_second_timers(void);
int server_update_socket(const char *); int server_update_socket(const char *);
@ -184,7 +183,9 @@ server_main(const char *srv_path, int srv_fd)
pfds = NULL; pfds = NULL;
while (!sigterm) { while (!sigterm) {
/* Initialise pollfd array. */ /* 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); pfds = xrealloc(pfds, nfds, sizeof *pfds);
pfd = pfds; pfd = pfds;
@ -279,19 +280,25 @@ server_main(const char *srv_path, int srv_fd)
void void
server_fill_windows(struct pollfd **pfd) server_fill_windows(struct pollfd **pfd)
{ {
struct window *w; struct window *w;
u_int i; struct window_pane *wp;
u_int i, j;
for (i = 0; i < ARRAY_LENGTH(&windows); i++) { for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
if ((w = ARRAY_ITEM(&windows, i)) == NULL || w->fd == -1) w = ARRAY_ITEM(&windows, i);
(*pfd)->fd = -1; for (j = 0; j < 2; j++) {
else { if (w != NULL)
(*pfd)->fd = w->fd; wp = w->panes[j];
(*pfd)->events = POLLIN; if (w == NULL || wp == NULL || wp->fd == -1) {
if (BUFFER_USED(w->out) > 0) (*pfd)->fd = -1;
(*pfd)->events |= POLLOUT; } 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 void
server_handle_windows(struct pollfd **pfd) server_handle_windows(struct pollfd **pfd)
{ {
struct window *w; struct window *w;
u_int i; struct window_pane *wp;
u_int i, j;
for (i = 0; i < ARRAY_LENGTH(&windows); i++) { for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
if ((w = ARRAY_ITEM(&windows, i)) != NULL && w->fd != -1) { w = ARRAY_ITEM(&windows, i);
if (buffer_poll(*pfd, w->in, w->out) != 0) for (j = 0; j < 2; j++) {
server_lost_window(w); if (w != NULL)
else wp = w->panes[j];
server_handle_window(w); 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; c->tty.flags &= ~TTY_FREEZE;
if (options_get_number(&s->options, "set-titles")) { 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 || strcmp(title, c->title) != 0) {
if (c->title != NULL) if (c->title != NULL)
xfree(c->title); xfree(c->title);
@ -338,16 +352,7 @@ server_check_redraw(struct client *c)
} }
} }
if (c->flags & CLIENT_REDRAW) { if (c->flags & (CLIENT_REDRAW|CLIENT_STATUS)) {
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->message_string != NULL) if (c->message_string != NULL)
status_message_redraw(c); status_message_redraw(c);
else if (c->prompt_string != NULL) else if (c->prompt_string != NULL)
@ -356,78 +361,47 @@ server_check_redraw(struct client *c)
status_redraw(c); status_redraw(c);
} }
if (c->flags & CLIENT_REDRAW) {
if (server_locked)
server_redraw_locked(c);
else
screen_redraw_screen(c, NULL);
}
if (c->flags & CLIENT_STATUS)
screen_redraw_status(c);
c->tty.flags |= flags; c->tty.flags |= flags;
c->flags &= ~(CLIENT_REDRAW|CLIENT_STATUS); c->flags &= ~(CLIENT_REDRAW|CLIENT_STATUS);
} }
/* 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;
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);
}
/* Redraw client when locked. */ /* Redraw client when locked. */
void void
server_do_redraw_locked(struct client *c) server_redraw_locked(struct client *c)
{ {
struct session *s = c->session; struct screen_write_ctx ctx;
struct window *w = s->curw->window; struct screen screen;
struct screen_write_ctx ctx; u_int colour, xx, yy;
struct screen screen; int style;
u_int colour, xx, yy;
int style;
xx = c->sx; xx = c->sx;
yy = c->sy - 1; yy = c->sy - 1;
if (xx == 0 || yy == 0) if (xx == 0 || yy == 0)
return; return;
colour = options_get_number(&w->options, "clock-mode-colour"); colour = options_get_number(
style = options_get_number(&w->options, "clock-mode-style"); &global_window_options, "clock-mode-colour");
style = options_get_number(
&global_window_options, "clock-mode-style");
screen_init(&screen, xx, yy, 0); 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); clock_draw(&ctx, colour, style);
screen_write_stop(&ctx); screen_write_stop(&ctx);
screen_redraw_screen(c, &screen);
screen_free(&screen); screen_free(&screen);
} }
@ -567,6 +541,7 @@ server_accept_client(int srv_fd)
c->session = NULL; c->session = NULL;
c->sx = 80; c->sx = 80;
c->sy = 25; c->sy = 25;
screen_init(&c->status, c->sx, 1, 0);
c->message_string = NULL; c->message_string = NULL;
@ -588,9 +563,12 @@ server_accept_client(int srv_fd)
void void
server_handle_client(struct client *c) server_handle_client(struct client *c)
{ {
struct window *w = c->session->curw->window; struct winlink *wl = c->session->curw;
int key, prefix; struct window_pane *wp = wl->window->active;
int key, prefix;
u_int oy;
/* Process keys. */
prefix = options_get_number(&c->session->options, "prefix"); prefix = options_get_number(&c->session->options, "prefix");
while (tty_keys_next(&c->tty, &key) == 0) { while (tty_keys_next(&c->tty, &key) == 0) {
server_activity = time(NULL); server_activity = time(NULL);
@ -610,8 +588,20 @@ server_handle_client(struct client *c)
} else if (key == prefix) } else if (key == prefix)
c->flags |= CLIENT_PREFIX; c->flags |= CLIENT_PREFIX;
else 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. */ /* Lost a client. */
@ -654,13 +644,14 @@ server_lost_client(struct client *c)
/* Handle window data. */ /* Handle window data. */
void void
server_handle_window(struct window *w) server_handle_window(struct window *w, int pane)
{ {
struct session *s; struct session *s;
struct client *c;
u_int i; u_int i;
int action, update; int action, update;
window_parse(w); window_pane_parse(w->panes[pane]);
if (!(w->flags & WINDOW_BELL) && !(w->flags & WINDOW_ACTIVITY)) if (!(w->flags & WINDOW_BELL) && !(w->flags & WINDOW_ACTIVITY))
return; return;
@ -678,12 +669,22 @@ server_handle_window(struct window *w)
action = options_get_number(&s->options, "bell-action"); action = options_get_number(&s->options, "bell-action");
switch (action) { switch (action) {
case BELL_ANY: 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; break;
case BELL_CURRENT: case BELL_CURRENT:
if (s->curw->window != w) if (w->active != w->panes[pane])
break; 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; break;
} }
update = 1; update = 1;
@ -703,20 +704,27 @@ server_handle_window(struct window *w)
} }
/* Lost window: move clients on to next window. */ /* Lost window: move clients on to next window. */
void int
server_lost_window(struct window *w) server_lost_window(struct window *w, int pane)
{ {
struct client *c; struct client *c;
struct session *s; struct session *s;
struct winlink *wl; struct winlink *wl;
u_int i, j; struct window_pane *wp;
int destroyed; u_int i, j;
int destroyed;
log_debug("lost window %d", w->fd); 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")) { if (options_get_number(&w->options, "remain-on-exit")) {
w->fd = -1; wp->fd = -1;
return; return (0);
} }
for (i = 0; i < ARRAY_LENGTH(&sessions); i++) { for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
@ -751,18 +759,20 @@ server_lost_window(struct window *w)
} }
recalculate_sizes(); recalculate_sizes();
return (1);
} }
/* Call any once-per-second timers. */ /* Call any once-per-second timers. */
void void
server_second_timers(void) server_second_timers(void)
{ {
struct window *w; struct window *w;
u_int i; struct window_pane *wp;
int xtimeout; u_int i, j;
struct tm now, then; int xtimeout;
static time_t last_t = 0; struct tm now, then;
time_t t; static time_t last_t = 0;
time_t t;
t = time(NULL); t = time(NULL);
xtimeout = options_get_number(&global_options, "lock-after-time"); 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++) { for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
w = ARRAY_ITEM(&windows, i); w = ARRAY_ITEM(&windows, i);
if (w->mode != NULL && w->mode->timer != NULL) if (w == NULL)
w->mode->timer(w); 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); gmtime_r(&t, &now);

158
status.c
View File

@ -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> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -39,11 +39,12 @@ char *status_prompt_complete(const char *);
void void
status_redraw(struct client *c) status_redraw(struct client *c)
{ {
struct screen_redraw_ctx ctx; struct screen_write_ctx ctx;
struct session *s = c->session; struct session *s = c->session;
struct winlink *wl; struct winlink *wl;
struct window_pane *wp;
char *left, *right, *text, *ptr; 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; size_t size, start, width;
struct grid_cell gc; struct grid_cell gc;
int larrow, rarrow; int larrow, rarrow;
@ -144,22 +145,28 @@ status_redraw(struct client *c)
width = xx; width = xx;
draw: 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. */ /* Bail here if anything is too small too. XXX. */
if (width == 0 || xx == 0) if (width == 0 || xx == 0)
goto blank; goto blank;
/* Begin drawing and move to the starting position. */ /* Begin drawing and move to the starting position. */
screen_redraw_start_client(&ctx, c); screen_write_start(&ctx, NULL, &c->status);
if (llen != 0) { if (llen != 0) {
ctx.write(ctx.data, TTY_CURSORMOVE, 0, yy); screen_write_cursormove(&ctx, 0, yy);
screen_redraw_puts(&ctx, &gc, "%s ", left); screen_write_puts(&ctx, &gc, "%s ", left);
if (larrow) if (larrow)
screen_redraw_putc(&ctx, &gc, ' '); screen_write_putc(&ctx, &gc, ' ');
} else { } else {
if (larrow) if (larrow)
ctx.write(ctx.data, TTY_CURSORMOVE, 1, yy); screen_write_cursormove(&ctx, 1, yy);
else else
ctx.write(ctx.data, TTY_CURSORMOVE, 0, yy); screen_write_cursormove(&ctx, 0, yy);
} }
/* Draw each character in succession. */ /* Draw each character in succession. */
@ -176,7 +183,7 @@ draw:
for (ptr = text; *ptr != '\0'; ptr++) { for (ptr = text; *ptr != '\0'; ptr++) {
if (offset >= start && offset < start + width) if (offset >= start && offset < start + width)
screen_redraw_putc(&ctx, &gc, *ptr); screen_write_putc(&ctx, &gc, *ptr);
offset++; offset++;
} }
@ -190,7 +197,7 @@ draw:
gc.attr &= ~GRID_ATTR_REVERSE; gc.attr &= ~GRID_ATTR_REVERSE;
if (offset < start + width) { if (offset < start + width) {
if (offset >= start) { if (offset >= start) {
screen_redraw_putc(&ctx, &gc, ' '); screen_write_putc(&ctx, &gc, ' ');
} }
offset++; offset++;
} }
@ -200,12 +207,12 @@ draw:
/* Fill the remaining space if any. */ /* Fill the remaining space if any. */
while (offset++ < xx) while (offset++ < xx)
screen_redraw_putc(&ctx, &gc, ' '); screen_write_putc(&ctx, &gc, ' ');
/* Draw the last item. */ /* Draw the last item. */
if (rlen != 0) { if (rlen != 0) {
ctx.write(ctx.data, TTY_CURSORMOVE, c->sx - rlen - 1, yy); screen_write_cursormove(&ctx, c->sx - rlen - 1, yy);
screen_redraw_puts(&ctx, &gc, " %s", right); screen_write_puts(&ctx, &gc, " %s", right);
} }
/* Draw the arrows. */ /* Draw the arrows. */
@ -215,10 +222,10 @@ draw:
else else
gc.attr &= ~GRID_ATTR_REVERSE; gc.attr &= ~GRID_ATTR_REVERSE;
if (llen != 0) if (llen != 0)
ctx.write(ctx.data, TTY_CURSORMOVE, llen + 1, yy); screen_write_cursormove(&ctx, llen + 1, yy);
else else
ctx.write(ctx.data, TTY_CURSORMOVE, 0, yy); screen_write_cursormove(&ctx, 0, yy);
screen_redraw_putc(&ctx, &gc, '<'); screen_write_putc(&ctx, &gc, '<');
gc.attr &= ~GRID_ATTR_REVERSE; gc.attr &= ~GRID_ATTR_REVERSE;
} }
if (rarrow != 0) { if (rarrow != 0) {
@ -226,12 +233,11 @@ draw:
gc.attr |= GRID_ATTR_REVERSE; gc.attr |= GRID_ATTR_REVERSE;
else else
gc.attr &= ~GRID_ATTR_REVERSE; gc.attr &= ~GRID_ATTR_REVERSE;
if (rlen != 0) { if (rlen != 0)
ctx.write( screen_write_cursormove(&ctx, c->sx - rlen - 2, yy);
ctx.data, TTY_CURSORMOVE, c->sx - rlen - 2, yy); else
} else screen_write_cursormove(&ctx, c->sx - 1, yy);
ctx.write(ctx.data, TTY_CURSORMOVE, c->sx - 1, yy); screen_write_putc(&ctx, &gc, '>');
screen_redraw_putc(&ctx, &gc, '>');
gc.attr &= ~GRID_ATTR_REVERSE; gc.attr &= ~GRID_ATTR_REVERSE;
} }
@ -239,10 +245,10 @@ draw:
blank: blank:
/* Just draw the whole line as blank. */ /* Just draw the whole line as blank. */
screen_redraw_start_client(&ctx, c); screen_write_start(&ctx, NULL, &c->status);
ctx.write(ctx.data, TTY_CURSORMOVE, 0, yy); screen_write_cursormove(&ctx, 0, yy);
for (offset = 0; offset < c->sx; offset++) for (offset = 0; offset < c->sx; offset++)
screen_redraw_putc(&ctx, &gc, ' '); screen_write_putc(&ctx, &gc, ' ');
goto out; goto out;
@ -251,17 +257,26 @@ off:
* Draw the real window last line. Necessary to wipe over message if * Draw the real window last line. Necessary to wipe over message if
* status is off. Not sure this is the right place for this. * status is off. Not sure this is the right place for this.
*/ */
screen_redraw_start_client(&ctx, c); screen_write_start(&ctx, NULL, &c->status);
/* If the screen is too small, use blank. */ wp = s->curw->window->panes[1];
if (screen_size_y(c->session->curw->window->screen) < c->sy) { sy = c->sy - (c->sy / 2);
ctx.write(ctx.data, TTY_CURSORMOVE, 0, c->sy - 1); 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++) for (offset = 0; offset < c->sx; offset++)
screen_redraw_putc(&ctx, &gc, ' '); screen_write_putc(&ctx, &gc, ' ');
} else abort();
screen_redraw_lines(&ctx, c->sy - 1, 1); } else {
screen_write_copy(&ctx, wp->screen, 0, wp->screen->grid->hsize +
screen_size_y(wp->screen) - 1, c->sx, 1);
}
out: out:
screen_redraw_stop(&ctx); screen_write_stop(&ctx);
if (left != NULL) if (left != NULL)
xfree(left); xfree(left);
@ -272,6 +287,7 @@ out:
char * char *
status_replace(struct session *s, char *fmt, time_t t) status_replace(struct session *s, char *fmt, time_t t)
{ {
struct winlink *wl = s->curw;
static char out[BUFSIZ]; static char out[BUFSIZ];
char in[BUFSIZ], ch, *iptr, *optr, *ptr, *endptr; char in[BUFSIZ], ch, *iptr, *optr, *ptr, *endptr;
size_t len; size_t len;
@ -300,7 +316,7 @@ status_replace(struct session *s, char *fmt, time_t t)
switch (*iptr++) { switch (*iptr++) {
case 'T': case 'T':
ptr = s->curw->window->base.title; ptr = wl->window->active->base.title;
len = strlen(ptr); len = strlen(ptr);
if ((size_t) n < len) if ((size_t) n < len)
len = n; len = n;
@ -333,7 +349,7 @@ status_width(struct winlink *wl)
return (xsnprintf(NULL, 0, "%d:%s ", wl->idx, wl->window->name)); return (xsnprintf(NULL, 0, "%d:%s ", wl->idx, wl->window->name));
#else #else
char *s; char *s;
size_t n; size_t n;
xasprintf(&s, "%d:%s ", wl->idx, wl->window->name); xasprintf(&s, "%d:%s ", wl->idx, wl->window->name);
n = strlen(s); n = strlen(s);
@ -372,64 +388,68 @@ status_print(struct session *s, struct winlink *wl, struct grid_cell *gc)
void void
status_message_redraw(struct client *c) status_message_redraw(struct client *c)
{ {
struct screen_redraw_ctx ctx; struct screen_write_ctx ctx;
struct session *s = c->session; struct session *s = c->session;
size_t xx, yy; size_t len;
struct grid_cell gc; struct grid_cell gc;
if (c->sx == 0 || c->sy == 0) if (c->sx == 0 || c->sy == 0)
return; 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); len = strlen(c->message_string);
if (xx > c->sx) if (len > c->sx)
xx = c->sx; len = c->sx;
yy = c->sy - 1;
memcpy(&gc, &grid_default_cell, sizeof gc); memcpy(&gc, &grid_default_cell, sizeof gc);
gc.fg = options_get_number(&s->options, "message-fg"); gc.fg = options_get_number(&s->options, "message-fg");
gc.bg = options_get_number(&s->options, "message-bg"); 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_write_cursormove(&ctx, 0, 0);
screen_redraw_puts(&ctx, &gc, "%.*s", (int) xx, c->message_string); screen_write_puts(&ctx, &gc, "%.*s", (int) len, c->message_string);
for (; xx < c->sx; xx++) for (; len < c->sx; len++)
screen_redraw_putc(&ctx, &gc, ' '); screen_write_putc(&ctx, &gc, ' ');
screen_redraw_stop(&ctx); screen_write_stop(&ctx);
tty_write_client(c, TTY_CURSORMODE, 0);
} }
/* Draw client prompt on status line of present else on last line. */ /* Draw client prompt on status line of present else on last line. */
void void
status_prompt_redraw(struct client *c) status_prompt_redraw(struct client *c)
{ {
struct screen_redraw_ctx ctx; struct screen_write_ctx ctx;
struct session *s = c->session; struct session *s = c->session;
size_t i, xx, yy, left, size, offset, n; size_t i, size, left, len, offset, n;
char ch; char ch;
struct grid_cell gc; struct grid_cell gc;
if (c->sx == 0 || c->sy == 0) if (c->sx == 0 || c->sy == 0)
return; return;
if (screen_size_x(&c->status) != c->sx) {
screen_free(&c->status);
screen_init(&c->status, c->sx, 1, 0);
}
offset = 0; offset = 0;
xx = strlen(c->prompt_string); len = strlen(c->prompt_string);
if (xx > c->sx) if (len > c->sx)
xx = c->sx; len = c->sx;
yy = c->sy - 1;
memcpy(&gc, &grid_default_cell, sizeof gc); memcpy(&gc, &grid_default_cell, sizeof gc);
gc.fg = options_get_number(&s->options, "message-fg"); gc.fg = options_get_number(&s->options, "message-fg");
gc.bg = options_get_number(&s->options, "message-bg"); 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_write_cursormove(&ctx, 0, 0);
screen_redraw_puts(&ctx, &gc, "%.*s", (int) xx, c->prompt_string); screen_write_puts(&ctx, &gc, "%.*s", (int) len, c->prompt_string);
left = c->sx - xx; left = c->sx - len;
if (left != 0) { if (left != 0) {
if (c->prompt_index < left) if (c->prompt_index < left)
size = strlen(c->prompt_buffer); size = strlen(c->prompt_buffer);
@ -444,20 +464,18 @@ status_prompt_redraw(struct client *c)
if (n > left) if (n > left)
n = left; n = left;
for (i = 0; i < n; i++) for (i = 0; i < n; i++)
screen_redraw_putc(&ctx, &gc, '*'); screen_write_putc(&ctx, &gc, '*');
} else { } else {
screen_redraw_puts(&ctx, &gc, screen_write_puts(&ctx, &gc,
"%.*s", (int) left, c->prompt_buffer + offset); "%.*s", (int) left, c->prompt_buffer + offset);
} }
for (i = xx + size; i < c->sx; i++) { for (i = len + size; i < c->sx; i++)
screen_redraw_putc(&ctx, &gc, ' '); screen_write_putc(&ctx, &gc, ' ');
ctx.s->cx++;
}
} }
/* Draw a fake cursor. */ /* 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)) if (c->prompt_index == strlen(c->prompt_buffer))
ch = ' '; ch = ' ';
else else
@ -466,11 +484,9 @@ status_prompt_redraw(struct client *c)
ch = ' '; ch = ' ';
gc.bg = gc.fg; gc.bg = gc.fg;
gc.fg = options_get_number(&s->options, "message-bg"); gc.fg = options_get_number(&s->options, "message-bg");
screen_redraw_putc(&ctx, &gc, ch); screen_write_putc(&ctx, &gc, ch);
screen_redraw_stop(&ctx); screen_write_stop(&ctx);
tty_write_client(c, TTY_CURSORMODE, 0);
} }
/* Handle keys in prompt. */ /* Handle keys in prompt. */

151
tmux.h
View File

@ -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> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -330,8 +330,6 @@ struct tty_term_code_entry {
/* Output commands. */ /* Output commands. */
enum tty_cmd { enum tty_cmd {
TTY_BELL,
TTY_CARRIAGERETURN,
TTY_CELL, TTY_CELL,
TTY_CLEARENDOFLINE, TTY_CLEARENDOFLINE,
TTY_CLEARENDOFSCREEN, TTY_CLEARENDOFSCREEN,
@ -339,12 +337,7 @@ enum tty_cmd {
TTY_CLEARSCREEN, TTY_CLEARSCREEN,
TTY_CLEARSTARTOFLINE, TTY_CLEARSTARTOFLINE,
TTY_CLEARSTARTOFSCREEN, TTY_CLEARSTARTOFSCREEN,
TTY_CURSORDOWN,
TTY_CURSORLEFT,
TTY_CURSORMODE, TTY_CURSORMODE,
TTY_CURSORMOVE,
TTY_CURSORRIGHT,
TTY_CURSORUP,
TTY_DELETECHARACTER, TTY_DELETECHARACTER,
TTY_DELETELINE, TTY_DELETELINE,
TTY_INSERTCHARACTER, TTY_INSERTCHARACTER,
@ -355,7 +348,6 @@ enum tty_cmd {
TTY_LINEFEED, TTY_LINEFEED,
TTY_MOUSEMODE, TTY_MOUSEMODE,
TTY_REVERSEINDEX, TTY_REVERSEINDEX,
TTY_SCROLLREGION,
}; };
/* Message codes. */ /* Message codes. */
@ -514,17 +506,6 @@ struct screen {
struct screen_sel sel; 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. */ /* Screen write context. */
struct screen_write_ctx { struct screen_write_ctx {
void *data; void *data;
@ -547,7 +528,7 @@ struct input_arg {
/* Input parser context. */ /* Input parser context. */
struct input_ctx { struct input_ctx {
struct window *w; struct window_pane *wp;
struct screen_write_ctx ctx; struct screen_write_ctx ctx;
u_char *buf; u_char *buf;
@ -584,17 +565,19 @@ struct input_ctx {
* right function to handle input and output. * right function to handle input and output.
*/ */
struct client; struct client;
struct window;
struct window_mode { struct window_mode {
struct screen *(*init)(struct window *); struct screen *(*init)(struct window_pane *);
void (*free)(struct window *); void (*free)(struct window_pane *);
void (*resize)(struct window *, u_int, u_int); void (*resize)(struct window_pane *, u_int, u_int);
void (*key)(struct window *, struct client *, int); void (*key)(struct window_pane *, struct client *, int);
void (*timer)(struct window *); void (*timer)(struct window_pane *);
}; };
/* Window structure. */ /* Child window structure. */
struct window { struct window_pane {
char *name; struct window *window;
char *cmd; char *cmd;
char *cwd; char *cwd;
@ -604,18 +587,29 @@ struct window {
struct input_ctx ictx; 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; int flags;
#define WINDOW_BELL 0x1 #define WINDOW_BELL 0x1
#define WINDOW_HIDDEN 0x2 #define WINDOW_HIDDEN 0x2
#define WINDOW_ACTIVITY 0x4 #define WINDOW_ACTIVITY 0x4
struct screen *screen; struct options options;
struct screen base;
const struct window_mode *mode;
void *modedata;
u_int references; u_int references;
}; };
@ -698,6 +692,14 @@ SLIST_HEAD(tty_terms, tty_term);
struct tty { struct tty {
char *path; char *path;
u_int cx;
u_int cy;
int cursor;
u_int rlower;
u_int rupper;
char *termname; char *termname;
struct tty_term *term; struct tty_term *term;
@ -742,6 +744,8 @@ struct client {
u_int sx; u_int sx;
u_int sy; u_int sy;
struct screen status;
#define CLIENT_TERMINAL 0x1 #define CLIENT_TERMINAL 0x1
#define CLIENT_PREFIX 0x2 #define CLIENT_PREFIX 0x2
#define CLIENT_MOUSE 0x4 #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 *); long long options_get_number(struct options *, const char *);
/* tty.c */ /* 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_init(struct tty *, char *, char *);
void tty_set_title(struct tty *, const char *); void tty_set_title(struct tty *, const char *);
int tty_open(struct tty *, char **); int tty_open(struct tty *, char **);
void tty_close(struct tty *); void tty_close(struct tty *);
void tty_free(struct tty *); void tty_free(struct tty *);
void tty_write(struct tty *, struct screen *, enum tty_cmd, ...); void tty_write(struct tty *,
void tty_vwrite( struct screen *, u_int, enum tty_cmd, ...);
struct tty *, struct screen *s, enum tty_cmd, va_list); void tty_vwrite(struct tty *,
struct screen *s, u_int, enum tty_cmd, va_list);
/* tty-term.c */ /* tty-term.c */
extern struct tty_terms tty_terms; extern struct tty_terms tty_terms;
@ -1003,12 +1014,8 @@ void tty_keys_free(struct tty *);
int tty_keys_next(struct tty *, int *); int tty_keys_next(struct tty *, int *);
/* tty-write.c */ /* 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_write_window(void *, enum tty_cmd, ...);
void tty_vwrite_window(void *, enum tty_cmd, va_list); 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 */ /* options-cmd.c */
void set_option_string(struct cmd_ctx *, 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_options_entry;
extern const struct cmd_entry cmd_show_window_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_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_start_server_entry;
extern const struct cmd_entry cmd_swap_window_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_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_unbind_key_entry;
extern const struct cmd_entry cmd_unlink_window_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 *); void server_clear_client_prompt(struct client *);
struct session *server_extract_session( struct session *server_extract_session(
struct msg_command_data *, char *, char **); struct msg_command_data *, char *, char **);
void server_write(struct client *, enum hdrtype, const void *, size_t);
void server_write_client( void server_write_client(
struct client *, enum hdrtype, const void *, size_t); struct client *, enum hdrtype, const void *, size_t);
void server_write_session( void server_write_session(
struct session *, enum hdrtype, const void *, size_t); struct session *, enum hdrtype, const void *, size_t);
void server_write_window( 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_redraw_client(struct client *);
void server_status_client(struct client *); void server_status_client(struct client *);
void server_redraw_session(struct session *); void server_redraw_session(struct session *);
@ -1225,12 +1235,12 @@ void status_prompt_key(struct client *, int);
void recalculate_sizes(void); void recalculate_sizes(void);
/* input.c */ /* input.c */
void input_init(struct window *); void input_init(struct window_pane *);
void input_free(struct window *); void input_free(struct window_pane *);
void input_parse(struct window *); void input_parse(struct window_pane *);
/* input-key.c */ /* input-key.c */
void input_key(struct window *, int); void input_key(struct window_pane *, int);
/* colour.c */ /* colour.c */
const char *colour_tostring(u_char); 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); void grid_view_delete_cells(struct grid_data *, u_int, u_int, u_int);
/* screen-write.c */ /* screen-write.c */
void screen_write_start_window(struct screen_write_ctx *, struct window *); void screen_write_start(
void screen_write_start_client(struct screen_write_ctx *, struct client *); struct screen_write_ctx *, struct window_pane *, struct screen *);
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_stop(struct screen_write_ctx *); void screen_write_stop(struct screen_write_ctx *);
void printflike3 screen_write_puts( void printflike3 screen_write_puts(
struct screen_write_ctx *, struct grid_cell *, const char *, ...); 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 *); void screen_write_cell(struct screen_write_ctx *, const struct grid_cell *);
/* screen-redraw.c */ /* screen-redraw.c */
void screen_redraw_start_window(struct screen_redraw_ctx *, struct window *); void screen_redraw_screen(struct client *, struct screen *);
void screen_redraw_start_client(struct screen_redraw_ctx *, struct client *); void screen_redraw_status(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);
/* screen.c */ /* screen.c */
void screen_init(struct screen *, u_int, u_int, u_int); 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 *); void winlink_stack_remove(struct winlink_stack *, struct winlink *);
struct window *window_create(const char *, const char *, struct window *window_create(const char *, const char *,
const char *, const char **, u_int, u_int, u_int); 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 *); void window_destroy(struct window *);
int window_resize(struct window *, u_int, u_int); int window_resize(struct window *, u_int, u_int);
int window_set_mode(struct window *, const struct window_mode *); int window_remove_pane(struct window *, int);
void window_reset_mode(struct window *); struct window_pane *window_pane_create(struct window *, u_int, u_int, u_int);
void window_parse(struct window *); void window_pane_destroy(struct window_pane *);
void window_key(struct window *, struct client *, int); 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 */ /* window-clock.c */
extern const struct window_mode window_clock_mode; extern const struct window_mode window_clock_mode;
@ -1384,8 +1383,8 @@ extern const struct window_mode window_scroll_mode;
/* window-more.c */ /* window-more.c */
extern const struct window_mode window_more_mode; extern const struct window_mode window_more_mode;
void window_more_vadd(struct window *, const char *, va_list); void window_more_vadd(struct window_pane *, const char *, va_list);
void printflike2 window_more_add(struct window *, const char *, ...); void printflike2 window_more_add(struct window_pane *, const char *, ...);
/* session.c */ /* session.c */
extern struct sessions sessions; extern struct sessions sessions;
@ -1399,7 +1398,7 @@ struct session *session_create(
void session_destroy(struct session *); void session_destroy(struct session *);
int session_index(struct session *, u_int *); int session_index(struct session *, u_int *);
struct winlink *session_new(struct session *, 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); struct winlink *session_attach(struct session *, struct window *, int);
int session_detach(struct session *, struct winlink *); int session_detach(struct session *, struct winlink *);
int session_has(struct session *, struct window *); int session_has(struct session *, struct window *);

View File

@ -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> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -20,26 +20,6 @@
#include "tmux.h" #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 void
tty_write_window(void *ptr, enum tty_cmd cmd, ...) tty_write_window(void *ptr, enum tty_cmd cmd, ...)
{ {
@ -53,55 +33,28 @@ tty_write_window(void *ptr, enum tty_cmd cmd, ...)
void void
tty_vwrite_window(void *ptr, enum tty_cmd cmd, va_list ap) tty_vwrite_window(void *ptr, enum tty_cmd cmd, va_list ap)
{ {
struct window *w = ptr; struct window_pane *wp = ptr;
struct client *c; struct client *c;
va_list aq; va_list aq;
u_int i; u_int i, oy;
if (w->flags & WINDOW_HIDDEN) if (wp->window->flags & WINDOW_HIDDEN)
return; return;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i); c = ARRAY_ITEM(&clients, i);
if (c == NULL || c->session == NULL) if (c == NULL || c->session == NULL)
continue; continue;
if (c->session->curw->window != w)
continue;
va_copy(aq, ap); if (c->session->curw->window == wp->window) {
tty_vwrite_client(c, cmd, aq); if (wp == wp->window->panes[0])
va_end(aq); oy = 0;
} else
} oy = wp->window->sy / 2;
void va_copy(aq, ap);
tty_write_session(void *ptr, enum tty_cmd cmd, ...) tty_vwrite(&c->tty, wp->screen, oy, cmd, aq);
{ va_end(aq);
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;
va_copy(aq, ap);
tty_vwrite_client(c, cmd, aq);
va_end(aq);
} }
} }

297
tty.c
View File

@ -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> * 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); struct tty *, enum tty_code_code, enum tty_code_code, u_int);
void tty_raw(struct tty *, const char *); 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_reset(struct tty *);
void tty_region(struct tty *, struct screen *, u_int);
void tty_attributes(struct tty *, const struct grid_cell *); void tty_attributes(struct tty *, const struct grid_cell *);
void tty_attributes_fg(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_attributes_bg(struct tty *, const struct grid_cell *);
void tty_cmd_bell(struct tty *, struct screen *, va_list); void tty_cmd_bell(struct tty *, struct screen *, u_int, va_list);
void tty_cmd_carriagereturn(struct tty *, struct screen *, va_list); void tty_cmd_carriagereturn(struct tty *, struct screen *, u_int, va_list);
void tty_cmd_cell(struct tty *, struct screen *, va_list); void tty_cmd_cell(struct tty *, struct screen *, u_int, va_list);
void tty_cmd_clearendofline(struct tty *, struct screen *, va_list); void tty_cmd_clearendofline(struct tty *, struct screen *, u_int, va_list);
void tty_cmd_clearendofscreen(struct tty *, struct screen *, va_list); void tty_cmd_clearendofscreen(struct tty *, struct screen *, u_int, va_list);
void tty_cmd_clearline(struct tty *, struct screen *, va_list); void tty_cmd_clearline(struct tty *, struct screen *, u_int, va_list);
void tty_cmd_clearscreen(struct tty *, struct screen *, va_list); void tty_cmd_clearscreen(struct tty *, struct screen *, u_int, va_list);
void tty_cmd_clearstartofline(struct tty *, struct screen *, va_list); void tty_cmd_clearstartofline(struct tty *, struct screen *, u_int, va_list);
void tty_cmd_clearstartofscreen(struct tty *, struct screen *, va_list); void tty_cmd_clearstartofscreen(struct tty *, struct screen *, u_int, va_list);
void tty_cmd_cursordown(struct tty *, struct screen *, va_list); void tty_cmd_cursormode(struct tty *, struct screen *, u_int, va_list);
void tty_cmd_cursorleft(struct tty *, struct screen *, va_list); void tty_cmd_deletecharacter(struct tty *, struct screen *, u_int, va_list);
void tty_cmd_cursormode(struct tty *, struct screen *, va_list); void tty_cmd_deleteline(struct tty *, struct screen *, u_int, va_list);
void tty_cmd_cursormove(struct tty *, struct screen *, va_list); void tty_cmd_insertcharacter(struct tty *, struct screen *, u_int, va_list);
void tty_cmd_cursorright(struct tty *, struct screen *, va_list); void tty_cmd_insertline(struct tty *, struct screen *, u_int, va_list);
void tty_cmd_cursorup(struct tty *, struct screen *, va_list); void tty_cmd_insertmode(struct tty *, struct screen *, u_int, va_list);
void tty_cmd_deletecharacter(struct tty *, struct screen *, va_list); void tty_cmd_kcursormode(struct tty *, struct screen *, u_int, va_list);
void tty_cmd_deleteline(struct tty *, struct screen *, va_list); void tty_cmd_kkeypadmode(struct tty *, struct screen *, u_int, va_list);
void tty_cmd_insertcharacter(struct tty *, struct screen *, va_list); void tty_cmd_linefeed(struct tty *, struct screen *, u_int, va_list);
void tty_cmd_insertline(struct tty *, struct screen *, va_list); void tty_cmd_mousemode(struct tty *, struct screen *, u_int, va_list);
void tty_cmd_insertmode(struct tty *, struct screen *, va_list); void tty_cmd_reverseindex(struct tty *, struct screen *, u_int, 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) = { void (*tty_cmds[])(struct tty *, struct screen *, u_int, va_list) = {
tty_cmd_bell,
tty_cmd_carriagereturn,
tty_cmd_cell, tty_cmd_cell,
tty_cmd_clearendofline, tty_cmd_clearendofline,
tty_cmd_clearendofscreen, tty_cmd_clearendofscreen,
@ -82,12 +70,7 @@ void (*tty_cmds[])(struct tty *, struct screen *, va_list) = {
tty_cmd_clearscreen, tty_cmd_clearscreen,
tty_cmd_clearstartofline, tty_cmd_clearstartofline,
tty_cmd_clearstartofscreen, tty_cmd_clearstartofscreen,
tty_cmd_cursordown,
tty_cmd_cursorleft,
tty_cmd_cursormode, tty_cmd_cursormode,
tty_cmd_cursormove,
tty_cmd_cursorright,
tty_cmd_cursorup,
tty_cmd_deletecharacter, tty_cmd_deletecharacter,
tty_cmd_deleteline, tty_cmd_deleteline,
tty_cmd_insertcharacter, tty_cmd_insertcharacter,
@ -98,7 +81,6 @@ void (*tty_cmds[])(struct tty *, struct screen *, va_list) = {
tty_cmd_linefeed, tty_cmd_linefeed,
tty_cmd_mousemode, tty_cmd_mousemode,
tty_cmd_reverseindex, tty_cmd_reverseindex,
tty_cmd_scrollregion,
}; };
void void
@ -138,6 +120,9 @@ tty_open(struct tty *tty, char **cause)
else else
tty->log_fd = -1; tty->log_fd = -1;
tty->cx = UINT_MAX;
tty->cy = UINT_MAX;
if ((tty->term = tty_term_find(tty->termname, tty->fd, cause)) == NULL) if ((tty->term = tty_term_find(tty->termname, tty->fd, cause)) == NULL)
goto error; goto error;
@ -314,6 +299,8 @@ tty_putc(struct tty *tty, char ch)
ch = tty_get_acs(tty, ch); ch = tty_get_acs(tty, ch);
buffer_write8(tty->out, ch); buffer_write8(tty->out, ch);
tty->cx++; /* This is right most of the time. */
if (tty->log_fd != -1) if (tty->log_fd != -1)
write(tty->log_fd, &ch, 1); write(tty->log_fd, &ch, 1);
} }
@ -344,72 +331,35 @@ tty_emulate_repeat(
} }
void 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_list ap;
va_start(ap, cmd); va_start(ap, cmd);
tty_vwrite(tty, s, cmd, ap); tty_vwrite(tty, s, oy, cmd, ap);
va_end(ap); va_end(ap);
} }
void 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) if (tty->flags & TTY_FREEZE || tty->term == NULL)
return; return;
if (tty_cmds[cmd] != NULL) if (tty_cmds[cmd] != NULL)
tty_cmds[cmd](tty, s, ap); tty_cmds[cmd](tty, s, oy, ap);
} }
void void
tty_cmd_cursorup(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_emulate_repeat(tty, TTYC_CUU, TTYC_CUU1, ua);
}
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)
{ {
u_int ua; u_int ua;
ua = va_arg(ap, u_int); ua = va_arg(ap, u_int);
tty_reset(tty); tty_reset(tty);
tty_cursor(tty, s->cx, s->cy, oy);
if (tty_term_has(tty->term, TTYC_ICH) || if (tty_term_has(tty->term, TTYC_ICH) ||
tty_term_has(tty->term, TTYC_ICH1)) 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) while (ua-- > 0)
tty_putc(tty, ' '); tty_putc(tty, ' ');
tty_putcode(tty, TTYC_RMIR); 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 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; u_int ua;
ua = va_arg(ap, u_int); ua = va_arg(ap, u_int);
tty_reset(tty); tty_reset(tty);
tty_cursor(tty, s->cx, s->cy, oy);
tty_emulate_repeat(tty, TTYC_DCH, TTYC_DCH1, ua); tty_emulate_repeat(tty, TTYC_DCH, TTYC_DCH1, ua);
} }
void 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; u_int ua;
ua = va_arg(ap, u_int); ua = va_arg(ap, u_int);
tty_reset(tty); 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); tty_emulate_repeat(tty, TTYC_IL, TTYC_IL1, ua);
} }
void 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; u_int ua;
ua = va_arg(ap, u_int); ua = va_arg(ap, u_int);
tty_reset(tty); 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); tty_emulate_repeat(tty, TTYC_DL, TTYC_DL1, ua);
} }
void 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; u_int i;
tty_reset(tty); tty_reset(tty);
tty_cursor(tty, s->cx, s->cy, oy);
if (tty_term_has(tty->term, TTYC_EL)) { 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_putcode(tty, TTYC_EL);
tty_putcode2(tty, TTYC_CUP, s->cy, s->cx); tty_putcode2(tty, TTYC_CUP, oy + s->cy, s->cx);
} else { } 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++) for (i = 0; i < screen_size_x(s); i++)
tty_putc(tty, ' '); tty_putc(tty, ' ');
tty_putcode2(tty, TTYC_CUP, s->cy, s->cx); tty_putcode2(tty, TTYC_CUP, oy + s->cy, s->cx);
} }
} }
void 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; u_int i;
tty_reset(tty); tty_reset(tty);
tty_cursor(tty, s->cx, s->cy, oy);
if (tty_term_has(tty->term, TTYC_EL)) if (tty_term_has(tty->term, TTYC_EL))
tty_putcode(tty, TTYC_EL); tty_putcode(tty, TTYC_EL);
else { 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++) for (i = s->cx; i < screen_size_x(s); i++)
tty_putc(tty, ' '); tty_putc(tty, ' ');
tty_putcode2(tty, TTYC_CUP, s->cy, s->cx); tty_putcode2(tty, TTYC_CUP, oy + s->cy, s->cx);
} }
} }
void 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; u_int i;
tty_reset(tty); tty_reset(tty);
tty_cursor(tty, s->cx, s->cy, oy);
if (tty_term_has(tty->term, TTYC_EL1)) if (tty_term_has(tty->term, TTYC_EL1))
tty_putcode(tty, TTYC_EL1); tty_putcode(tty, TTYC_EL1);
else { 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++) for (i = 0; i < s->cx + 1; i++)
tty_putc(tty, ' '); tty_putc(tty, ' ');
tty_putcode2(tty, TTYC_CUP, s->cy, s->cx); tty_putcode2(tty, TTYC_CUP, oy + s->cy, s->cx);
} }
} }
void void
tty_cmd_cursormove(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, ub; int ua;
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)
{
u_int ua;
ua = va_arg(ap, int); ua = va_arg(ap, int);
if (tty->cursor == ua)
return;
tty->cursor = ua;
if (ua && !(tty->flags & TTY_NOCURSOR)) if (ua && !(tty->flags & TTY_NOCURSOR))
tty_putcode(tty, TTYC_CNORM); tty_putcode(tty, TTYC_CNORM);
else else
@ -538,28 +496,21 @@ tty_cmd_cursormode(struct tty *tty, unused struct screen *s, va_list ap)
void void
tty_cmd_reverseindex( 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_reset(tty);
tty_region(tty, s, oy);
tty_cursor(tty, s->cx, s->cy, oy);
tty_putcode(tty, TTYC_RI); tty_putcode(tty, TTYC_RI);
} }
void void
tty_cmd_scrollregion(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, ub; int ua;
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)
{
u_int ua;
ua = va_arg(ap, int); ua = va_arg(ap, int);
@ -573,9 +524,10 @@ tty_cmd_insertmode(unused struct tty *tty, unused struct screen *s, va_list ap)
} }
void 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)) if (!tty_term_has(tty->term, TTYC_KMOUS))
return; return;
@ -589,52 +541,45 @@ tty_cmd_mousemode(struct tty *tty, unused struct screen *s, va_list ap)
} }
void void
tty_cmd_kcursormode( tty_cmd_kcursormode(unused struct tty *tty,
unused struct tty *tty, unused struct screen *s, unused va_list ap) unused struct screen *s, unused u_int oy, unused va_list ap)
{ {
} }
void void
tty_cmd_kkeypadmode( tty_cmd_kkeypadmode(unused struct tty *tty,
unused struct tty *tty, unused struct screen *s, unused va_list ap) unused struct screen *s, unused u_int oy, unused va_list ap)
{ {
} }
void 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_reset(tty);
tty_region(tty, s, oy);
tty_cursor(tty, s->cx, s->cy, oy);
tty_putc(tty, '\n'); tty_putc(tty, '\n');
} }
void void
tty_cmd_carriagereturn( tty_cmd_bell(struct tty *tty,
struct tty *tty, unused struct screen *s, unused va_list ap) unused struct screen *s, unused u_int oy, 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_putcode(tty, TTYC_BEL); tty_putcode(tty, TTYC_BEL);
} }
void 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; u_int i, j;
tty_reset(tty); tty_reset(tty);
tty_cursor(tty, s->cx, s->cy, oy);
if (tty_term_has(tty->term, TTYC_EL)) { 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); tty_putcode(tty, TTYC_EL);
if (i != screen_size_y(s) - 1) if (i != screen_size_y(s) - 1)
tty_emulate_repeat(tty, TTYC_CUD, TTYC_CUD1, 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 { } else {
for (i = s->cx; i < screen_size_y(s); i++) for (i = s->cx; i < screen_size_y(s); i++)
tty_putc(tty, ' '); 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++) for (i = 0; i < screen_size_x(s); i++)
tty_putc(tty, ' '); tty_putc(tty, ' ');
} }
} }
tty_putcode2(tty, TTYC_CUP, s->cy, s->cx); tty_putcode2(tty, TTYC_CUP, oy + s->cy, s->cx);
} }
void 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; u_int i, j;
tty_reset(tty); 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)) { 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_putcode(tty, TTYC_EL);
tty_emulate_repeat(tty, TTYC_CUD, TTYC_CUD1, 1); 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 { } 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++) for (i = 0; i < screen_size_x(s); i++)
tty_putc(tty, ' '); tty_putc(tty, ' ');
} }
} }
for (i = 0; i < s->cx; i++) for (i = 0; i < s->cx; i++)
tty_putc(tty, ' '); tty_putc(tty, ' ');
tty_putcode2(tty, TTYC_CUP, s->cy, s->cx); tty_putcode2(tty, TTYC_CUP, oy + s->cy, s->cx);
} }
void 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; u_int i, j;
tty_reset(tty); 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)) { if (tty_term_has(tty->term, TTYC_EL)) {
for (i = 0; i < screen_size_y(s); i++) { for (i = 0; i < screen_size_y(s); i++) {
tty_putcode(tty, TTYC_EL); 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_putc(tty, ' ');
} }
} }
tty_putcode2(tty, TTYC_CUP, s->cy, s->cx); tty_putcode2(tty, TTYC_CUP, oy + s->cy, s->cx);
} }
void 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; struct grid_cell *gc;
u_int i, width; u_int i, width;
u_char out[4]; u_char out[4];
tty_cursor(tty, s->cx, s->cy, oy);
gc = va_arg(ap, struct grid_cell *); gc = va_arg(ap, struct grid_cell *);
/* If this is a padding character, do nothing. */ /* If this is a padding character, do nothing. */
@ -756,6 +707,28 @@ tty_reset(struct tty *tty)
memcpy(tc, &grid_default_cell, sizeof *tc); memcpy(tc, &grid_default_cell, sizeof *tc);
} }
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 void
tty_attributes(struct tty *tty, const struct grid_cell *gc) tty_attributes(struct tty *tty, const struct grid_cell *gc)
{ {

View File

@ -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> * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@ -23,13 +23,13 @@
#include "tmux.h" #include "tmux.h"
struct screen *window_clock_init(struct window *); struct screen *window_clock_init(struct window_pane *);
void window_clock_free(struct window *); void window_clock_free(struct window_pane *);
void window_clock_resize(struct window *, u_int, u_int); void window_clock_resize(struct window_pane *, u_int, u_int);
void window_clock_key(struct window *, struct client *, int); void window_clock_key(struct window_pane *, struct client *, int);
void window_clock_timer(struct window *); 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 = { const struct window_mode window_clock_mode = {
window_clock_init, window_clock_init,
@ -45,52 +45,53 @@ struct window_clock_mode_data {
}; };
struct screen * struct screen *
window_clock_init(struct window *w) window_clock_init(struct window_pane *wp)
{ {
struct window_clock_mode_data *data; struct window_clock_mode_data *data;
struct screen *s; struct screen *s;
w->modedata = data = xmalloc(sizeof *data); wp->modedata = data = xmalloc(sizeof *data);
data->tim = time(NULL); data->tim = time(NULL);
s = &data->screen; 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; s->mode &= ~MODE_CURSOR;
window_clock_draw_screen(w); window_clock_draw_screen(wp);
return (s); return (s);
} }
void 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); screen_free(&data->screen);
xfree(data); xfree(data);
} }
void 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; struct screen *s = &data->screen;
screen_resize(s, sx, sy); screen_resize(s, sx, sy);
window_clock_draw_screen(w); window_clock_draw_screen(wp);
} }
void 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 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; struct tm *now, *then;
time_t t; time_t t;
@ -101,22 +102,22 @@ window_clock_timer(struct window *w)
return; return;
data->tim = t; data->tim = t;
window_clock_draw_screen(w); window_clock_draw_screen(wp);
server_redraw_window(w); server_redraw_window(wp->window);
} }
void 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; struct screen_write_ctx ctx;
u_int colour; u_int colour;
int style; int style;
colour = options_get_number(&w->options, "clock-mode-colour"); colour = options_get_number(&wp->window->options, "clock-mode-colour");
style = options_get_number(&w->options, "clock-mode-style"); 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); clock_draw(&ctx, colour, style);
screen_write_stop(&ctx); screen_write_stop(&ctx);
} }

View File

@ -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> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -22,42 +22,42 @@
#include "tmux.h" #include "tmux.h"
struct screen *window_copy_init(struct window *); struct screen *window_copy_init(struct window_pane *);
void window_copy_free(struct window *); void window_copy_free(struct window_pane *);
void window_copy_resize(struct window *, u_int, u_int); void window_copy_resize(struct window_pane *, u_int, u_int);
void window_copy_key(struct window *, struct client *, 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_lines(struct window_pane *, u_int, u_int);
void window_copy_redraw_screen(struct window *); void window_copy_redraw_screen(struct window_pane *);
void window_copy_write_line( 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( 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( 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( 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_update_cursor(struct window_pane *);
void window_copy_start_selection(struct window *); void window_copy_start_selection(struct window_pane *);
int window_copy_update_selection(struct window *); int window_copy_update_selection(struct window_pane *);
void window_copy_copy_selection(struct window *, struct client *); void window_copy_copy_selection(struct window_pane *, struct client *);
void window_copy_copy_line( void window_copy_copy_line(
struct window *, char **, size_t *, u_int, u_int, u_int); struct window_pane *, char **, size_t *, u_int, u_int, u_int);
int window_copy_is_space(struct window *, u_int, u_int); int window_copy_is_space(struct window_pane *, u_int, u_int);
u_int window_copy_find_length(struct window *, u_int); u_int window_copy_find_length(struct window_pane *, u_int);
void window_copy_cursor_start_of_line(struct window *); void window_copy_cursor_start_of_line(struct window_pane *);
void window_copy_cursor_end_of_line(struct window *); void window_copy_cursor_end_of_line(struct window_pane *);
void window_copy_cursor_left(struct window *); void window_copy_cursor_left(struct window_pane *);
void window_copy_cursor_right(struct window *); void window_copy_cursor_right(struct window_pane *);
void window_copy_cursor_up(struct window *); void window_copy_cursor_up(struct window_pane *);
void window_copy_cursor_down(struct window *); void window_copy_cursor_down(struct window_pane *);
void window_copy_cursor_next_word(struct window *); void window_copy_cursor_next_word(struct window_pane *);
void window_copy_cursor_previous_word(struct window *); void window_copy_cursor_previous_word(struct window_pane *);
void window_copy_scroll_left(struct window *, u_int); void window_copy_scroll_left(struct window_pane *, u_int);
void window_copy_scroll_right(struct window *, u_int); void window_copy_scroll_right(struct window_pane *, u_int);
void window_copy_scroll_up(struct window *, u_int); void window_copy_scroll_up(struct window_pane *, u_int);
void window_copy_scroll_down(struct window *, u_int); void window_copy_scroll_down(struct window_pane *, u_int);
const struct window_mode window_copy_mode = { const struct window_mode window_copy_mode = {
window_copy_init, window_copy_init,
@ -81,27 +81,27 @@ struct window_copy_mode_data {
}; };
struct screen * struct screen *
window_copy_init(struct window *w) window_copy_init(struct window_pane *wp)
{ {
struct window_copy_mode_data *data; struct window_copy_mode_data *data;
struct screen *s; struct screen *s;
struct screen_write_ctx ctx; struct screen_write_ctx ctx;
u_int i; u_int i;
w->modedata = data = xmalloc(sizeof *data); wp->modedata = data = xmalloc(sizeof *data);
data->ox = 0; data->ox = 0;
data->oy = 0; data->oy = 0;
data->cx = w->base.cx; data->cx = wp->base.cx;
data->cy = w->base.cy; data->cy = wp->base.cy;
s = &data->screen; 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->cx = data->cx;
s->cy = data->cy; 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++) 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_cursormove(&ctx, data->cx, data->cy);
screen_write_stop(&ctx); screen_write_stop(&ctx);
@ -109,92 +109,92 @@ window_copy_init(struct window *w)
} }
void 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); screen_free(&data->screen);
xfree(data); xfree(data);
} }
void 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 *s = &data->screen;
struct screen_write_ctx ctx; struct screen_write_ctx ctx;
screen_resize(s, sx, sy); screen_resize(s, sx, sy);
screen_write_start(&ctx, s, NULL, NULL); screen_write_start(&ctx, NULL, s);
window_copy_write_lines(w, &ctx, 0, screen_size_y(s) - 1); window_copy_write_lines(wp, &ctx, 0, screen_size_y(s) - 1);
screen_write_stop(&ctx); screen_write_stop(&ctx);
window_copy_update_selection(w); window_copy_update_selection(wp);
} }
void 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; struct screen *s = &data->screen;
int table; 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)) { switch (mode_key_lookup(table, key)) {
case MODEKEY_QUIT: case MODEKEY_QUIT:
window_reset_mode(w); window_pane_reset_mode(wp);
break; break;
case MODEKEY_LEFT: case MODEKEY_LEFT:
window_copy_cursor_left(w); window_copy_cursor_left(wp);
return; return;
case MODEKEY_RIGHT: case MODEKEY_RIGHT:
window_copy_cursor_right(w); window_copy_cursor_right(wp);
return; return;
case MODEKEY_UP: case MODEKEY_UP:
window_copy_cursor_up(w); window_copy_cursor_up(wp);
return; return;
case MODEKEY_DOWN: case MODEKEY_DOWN:
window_copy_cursor_down(w); window_copy_cursor_down(wp);
return; return;
case MODEKEY_PPAGE: case MODEKEY_PPAGE:
if (data->oy + screen_size_y(s) > screen_hsize(&w->base)) if (data->oy + screen_size_y(s) > screen_hsize(&wp->base))
data->oy = screen_hsize(&w->base); data->oy = screen_hsize(&wp->base);
else else
data->oy += screen_size_y(s); data->oy += screen_size_y(s);
window_copy_update_selection(w); window_copy_update_selection(wp);
window_copy_redraw_screen(w); window_copy_redraw_screen(wp);
break; break;
case MODEKEY_NPAGE: case MODEKEY_NPAGE:
if (data->oy < screen_size_y(s)) if (data->oy < screen_size_y(s))
data->oy = 0; data->oy = 0;
else else
data->oy -= screen_size_y(s); data->oy -= screen_size_y(s);
window_copy_update_selection(w); window_copy_update_selection(wp);
window_copy_redraw_screen(w); window_copy_redraw_screen(wp);
break; break;
case MODEKEY_STARTSEL: case MODEKEY_STARTSEL:
window_copy_start_selection(w); window_copy_start_selection(wp);
break; break;
case MODEKEY_CLEARSEL: case MODEKEY_CLEARSEL:
screen_clear_selection(&data->screen); screen_clear_selection(&data->screen);
window_copy_redraw_screen(w); window_copy_redraw_screen(wp);
break; break;
case MODEKEY_COPYSEL: case MODEKEY_COPYSEL:
if (c != NULL && c->session != NULL) { if (c != NULL && c->session != NULL) {
window_copy_copy_selection(w, c); window_copy_copy_selection(wp, c);
window_reset_mode(w); window_pane_reset_mode(wp);
} }
break; break;
case MODEKEY_BOL: case MODEKEY_BOL:
window_copy_cursor_start_of_line(w); window_copy_cursor_start_of_line(wp);
break; break;
case MODEKEY_EOL: case MODEKEY_EOL:
window_copy_cursor_end_of_line(w); window_copy_cursor_end_of_line(wp);
break; break;
case MODEKEY_NWORD: case MODEKEY_NWORD:
window_copy_cursor_next_word(w); window_copy_cursor_next_word(wp);
break; break;
case MODEKEY_PWORD: case MODEKEY_PWORD:
window_copy_cursor_previous_word(w); window_copy_cursor_previous_word(wp);
break; break;
default: default:
break; break;
@ -202,9 +202,9 @@ window_copy_key(struct window *w, struct client *c, int key)
} }
void 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 screen *s = &data->screen;
struct grid_cell gc; struct grid_cell gc;
char hdr[32]; 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) { if (py == 0) {
memcpy(&gc, &grid_default_cell, sizeof gc); memcpy(&gc, &grid_default_cell, sizeof gc);
size = xsnprintf(hdr, sizeof hdr, size = xsnprintf(hdr, sizeof hdr,
"[%u,%u/%u]", data->ox, data->oy, screen_hsize(&w->base)); "[%u,%u/%u]", data->ox, data->oy, screen_hsize(&wp->base));
gc.fg = options_get_number(&w->options, "mode-fg"); gc.fg = options_get_number(&wp->window->options, "mode-fg");
gc.bg = options_get_number(&w->options, "mode-bg"); gc.bg = options_get_number(&wp->window->options, "mode-bg");
screen_write_cursormove(ctx, screen_size_x(s) - size, 0); screen_write_cursormove(ctx, screen_size_x(s) - size, 0);
screen_write_puts(ctx, &gc, "%s", hdr); screen_write_puts(ctx, &gc, "%s", hdr);
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; size = 0;
screen_write_cursormove(ctx, 0, py); 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); data->oy) + py, screen_size_x(s) - size, 1);
} }
void void
window_copy_write_lines( 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; u_int yy;
for (yy = py; yy < py + ny; yy++) for (yy = py; yy < py + ny; yy++)
window_copy_write_line(w, ctx, py); window_copy_write_line(wp, ctx, py);
} }
void void
window_copy_write_column( 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; struct screen *s = &data->screen;
screen_write_cursormove(ctx, px, 0); screen_write_cursormove(ctx, px, 0);
screen_write_copy(ctx, &w->base, screen_write_copy(ctx, &wp->base,
data->ox, screen_hsize(&w->base) - data->oy, 1, screen_size_y(s)); data->ox, screen_hsize(&wp->base) - data->oy, 1, screen_size_y(s));
} }
void void
window_copy_write_columns( 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; u_int xx;
for (xx = px; xx < px + nx; xx++) for (xx = px; xx < px + nx; xx++)
window_copy_write_column(w, ctx, px); window_copy_write_column(wp, ctx, px);
} }
void 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; struct screen_write_ctx ctx;
u_int i; u_int i;
screen_write_start_window(&ctx, w); screen_write_start(&ctx, wp, NULL);
for (i = py; i < py + ny; i++) 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_cursormove(&ctx, data->cx, data->cy);
screen_write_stop(&ctx); screen_write_stop(&ctx);
} }
void 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 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; 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_cursormove(&ctx, data->cx, data->cy);
screen_write_stop(&ctx); screen_write_stop(&ctx);
} }
void 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; struct screen *s = &data->screen;
data->selx = data->cx + data->ox; 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; s->sel.flag = 1;
window_copy_update_selection(w); window_copy_update_selection(wp);
} }
int 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 screen *s = &data->screen;
struct grid_cell gc; struct grid_cell gc;
u_int sx, sy, tx, ty; u_int sx, sy, tx, ty;
@ -318,12 +318,12 @@ window_copy_update_selection(struct window *w)
/* Set colours. */ /* Set colours. */
memcpy(&gc, &grid_default_cell, sizeof gc); memcpy(&gc, &grid_default_cell, sizeof gc);
gc.fg = options_get_number(&w->options, "mode-fg"); gc.fg = options_get_number(&wp->window->options, "mode-fg");
gc.bg = options_get_number(&w->options, "mode-bg"); gc.bg = options_get_number(&wp->window->options, "mode-bg");
/* Find top-left of screen. */ /* Find top-left of screen. */
tx = data->ox; tx = data->ox;
ty = screen_hsize(&w->base) - data->oy; ty = screen_hsize(&wp->base) - data->oy;
/* Adjust the selection. */ /* Adjust the selection. */
sx = data->selx; sx = data->selx;
@ -357,9 +357,9 @@ window_copy_update_selection(struct window *w)
} }
void 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; struct screen *s = &data->screen;
char *buf; char *buf;
size_t off; size_t off;
@ -380,7 +380,7 @@ window_copy_copy_selection(struct window *w, struct client *c)
/* Find start and end. */ /* Find start and end. */
xx = data->cx + data->ox; 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)) { if (xx < data->selx || (yy == data->sely && xx < data->selx)) {
sx = xx; sy = yy; sx = xx; sy = yy;
ex = data->selx; ey = data->sely; 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. */ /* Trim ex to end of line. */
xx = window_copy_find_length(w, ey); xx = window_copy_find_length(wp, ey);
if (ex > xx) if (ex > xx)
ex = xx; ex = xx;
/* Copy the lines. */ /* Copy the lines. */
if (sy == ey) if (sy == ey)
window_copy_copy_line(w, &buf, &off, sy, sx, ex); window_copy_copy_line(wp, &buf, &off, sy, sx, ex);
else { else {
xx = window_copy_find_length(w, sy); xx = window_copy_find_length(wp, sy);
window_copy_copy_line(w, &buf, &off, sy, sx, xx); window_copy_copy_line(wp, &buf, &off, sy, sx, xx);
if (ey - sy > 1) { if (ey - sy > 1) {
for (i = sy + 1; i < ey - 1; i++) { for (i = sy + 1; i < ey - 1; i++) {
xx = window_copy_find_length(w, i); xx = window_copy_find_length(wp, i);
window_copy_copy_line(w, &buf, &off, i, 0, xx); 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. */ /* Terminate buffer, overwriting final \n. */
@ -421,7 +421,7 @@ window_copy_copy_selection(struct window *w, struct client *c)
void void
window_copy_copy_line( 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; const struct grid_cell *gc;
u_char i, j, xx, data[4]; u_char i, j, xx, data[4];
@ -429,7 +429,7 @@ window_copy_copy_line(
if (sx > ex) if (sx > ex)
return; return;
xx = window_copy_find_length(w, sy); xx = window_copy_find_length(wp, sy);
if (ex > xx) if (ex > xx)
ex = xx; ex = xx;
if (sx > xx) if (sx > xx)
@ -437,7 +437,7 @@ window_copy_copy_line(
if (sx < ex) { if (sx < ex) {
for (i = sx; i < ex; i++) { 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); utf8_split(gc->data, data);
*buf = xrealloc(*buf, 1, (*off) + 4); *buf = xrealloc(*buf, 1, (*off) + 4);
@ -455,12 +455,12 @@ window_copy_copy_line(
} }
int 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 struct grid_cell *gc;
const char *spaces = " -_@"; 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) if (gc->flags & GRID_FLAG_PADDING)
return (0); return (0);
if (gc->data == 0x00 || gc->data > 0xff) 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 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; const struct grid_cell *gc;
u_int px; u_int px;
px = w->base.grid->size[py]; px = wp->base.grid->size[py];
while (px > 0) { 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) if (gc->data != 0x20)
break; break;
px--; px--;
@ -485,29 +485,29 @@ window_copy_find_length(struct window *w, u_int py)
} }
void 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) if (data->ox != 0)
window_copy_scroll_right(w, data->ox); window_copy_scroll_right(wp, data->ox);
data->cx = 0; data->cx = 0;
if (window_copy_update_selection(w)) if (window_copy_update_selection(wp))
window_copy_redraw_lines(w, data->cy, 1); window_copy_redraw_lines(wp, data->cy, 1);
else else
window_copy_update_cursor(w); window_copy_update_cursor(wp);
} }
void 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; struct screen *s = &data->screen;
u_int px, py; u_int px, py;
py = screen_hsize(&w->base) + data->cy - data->oy; py = screen_hsize(&wp->base) + data->cy - data->oy;
px = window_copy_find_length(w, py); px = window_copy_find_length(wp, py);
/* On screen. */ /* On screen. */
if (px > data->ox && px <= data->ox + screen_size_x(s) - 1) 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) { if (px > data->ox + screen_size_x(s) - 1) {
/* Move cursor to last and scroll screen. */ /* Move cursor to last and scroll screen. */
window_copy_scroll_left( 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; 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 <= data->ox) {
if (px < screen_size_x(s) - 1) { if (px < screen_size_x(s) - 1) {
/* Short enough to fit on screen. */ /* Short enough to fit on screen. */
window_copy_scroll_right(w, data->ox); window_copy_scroll_right(wp, data->ox);
data->cx = px; data->cx = px;
} else { } else {
/* Too long to fit on screen. */ /* Too long to fit on screen. */
window_copy_scroll_right( 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; data->cx = screen_size_x(s) - 1;
} }
} }
if (window_copy_update_selection(w)) if (window_copy_update_selection(wp))
window_copy_redraw_lines(w, data->cy, 1); window_copy_redraw_lines(wp, data->cy, 1);
else else
window_copy_update_cursor(w); window_copy_update_cursor(wp);
} }
void 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->cx == 0) {
if (data->ox > 0) if (data->ox > 0)
window_copy_scroll_right(w, 1); window_copy_scroll_right(wp, 1);
else { else {
window_copy_cursor_up(w); window_copy_cursor_up(wp);
window_copy_cursor_end_of_line(w); window_copy_cursor_end_of_line(wp);
} }
} else { } else {
data->cx--; data->cx--;
if (window_copy_update_selection(w)) if (window_copy_update_selection(wp))
window_copy_redraw_lines(w, data->cy, 1); window_copy_redraw_lines(wp, data->cy, 1);
else else
window_copy_update_cursor(w); window_copy_update_cursor(wp);
} }
} }
void 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; u_int px, py;
py = screen_hsize(&w->base) + data->cy - data->oy; py = screen_hsize(&wp->base) + data->cy - data->oy;
px = window_copy_find_length(w, py); px = window_copy_find_length(wp, py);
if (data->cx >= px) { if (data->cx >= px) {
window_copy_cursor_start_of_line(w); window_copy_cursor_start_of_line(wp);
window_copy_cursor_down(w); window_copy_cursor_down(wp);
} else { } else {
data->cx++; data->cx++;
if (window_copy_update_selection(w)) if (window_copy_update_selection(wp))
window_copy_redraw_lines(w, data->cy, 1); window_copy_redraw_lines(wp, data->cy, 1);
else else
window_copy_update_cursor(w); window_copy_update_cursor(wp);
} }
} }
void 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; u_int ox, oy, px, py;
oy = screen_hsize(&w->base) + data->cy - data->oy; oy = screen_hsize(&wp->base) + data->cy - data->oy;
ox = window_copy_find_length(w, oy); ox = window_copy_find_length(wp, oy);
if (data->cy == 0) if (data->cy == 0)
window_copy_scroll_down(w, 1); window_copy_scroll_down(wp, 1);
else { else {
data->cy--; data->cy--;
if (window_copy_update_selection(w)) if (window_copy_update_selection(wp))
window_copy_redraw_lines(w, data->cy, 2); window_copy_redraw_lines(wp, data->cy, 2);
else else
window_copy_update_cursor(w); window_copy_update_cursor(wp);
} }
py = screen_hsize(&w->base) + data->cy - data->oy; py = screen_hsize(&wp->base) + data->cy - data->oy;
px = window_copy_find_length(w, py); px = window_copy_find_length(wp, py);
if (data->cx + data->ox >= px || data->cx + data->ox >= ox) 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 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; struct screen *s = &data->screen;
u_int ox, oy, px, py; u_int ox, oy, px, py;
oy = screen_hsize(&w->base) + data->cy - data->oy; oy = screen_hsize(&wp->base) + data->cy - data->oy;
ox = window_copy_find_length(w, oy); ox = window_copy_find_length(wp, oy);
if (data->cy == screen_size_y(s) - 1) if (data->cy == screen_size_y(s) - 1)
window_copy_scroll_up(w, 1); window_copy_scroll_up(wp, 1);
else { else {
data->cy++; data->cy++;
if (window_copy_update_selection(w)) if (window_copy_update_selection(wp))
window_copy_redraw_lines(w, data->cy - 1, 2); window_copy_redraw_lines(wp, data->cy - 1, 2);
else else
window_copy_update_cursor(w); window_copy_update_cursor(wp);
} }
py = screen_hsize(&w->base) + data->cy - data->oy; py = screen_hsize(&wp->base) + data->cy - data->oy;
px = window_copy_find_length(w, py); px = window_copy_find_length(wp, py);
if (data->cx + data->ox >= px || data->cx + data->ox >= ox) 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 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; struct screen *s = &data->screen;
u_int px, py, xx, skip; u_int px, py, xx, skip;
px = data->ox + data->cx; px = data->ox + data->cx;
py = screen_hsize(&w->base) + data->cy - data->oy; py = screen_hsize(&wp->base) + data->cy - data->oy;
xx = window_copy_find_length(w, py); xx = window_copy_find_length(wp, py);
skip = 1; skip = 1;
if (px < xx) { if (px < xx) {
/* If currently on a space, skip space. */ /* 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; skip = 0;
} else } else
skip = 0; skip = 0;
@ -668,21 +668,21 @@ window_copy_cursor_next_word(struct window *w)
} }
px = 0; px = 0;
window_copy_cursor_down(w); window_copy_cursor_down(wp);
py =screen_hsize( py =screen_hsize(
&w->base) + data->cy - data->oy; &wp->base) + data->cy - data->oy;
xx = window_copy_find_length(w, py); xx = window_copy_find_length(wp, py);
} }
} }
if (skip) { if (skip) {
/* Currently skipping non-space (until space). */ /* Currently skipping non-space (until space). */
if (window_copy_is_space(w, px, py)) if (window_copy_is_space(wp, px, py))
break; break;
} else { } else {
/* Currently skipping space (until non-space). */ /* Currently skipping space (until non-space). */
if (!window_copy_is_space(w, px, py)) if (!window_copy_is_space(wp, px, py))
skip = 1; skip = 1;
} }
@ -698,7 +698,7 @@ out:
if (px > data->ox + screen_size_x(s) - 1) { if (px > data->ox + screen_size_x(s) - 1) {
/* Move cursor to last and scroll screen. */ /* Move cursor to last and scroll screen. */
window_copy_scroll_left( 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; data->cx = screen_size_x(s) - 1;
} }
@ -706,36 +706,36 @@ out:
if (px <= data->ox) { if (px <= data->ox) {
if (px < screen_size_x(s) - 1) { if (px < screen_size_x(s) - 1) {
/* Short enough to fit on screen. */ /* Short enough to fit on screen. */
window_copy_scroll_right(w, data->ox); window_copy_scroll_right(wp, data->ox);
data->cx = px; data->cx = px;
} else { } else {
/* Too long to fit on screen. */ /* Too long to fit on screen. */
window_copy_scroll_right( 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; data->cx = screen_size_x(s) - 1;
} }
} }
if (window_copy_update_selection(w)) if (window_copy_update_selection(wp))
window_copy_redraw_lines(w, data->cy, 1); window_copy_redraw_lines(wp, data->cy, 1);
else else
window_copy_update_cursor(w); window_copy_update_cursor(wp);
} }
void 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; struct screen *s = &data->screen;
u_int ox, px, py, skip; u_int ox, px, py, skip;
ox = px = data->ox + data->cx; 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; skip = 1;
if (px != 0) { if (px != 0) {
/* If currently on a space, skip space. */ /* 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; skip = 0;
} }
for (;;) { for (;;) {
@ -745,26 +745,26 @@ window_copy_cursor_previous_word(struct window *w)
while (px == 0) { while (px == 0) {
if (data->cy == 0 && if (data->cy == 0 &&
(screen_hsize(&w->base) == 0 || (screen_hsize(&wp->base) == 0 ||
data->oy >= screen_hsize(&w->base) - 1)) data->oy >= screen_hsize(&wp->base) - 1))
goto out; goto out;
window_copy_cursor_up(w); window_copy_cursor_up(wp);
py = screen_hsize( py = screen_hsize(
&w->base) + data->cy - data->oy; &wp->base) + data->cy - data->oy;
px = window_copy_find_length(w, py); px = window_copy_find_length(wp, py);
} }
goto out; goto out;
} }
if (skip) { if (skip) {
/* Currently skipping non-space (until space). */ /* 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; skip = 0;
} else { } else {
/* Currently skipping space (until non-space). */ /* 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; break;
} }
@ -780,7 +780,7 @@ out:
if (px > data->ox + screen_size_x(s) - 1) { if (px > data->ox + screen_size_x(s) - 1) {
/* Move cursor to last and scroll screen. */ /* Move cursor to last and scroll screen. */
window_copy_scroll_left( 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; data->cx = screen_size_x(s) - 1;
} }
@ -788,26 +788,26 @@ out:
if (px <= data->ox) { if (px <= data->ox) {
if (px < screen_size_x(s) - 1) { if (px < screen_size_x(s) - 1) {
/* Short enough to fit on screen. */ /* Short enough to fit on screen. */
window_copy_scroll_right(w, data->ox); window_copy_scroll_right(wp, data->ox);
data->cx = px; data->cx = px;
} else { } else {
/* Too long to fit on screen. */ /* Too long to fit on screen. */
window_copy_scroll_right( 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; data->cx = screen_size_x(s) - 1;
} }
} }
if (window_copy_update_selection(w)) if (window_copy_update_selection(wp))
window_copy_redraw_lines(w, data->cy, 1); window_copy_redraw_lines(wp, data->cy, 1);
else else
window_copy_update_cursor(w); window_copy_update_cursor(wp);
} }
void 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 *s = &data->screen;
struct screen_write_ctx ctx; struct screen_write_ctx ctx;
u_int i; u_int i;
@ -817,27 +817,27 @@ window_copy_scroll_left(struct window *w, u_int nx)
if (nx == 0) if (nx == 0)
return; return;
data->ox += nx; 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++) { for (i = 1; i < screen_size_y(s); i++) {
screen_write_cursormove(&ctx, 0, i); screen_write_cursormove(&ctx, 0, i);
screen_write_deletecharacter(&ctx, nx); screen_write_deletecharacter(&ctx, nx);
} }
window_copy_write_columns(w, &ctx, screen_size_x(s) - nx, nx); window_copy_write_columns(wp, &ctx, screen_size_x(s) - nx, nx);
window_copy_write_line(w, &ctx, 0); window_copy_write_line(wp, &ctx, 0);
if (s->sel.flag) { if (s->sel.flag) {
window_copy_update_selection(w); window_copy_update_selection(wp);
window_copy_write_lines(w, &ctx, data->cy, 1); window_copy_write_lines(wp, &ctx, data->cy, 1);
} }
screen_write_cursormove(&ctx, data->cx, data->cy); screen_write_cursormove(&ctx, data->cx, data->cy);
screen_write_stop(&ctx); screen_write_stop(&ctx);
} }
void 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 *s = &data->screen;
struct screen_write_ctx ctx; struct screen_write_ctx ctx;
u_int i; u_int i;
@ -847,25 +847,25 @@ window_copy_scroll_right(struct window *w, u_int nx)
if (nx == 0) if (nx == 0)
return; return;
data->ox -= nx; 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++) { for (i = 1; i < screen_size_y(s); i++) {
screen_write_cursormove(&ctx, 0, i); screen_write_cursormove(&ctx, 0, i);
screen_write_insertcharacter(&ctx, nx); screen_write_insertcharacter(&ctx, nx);
} }
window_copy_write_columns(w, &ctx, 0, nx); window_copy_write_columns(wp, &ctx, 0, nx);
window_copy_write_line(w, &ctx, 0); window_copy_write_line(wp, &ctx, 0);
if (s->sel.flag) 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_cursormove(&ctx, data->cx, data->cy);
screen_write_stop(&ctx); screen_write_stop(&ctx);
} }
void 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 *s = &data->screen;
struct screen_write_ctx ctx; struct screen_write_ctx ctx;
@ -874,45 +874,45 @@ window_copy_scroll_up(struct window *w, u_int ny)
if (ny == 0) if (ny == 0)
return; return;
data->oy -= ny; 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_cursormove(&ctx, 0, 0);
screen_write_deleteline(&ctx, ny); screen_write_deleteline(&ctx, ny);
window_copy_write_lines(w, &ctx, screen_size_y(s) - ny, ny); window_copy_write_lines(wp, &ctx, screen_size_y(s) - ny, ny);
window_copy_write_line(w, &ctx, 0); window_copy_write_line(wp, &ctx, 0);
window_copy_write_line(w, &ctx, 1); window_copy_write_line(wp, &ctx, 1);
if (s->sel.flag && screen_size_y(s) > ny) 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_cursormove(&ctx, data->cx, data->cy);
screen_write_stop(&ctx); screen_write_stop(&ctx);
} }
void 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 *s = &data->screen;
struct screen_write_ctx ctx; struct screen_write_ctx ctx;
if (ny > screen_hsize(&w->base)) if (ny > screen_hsize(&wp->base))
return; return;
if (data->oy > screen_hsize(&w->base) - ny) if (data->oy > screen_hsize(&wp->base) - ny)
ny = screen_hsize(&w->base) - data->oy; ny = screen_hsize(&wp->base) - data->oy;
if (ny == 0) if (ny == 0)
return; return;
data->oy += ny; 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_cursormove(&ctx, 0, 0);
screen_write_insertline(&ctx, ny); 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) 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 */ 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_cursormove(&ctx, data->cx, data->cy);
screen_write_stop(&ctx); screen_write_stop(&ctx);
} }

View File

@ -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> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -22,17 +22,17 @@
#include "tmux.h" #include "tmux.h"
struct screen *window_more_init(struct window *); struct screen *window_more_init(struct window_pane *);
void window_more_free(struct window *); void window_more_free(struct window_pane *);
void window_more_resize(struct window *, u_int, u_int); void window_more_resize(struct window_pane *, u_int, u_int);
void window_more_key(struct window *, struct client *, 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( 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_up(struct window_pane *);
void window_more_scroll_down(struct window *); void window_more_scroll_down(struct window_pane *);
const struct window_mode window_more_mode = { const struct window_mode window_more_mode = {
window_more_init, window_more_init,
@ -50,9 +50,9 @@ struct window_more_mode_data {
}; };
void 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 *s = &data->screen;
struct screen_write_ctx ctx; struct screen_write_ctx ctx;
char *msg; char *msg;
@ -61,48 +61,48 @@ window_more_vadd(struct window *w, const char *fmt, va_list ap)
xvasprintf(&msg, fmt, ap); xvasprintf(&msg, fmt, ap);
ARRAY_ADD(&data->list, msg); ARRAY_ADD(&data->list, msg);
screen_write_start_window(&ctx, w); screen_write_start(&ctx, wp, NULL);
size = ARRAY_LENGTH(&data->list) - 1; size = ARRAY_LENGTH(&data->list) - 1;
if (size >= data->top && size <= data->top + screen_size_y(s) - 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) if (size != data->top)
window_more_write_line(w, &ctx, 0); window_more_write_line(wp, &ctx, 0);
} else } else
window_more_write_line(w, &ctx, 0); window_more_write_line(wp, &ctx, 0);
screen_write_stop(&ctx); screen_write_stop(&ctx);
} }
void void
window_more_add(struct window *w, const char *fmt, ...) window_more_add(struct window_pane *wp, const char *fmt, ...)
{ {
va_list ap; va_list ap;
va_start(ap, fmt); va_start(ap, fmt);
window_more_vadd(w, fmt, ap); window_more_vadd(wp, fmt, ap);
va_end(ap); va_end(ap);
} }
struct screen * struct screen *
window_more_init(struct window *w) window_more_init(struct window_pane *wp)
{ {
struct window_more_mode_data *data; struct window_more_mode_data *data;
struct screen *s; struct screen *s;
w->modedata = data = xmalloc(sizeof *data); wp->modedata = data = xmalloc(sizeof *data);
ARRAY_INIT(&data->list); ARRAY_INIT(&data->list);
data->top = 0; data->top = 0;
s = &data->screen; 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; s->mode &= ~MODE_CURSOR;
return (s); return (s);
} }
void 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; u_int i;
for (i = 0; i < ARRAY_LENGTH(&data->list); i++) for (i = 0; i < ARRAY_LENGTH(&data->list); i++)
@ -114,39 +114,39 @@ window_more_free(struct window *w)
} }
void 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; struct screen *s = &data->screen;
screen_resize(s, sx, sy); screen_resize(s, sx, sy);
window_more_redraw_screen(w); window_more_redraw_screen(wp);
} }
void 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; struct screen *s = &data->screen;
int table; 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)) { switch (mode_key_lookup(table, key)) {
case MODEKEY_QUIT: case MODEKEY_QUIT:
window_reset_mode(w); window_pane_reset_mode(wp);
break; break;
case MODEKEY_UP: case MODEKEY_UP:
window_more_scroll_up(w); window_more_scroll_up(wp);
break; break;
case MODEKEY_DOWN: case MODEKEY_DOWN:
window_more_scroll_down(w); window_more_scroll_down(wp);
break; break;
case MODEKEY_PPAGE: case MODEKEY_PPAGE:
if (data->top < screen_size_y(s)) if (data->top < screen_size_y(s))
data->top = 0; data->top = 0;
else else
data->top -= screen_size_y(s); data->top -= screen_size_y(s);
window_more_redraw_screen(w); window_more_redraw_screen(wp);
break; break;
case MODEKEY_NONE: case MODEKEY_NONE:
if (key != ' ') if (key != ' ')
@ -157,7 +157,7 @@ window_more_key(struct window *w, unused struct client *c, int key)
data->top = ARRAY_LENGTH(&data->list); data->top = ARRAY_LENGTH(&data->list);
else else
data->top += screen_size_y(s); data->top += screen_size_y(s);
window_more_redraw_screen(w); window_more_redraw_screen(wp);
break; break;
default: default:
break; break;
@ -165,9 +165,9 @@ window_more_key(struct window *w, unused struct client *c, int key)
} }
void 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 screen *s = &data->screen;
struct grid_cell gc; struct grid_cell gc;
char *msg, hdr[32]; 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, size = xsnprintf(hdr, sizeof hdr,
"[%u/%u]", data->top, ARRAY_LENGTH(&data->list)); "[%u/%u]", data->top, ARRAY_LENGTH(&data->list));
screen_write_cursormove(ctx, screen_size_x(s) - size, 0); screen_write_cursormove(ctx, screen_size_x(s) - size, 0);
gc.fg = options_get_number(&w->options, "mode-fg"); gc.fg = options_get_number(&wp->window->options, "mode-fg");
gc.bg = options_get_number(&w->options, "mode-bg"); gc.bg = options_get_number(&wp->window->options, "mode-bg");
screen_write_puts(ctx, &gc, "%s", hdr); screen_write_puts(ctx, &gc, "%s", hdr);
memcpy(&gc, &grid_default_cell, sizeof gc); memcpy(&gc, &grid_default_cell, sizeof gc);
} else } else
@ -197,41 +197,41 @@ window_more_write_line(struct window *w, struct screen_write_ctx *ctx, u_int py)
} }
void 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 *s = &data->screen;
struct screen_write_ctx ctx; struct screen_write_ctx ctx;
u_int i; u_int i;
screen_write_start_window(&ctx, w); screen_write_start(&ctx, wp, NULL);
for (i = 0; i < screen_size_y(s); i++) 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); screen_write_stop(&ctx);
} }
void 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; struct screen_write_ctx ctx;
if (data->top == 0) if (data->top == 0)
return; return;
data->top--; data->top--;
screen_write_start_window(&ctx, w); screen_write_start(&ctx, wp, NULL);
screen_write_cursormove(&ctx, 0, 0); screen_write_cursormove(&ctx, 0, 0);
screen_write_insertline(&ctx, 1); screen_write_insertline(&ctx, 1);
window_more_write_line(w, &ctx, 0); window_more_write_line(wp, &ctx, 0);
window_more_write_line(w, &ctx, 1); window_more_write_line(wp, &ctx, 1);
screen_write_stop(&ctx); screen_write_stop(&ctx);
} }
void 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 *s = &data->screen;
struct screen_write_ctx ctx; struct screen_write_ctx ctx;
@ -239,10 +239,10 @@ window_more_scroll_down(struct window *w)
return; return;
data->top++; data->top++;
screen_write_start_window(&ctx, w); screen_write_start(&ctx, wp, NULL);
screen_write_cursormove(&ctx, 0, 0); screen_write_cursormove(&ctx, 0, 0);
screen_write_deleteline(&ctx, 1); screen_write_deleteline(&ctx, 1);
window_more_write_line(w, &ctx, screen_size_y(s) - 1); window_more_write_line(wp, &ctx, screen_size_y(s) - 1);
window_more_write_line(w, &ctx, 0); window_more_write_line(wp, &ctx, 0);
screen_write_stop(&ctx); screen_write_stop(&ctx);
} }

View File

@ -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> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -22,21 +22,21 @@
#include "tmux.h" #include "tmux.h"
struct screen *window_scroll_init(struct window *); struct screen *window_scroll_init(struct window_pane *);
void window_scroll_free(struct window *); void window_scroll_free(struct window_pane *);
void window_scroll_resize(struct window *, u_int, u_int); void window_scroll_resize(struct window_pane *, u_int, u_int);
void window_scroll_key(struct window *, struct client *, 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( 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( 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_up(struct window_pane *);
void window_scroll_scroll_down(struct window *); void window_scroll_scroll_down(struct window_pane *);
void window_scroll_scroll_left(struct window *); void window_scroll_scroll_left(struct window_pane *);
void window_scroll_scroll_right(struct window *); void window_scroll_scroll_right(struct window_pane *);
const struct window_mode window_scroll_mode = { const struct window_mode window_scroll_mode = {
window_scroll_init, window_scroll_init,
@ -54,90 +54,90 @@ struct window_scroll_mode_data {
}; };
struct screen * struct screen *
window_scroll_init(struct window *w) window_scroll_init(struct window_pane *wp)
{ {
struct window_scroll_mode_data *data; struct window_scroll_mode_data *data;
struct screen *s; struct screen *s;
struct screen_write_ctx ctx; struct screen_write_ctx ctx;
u_int i; u_int i;
w->modedata = data = xmalloc(sizeof *data); wp->modedata = data = xmalloc(sizeof *data);
data->ox = 0; data->ox = 0;
data->oy = 0; data->oy = 0;
s = &data->screen; 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; 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++) 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); screen_write_stop(&ctx);
return (s); return (s);
} }
void 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); screen_free(&data->screen);
xfree(data); xfree(data);
} }
void 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 *s = &data->screen;
struct screen_write_ctx ctx; struct screen_write_ctx ctx;
u_int i; u_int i;
screen_resize(s, sx, sy); 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++) 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); screen_write_stop(&ctx);
} }
void 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; struct screen *s = &data->screen;
int table; 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)) { switch (mode_key_lookup(table, key)) {
case MODEKEY_QUIT: case MODEKEY_QUIT:
window_reset_mode(w); window_pane_reset_mode(wp);
break; break;
case MODEKEY_LEFT: case MODEKEY_LEFT:
window_scroll_scroll_left(w); window_scroll_scroll_left(wp);
break; break;
case MODEKEY_RIGHT: case MODEKEY_RIGHT:
window_scroll_scroll_right(w); window_scroll_scroll_right(wp);
break; break;
case MODEKEY_UP: case MODEKEY_UP:
window_scroll_scroll_up(w); window_scroll_scroll_up(wp);
break; break;
case MODEKEY_DOWN: case MODEKEY_DOWN:
window_scroll_scroll_down(w); window_scroll_scroll_down(wp);
break; break;
case MODEKEY_PPAGE: case MODEKEY_PPAGE:
if (data->oy + screen_size_y(s) > screen_hsize(&w->base)) if (data->oy + screen_size_y(s) > screen_hsize(&wp->base))
data->oy = screen_hsize(&w->base); data->oy = screen_hsize(&wp->base);
else else
data->oy += screen_size_y(s); data->oy += screen_size_y(s);
window_scroll_redraw_screen(w); window_scroll_redraw_screen(wp);
break; break;
case MODEKEY_NPAGE: case MODEKEY_NPAGE:
if (data->oy < screen_size_y(s)) if (data->oy < screen_size_y(s))
data->oy = 0; data->oy = 0;
else else
data->oy -= screen_size_y(s); data->oy -= screen_size_y(s);
window_scroll_redraw_screen(w); window_scroll_redraw_screen(wp);
break; break;
default: default:
break; break;
@ -146,9 +146,9 @@ window_scroll_key(struct window *w, unused struct client *c, int key)
void void
window_scroll_write_line( 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 screen *s = &data->screen;
struct grid_cell gc; struct grid_cell gc;
char hdr[32]; char hdr[32];
@ -157,9 +157,9 @@ window_scroll_write_line(
if (py == 0) { if (py == 0) {
memcpy(&gc, &grid_default_cell, sizeof gc); memcpy(&gc, &grid_default_cell, sizeof gc);
size = xsnprintf(hdr, sizeof hdr, size = xsnprintf(hdr, sizeof hdr,
"[%u,%u/%u]", data->ox, data->oy, screen_hsize(&w->base)); "[%u,%u/%u]", data->ox, data->oy, screen_hsize(&wp->base));
gc.fg = options_get_number(&w->options, "mode-fg"); gc.fg = options_get_number(&wp->window->options, "mode-fg");
gc.bg = options_get_number(&w->options, "mode-bg"); gc.bg = options_get_number(&wp->window->options, "mode-bg");
screen_write_cursormove(ctx, screen_size_x(s) - size, 0); screen_write_cursormove(ctx, screen_size_x(s) - size, 0);
screen_write_puts(ctx, &gc, "%s", hdr); screen_write_puts(ctx, &gc, "%s", hdr);
memcpy(&gc, &grid_default_cell, sizeof gc); memcpy(&gc, &grid_default_cell, sizeof gc);
@ -167,58 +167,58 @@ window_scroll_write_line(
size = 0; size = 0;
screen_write_cursormove(ctx, 0, py); 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); data->oy) + py, screen_size_x(s) - size, 1);
} }
void void
window_scroll_write_column( 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; struct screen *s = &data->screen;
screen_write_cursormove(ctx, px, 0); screen_write_cursormove(ctx, px, 0);
screen_write_copy(ctx, &w->base, data->ox + px, screen_write_copy(ctx, &wp->base, data->ox + px,
screen_hsize(&w->base) - data->oy, 1, screen_size_y(s)); screen_hsize(&wp->base) - data->oy, 1, screen_size_y(s));
} }
void 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 *s = &data->screen;
struct screen_write_ctx ctx; struct screen_write_ctx ctx;
u_int i; u_int i;
screen_write_start_window(&ctx, w); screen_write_start(&ctx, wp, NULL);
for (i = 0; i < screen_size_y(s); i++) 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); screen_write_stop(&ctx);
} }
void 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; struct screen_write_ctx ctx;
if (data->oy >= screen_hsize(&w->base)) if (data->oy >= screen_hsize(&wp->base))
return; return;
data->oy++; data->oy++;
screen_write_start_window(&ctx, w); screen_write_start(&ctx, wp, NULL);
screen_write_cursormove(&ctx, 0, 0); screen_write_cursormove(&ctx, 0, 0);
screen_write_insertline(&ctx, 1); screen_write_insertline(&ctx, 1);
window_scroll_write_line(w, &ctx, 0); window_scroll_write_line(wp, &ctx, 0);
window_scroll_write_line(w, &ctx, 1); window_scroll_write_line(wp, &ctx, 1);
screen_write_stop(&ctx); screen_write_stop(&ctx);
} }
void 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 *s = &data->screen;
struct screen_write_ctx ctx; struct screen_write_ctx ctx;
@ -226,18 +226,18 @@ window_scroll_scroll_down(struct window *w)
return; return;
data->oy--; data->oy--;
screen_write_start_window(&ctx, w); screen_write_start(&ctx, wp, NULL);
screen_write_cursormove(&ctx, 0, 0); screen_write_cursormove(&ctx, 0, 0);
screen_write_deleteline(&ctx, 1); screen_write_deleteline(&ctx, 1);
window_scroll_write_line(w, &ctx, screen_size_y(s) - 1); window_scroll_write_line(wp, &ctx, screen_size_y(s) - 1);
window_scroll_write_line(w, &ctx, 0); window_scroll_write_line(wp, &ctx, 0);
screen_write_stop(&ctx); screen_write_stop(&ctx);
} }
void 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 *s = &data->screen;
struct screen_write_ctx ctx; struct screen_write_ctx ctx;
u_int i; u_int i;
@ -246,20 +246,20 @@ window_scroll_scroll_right(struct window *w)
return; return;
data->ox++; data->ox++;
screen_write_start_window(&ctx, w); screen_write_start(&ctx, wp, NULL);
for (i = 1; i < screen_size_y(s); i++) { for (i = 1; i < screen_size_y(s); i++) {
screen_write_cursormove(&ctx, 0, i); screen_write_cursormove(&ctx, 0, i);
screen_write_deletecharacter(&ctx, 1); screen_write_deletecharacter(&ctx, 1);
} }
window_scroll_write_column(w, &ctx, screen_size_x(s) - 1); window_scroll_write_column(wp, &ctx, screen_size_x(s) - 1);
window_scroll_write_line(w, &ctx, 0); window_scroll_write_line(wp, &ctx, 0);
screen_write_stop(&ctx); screen_write_stop(&ctx);
} }
void 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 *s = &data->screen;
struct screen_write_ctx ctx; struct screen_write_ctx ctx;
u_int i; u_int i;
@ -268,12 +268,12 @@ window_scroll_scroll_left(struct window *w)
return; return;
data->ox--; data->ox--;
screen_write_start_window(&ctx, w); screen_write_start(&ctx, wp, NULL);
for (i = 1; i < screen_size_y(s); i++) { for (i = 1; i < screen_size_y(s); i++) {
screen_write_cursormove(&ctx, 0, i); screen_write_cursormove(&ctx, 0, i);
screen_write_insertcharacter(&ctx, 1); screen_write_insertcharacter(&ctx, 1);
} }
window_scroll_write_column(w, &ctx, 0); window_scroll_write_column(wp, &ctx, 0);
window_scroll_write_line(w, &ctx, 0); window_scroll_write_line(wp, &ctx, 0);
screen_write_stop(&ctx); screen_write_stop(&ctx);
} }

271
window.c
View File

@ -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> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -46,16 +46,17 @@
#include "tmux.h" #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, * 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 * 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 * input_parse (in input.c). Input data is received as key codes and written
* directly via input_key. * directly via input_key.
* *
* Each window also has a "virtual" screen (screen.c) which contains the * Each pane also has a "virtual" screen (screen.c) which contains the current
* current state and is redisplayed when the window is reattached to a client. * 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 * 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 * 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; char *ptr, *copy;
w = xmalloc(sizeof *w); 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->flags = 0;
w->panes[0] = window_pane_create(w, sx, sy, hlimit);
w->panes[1] = NULL;
screen_init(&w->base, sx, sy, hlimit); w->sx = sx;
w->screen = &w->base; w->sy = sy;
w->active = w->panes[0];
input_init(w);
options_init(&w->options, &global_window_options); options_init(&w->options, &global_window_options);
if (name == NULL) { if (name == NULL) {
@ -253,60 +249,13 @@ window_create(const char *name, const char *cmd,
ARRAY_ADD(&windows, w); ARRAY_ADD(&windows, w);
w->references = 0; w->references = 0;
if (window_spawn(w, cmd, cwd, envp) != 0) { if (window_pane_spawn(w->active, cmd, cwd, envp) != 0) {
window_destroy(w); window_destroy(w);
return (NULL); return (NULL);
} }
return (w); return (w);
} }
int
window_spawn(
struct window *w, 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);
memset(&ws, 0, sizeof ws);
ws.ws_col = screen_size_x(&w->base);
ws.ws_row = screen_size_y(&w->base);
switch (forkpty(&w->fd, NULL, NULL, &ws)) {
case -1:
return (1);
case 0:
if (chdir(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);
fatal("execl failed");
}
if ((mode = fcntl(w->fd, F_GETFL)) == -1)
fatal("fcntl failed");
if (fcntl(w->fd, F_SETFL, mode|O_NONBLOCK) == -1)
fatal("fcntl failed");
if (fcntl(w->fd, F_SETFD, FD_CLOEXEC) == -1)
fatal("fcntl failed");
return (0);
}
void void
window_destroy(struct window *w) window_destroy(struct window *w)
{ {
@ -318,87 +267,207 @@ window_destroy(struct window *w)
} }
ARRAY_REMOVE(&windows, i); ARRAY_REMOVE(&windows, i);
if (w->fd != -1)
close(w->fd);
input_free(w);
window_reset_mode(w);
options_free(&w->options); options_free(&w->options);
screen_free(&w->base);
buffer_destroy(w->in); window_pane_destroy(w->panes[0]);
buffer_destroy(w->out); if (w->panes[1] != NULL)
window_pane_destroy(w->panes[1]);
if (w->cwd != NULL)
xfree(w->cwd);
if (w->cmd != NULL)
xfree(w->cmd);
xfree(w->name); xfree(w->name);
xfree(w); xfree(w);
} }
int int
window_resize(struct window *w, u_int sx, u_int sy) 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_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 (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(&wp->base);
ws.ws_row = screen_size_y(&wp->base);
switch (forkpty(&wp->fd, NULL, NULL, &ws)) {
case -1:
return (1);
case 0:
if (chdir(wp->cwd) != 0)
chdir("/");
for (envq = envp; *envq != NULL; envq++) {
if (putenv(*envq) != 0)
fatal("putenv failed");
}
sigreset();
log_close();
execl(_PATH_BSHELL, "sh", "-c", wp->cmd, (char *) NULL);
fatal("execl failed");
}
if ((mode = fcntl(wp->fd, F_GETFL)) == -1)
fatal("fcntl failed");
if (fcntl(wp->fd, F_SETFL, mode|O_NONBLOCK) == -1)
fatal("fcntl failed");
if (fcntl(wp->fd, F_SETFD, FD_CLOEXEC) == -1)
fatal("fcntl failed");
return (0);
}
int
window_pane_resize(struct window_pane *wp, u_int sx, u_int sy)
{ {
struct winsize ws; 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); return (-1);
memset(&ws, 0, sizeof ws); memset(&ws, 0, sizeof ws);
ws.ws_col = sx; ws.ws_col = sx;
ws.ws_row = sy; ws.ws_row = sy;
screen_resize(&w->base, sx, sy); screen_resize(&wp->base, sx, sy);
if (w->mode != NULL) if (wp->mode != NULL)
w->mode->resize(w, sx, sy); 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"); fatal("ioctl failed");
return (0); return (0);
} }
int 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; struct screen *s;
if (w->mode != NULL || w->mode == mode) if (wp->mode != NULL || wp->mode == mode)
return (1); return (1);
w->mode = mode; wp->mode = mode;
if ((s = w->mode->init(w)) != NULL) if ((s = wp->mode->init(wp)) != NULL)
w->screen = s; wp->screen = s;
server_redraw_window(w); server_redraw_window(wp->window);
return (0); return (0);
} }
void void
window_reset_mode(struct window *w) window_pane_reset_mode(struct window_pane *wp)
{ {
if (w->mode == NULL) if (wp->mode == NULL)
return; return;
w->mode->free(w); wp->mode->free(wp);
w->mode = NULL; wp->mode = NULL;
w->screen = &w->base; wp->screen = &wp->base;
server_redraw_window(w); server_redraw_window(wp->window);
} }
void void
window_parse(struct window *w) window_pane_parse(struct window_pane *wp)
{ {
input_parse(w); input_parse(wp);
} }
void 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) if (wp->mode != NULL)
w->mode->key(w, c, key); wp->mode->key(wp, c, key);
else else
input_key(w, key); input_key(wp, key);
} }