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

pull/1/head
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
* Vertical window splitting. Currently can only split a window into two panes.
New split-window command splits (bound to ") and switch-pane command (bound to
o) switches between panes.
close-pane, swap-pane commands are to follow. Also to come are pane resizing,
>2 panes, the ability to break a pane out to a full window and vice versa and
possibly horizontal splitting.
Panes are subelements of windows rather than being windows in their own
right. I tried to make them windows (so the splitting was at the session or
client level) but this rapidly became very complex and invasive. So in the
interests of having something working, I just made it so each window can have
two child processes instead of one (and it still took me 12 hours straight
coding). Now the concept is proven and much of the support code is there,
this may change in future if more flexibility is needed.
* save-buffer command, from Tiago Cunha.
10 January 2009
@ -859,7 +874,7 @@
(including mutt, emacs). No status bar yet and no key remapping or other
customisation.
$Id: CHANGES,v 1.192 2009-01-11 23:14:57 nicm Exp $
$Id: CHANGES,v 1.193 2009-01-11 23:31:46 nicm Exp $
LocalWords: showw utf UTF fulvio ciriaco joshe OSC APC gettime abc DEF OA clr
LocalWords: rivo nurges lscm Erdely eol smysession mysession ek dstname RB

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
@ -33,7 +33,7 @@ SRCS= tmux.c server.c server-msg.c server-fn.c buffer.c buffer-poll.c status.c \
cmd-list-commands.c cmd-move-window.c cmd-select-prompt.c \
cmd-respawn-window.c cmd-source-file.c cmd-server-info.c \
cmd-clock-mode.c cmd-lock-server.c cmd-set-password.c \
cmd-save-buffer.c \
cmd-save-buffer.c cmd-switch-pane.c cmd-split-window.c \
window-clock.c window-scroll.c window-more.c window-copy.c \
options.c options-cmd.c paste.c colour.c utf8.c clock.c \
tty.c tty-term.c tty-keys.c tty-write.c

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
.PHONY: clean update-index.html upload-index.html
@ -37,7 +37,7 @@ SRCS= tmux.c server.c server-msg.c server-fn.c buffer.c buffer-poll.c status.c \
cmd-list-commands.c cmd-move-window.c cmd-select-prompt.c \
cmd-respawn-window.c cmd-source-file.c cmd-server-info.c \
cmd-clock-mode.c cmd-lock-server.c cmd-set-password.c \
cmd-save-buffer.c \
cmd-save-buffer.c cmd-switch-pane.c cmd-split-window.c \
window-clock.c window-scroll.c window-more.c window-copy.c \
options.c options-cmd.c paste.c colour.c utf8.c clock.c \
tty.c tty-term.c tty-keys.c tty-write.c

21
TODO
View File

@ -13,7 +13,7 @@
- status-fg/status-bg should be able to set attributes: bold, etc
- refer to windows by name etc (duplicates? fnmatch?)
- commands:
command to run something without a window at all?
command to run something without a window at all - output to window-more
command to purge window history
extend list-clients to list clients attached to a session (-a for all?)
bring back detach-session to detach all clients on a session?
@ -42,7 +42,7 @@
session not being watched?
- tidy up window modes
- problems with force-width when wrapping line in emacs?
- next prev word etc in command prompt; also ^K; also make is support modes
- next prev word etc in command prompt; also ^K; also make it support modes
to support vi. is there something could use for this? editline(3)/readline?
- many more info() displays for various things
- vi half page scroll
@ -51,8 +51,8 @@
others do not. this might be hard: a flag for each grid line (top bit of size
maybe)? a single flag is insufficient as can't then tell when to /stop/
unwrapping
- OPTIONS section in man page with description of new option handling
- update set/setw in man page with -g and -u flags
- document OPTIONS section in man page with description of new option handling
- document update set/setw in man page with -g and -u flags
- more # commands in status-left,right eg #H for hostname. others?
- input.c is too complicated. simplify?
- try change from pass-though model to redraw model (use updated screen
@ -66,7 +66,9 @@
- document clock-mode
- document password/locking commands
- document lock-after-time
- document panes and window splitting: split-window and switch-pane
- a command to display the status line briefly when it is turned off
- neww should support -k
- FAQ "Can I have some examples of cool things I can do with tmux?" -- linkw, more??
17:06 < NicM> tmux new then eg tmux linkw -s0:0
17:06 < simmel> NicM link-window?
@ -87,3 +89,14 @@
17:09 < NicM> or kills it if it is only linked to one
17:09 < NicM> unlinkw only unlinks it
- clone session command
- panes:
swap-panes
close-pane
move-pane (to window)
pane resizing
>2 panes per window
- would be nice if tmux could be the shell
- some sort of extension to command prompt so can do eg
bind m command-prompt 'split "man %%"'
bind r command-prompt 'renamew "%%"'
which then asks for a string, substitutes %% in command and executes it

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

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

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

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

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>
@ -46,6 +46,7 @@ cmd_respawn_window_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct winlink *wl;
struct window *w;
struct session *s;
const char *env[] = {
NULL /* TMUX= */, "TERM=screen", NULL
@ -55,8 +56,10 @@ cmd_respawn_window_exec(struct cmd *self, struct cmd_ctx *ctx)
if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL)
return;
w = wl->window;
if (wl->window->fd != -1 && !(data->flags & CMD_KFLAG)) {
if ((w->panes[0]->fd != -1 || (w->panes[1] != NULL &&
w->panes[1]->fd != -1)) && !(data->flags & CMD_KFLAG)) {
ctx->error(ctx, "window still active: %s:%d", s->name, wl->idx);
return;
}
@ -66,14 +69,17 @@ cmd_respawn_window_exec(struct cmd *self, struct cmd_ctx *ctx)
xsnprintf(buf, sizeof buf, "TMUX=%ld,%u", (long) getpid(), i);
env[0] = buf;
if (window_spawn(wl->window, data->arg, wl->window->cwd, env) != 0) {
if (w->panes[1] != NULL)
window_remove_pane(w, 1);
if (window_pane_spawn(w->panes[0], data->arg, NULL, env) != 0) {
ctx->error(ctx, "respawn failed: %s:%d", s->name, wl->idx);
return;
}
screen_reinit(&wl->window->base);
screen_reinit(&w->panes[0]->base);
recalculate_sizes();
server_redraw_window(wl->window);
server_redraw_window(w);
if (ctx->cmdclient != NULL)
server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0);

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

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

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>
@ -51,7 +51,7 @@ cmd_send_prefix_exec(struct cmd *self, struct cmd_ctx *ctx)
return;
key = options_get_number(&s->options, "prefix");
window_key(wl->window, ctx->curclient, key);
window_pane_key(wl->window->active, ctx->curclient, key);
if (ctx->cmdclient != NULL)
server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0);

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>
@ -71,9 +71,11 @@ const struct cmd_entry *cmd_table[] = {
&cmd_show_options_entry,
&cmd_show_window_options_entry,
&cmd_source_file_entry,
&cmd_split_window_entry,
&cmd_start_server_entry,
&cmd_swap_window_entry,
&cmd_switch_client_entry,
&cmd_switch_pane_entry,
&cmd_unbind_key_entry,
&cmd_unlink_window_entry,
NULL

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

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

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

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>
@ -125,12 +125,11 @@ recalculate_sizes(void)
if (limit != 0 && ssy > limit)
ssy = limit;
if (screen_size_x(&w->base) == ssx &&
screen_size_y(&w->base) == ssy)
if (w->sx == ssx && w->sy == ssy)
continue;
log_debug("window size %u,%u (was %u,%u)", ssx, ssy,
screen_size_x(&w->base), screen_size_y(&w->base));
log_debug(
"window size %u,%u (was %u,%u)", ssx, ssy, w->sx, w->sy);
window_resize(w, ssx, ssy);
server_redraw_window(w);

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>
@ -22,146 +22,143 @@
#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
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. */
void
screen_redraw_start_client(struct screen_redraw_ctx *ctx, struct client *c)
{
struct screen *t = c->session->curw->window->screen;
/* Override the normal screen if one is given. */
if (s != NULL) {
for (i = 0; i < screen_size_y(s); i++)
screen_redraw_line(c, s, 0, i);
return;
}
screen_redraw_start(ctx, t, tty_write_client, c);
}
/* Initialise redrawing with a session. */
void
screen_redraw_start_session(struct screen_redraw_ctx *ctx, struct session *s)
{
struct screen *t = s->curw->window->screen;
screen_redraw_start(ctx, t, tty_write_session, s);
}
/* Initialise for redrawing. */
void
screen_redraw_start(struct screen_redraw_ctx *ctx,
struct screen *s, void (*write)(void *, 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.
/*
* A normal client screen is made up of three parts: a top window, a
* bottom window and a status line. The bottom window may be turned
* off; the status line is always drawn.
*/
ctx->saved_cx = s->cx;
ctx->saved_cy = s->cy;
ctx->write(ctx->data, TTY_SCROLLREGION, 0, screen_size_y(s) - 1);
ctx->write(ctx->data, TTY_CURSORMOVE, s->cx, s->cy);
ctx->write(ctx->data, TTY_CURSORMODE, 0);
ctx->write(ctx->data, TTY_MOUSEMODE, 0);
/* Draw the top window. */
s = wl->window->panes[0]->screen;
sy = screen_size_y(s);
if (screen_size_y(s) == c->sy && wl->window->panes[1] == NULL)
sy--;
cx = s->cx;
cy = s->cy;
for (i = 0; i < sy; i++)
screen_redraw_line(c, s, 0, i);
s->cx = cx;
s->cy = cy;
/* Draw the bottom window. */
if (wl->window->panes[1] != NULL) {
s = wl->window->panes[1]->screen;
sy = screen_size_y(s);
if (!status && screen_size_y(s) == c->sy - (c->sy / 2) - 1)
sy--;
cx = s->cx;
cy = s->cy;
for (i = 0; i < sy; i++)
screen_redraw_line(c, s, wl->window->sy / 2, i);
s->cx = cx;
s->cy = cy;
}
/* 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
screen_redraw_stop(struct screen_redraw_ctx *ctx)
screen_redraw_status(struct client *c)
{
struct screen *s = ctx->s;
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);
screen_redraw_line(c, &c->status, c->sy - 1, 0);
}
/* Write character. */
/* Draw blank columns. */
void
screen_redraw_putc(
struct screen_redraw_ctx *ctx, struct grid_cell *gc, u_char ch)
screen_redraw_blankx(struct client *c, u_int ox, u_int nx)
{
gc->data = ch;
ctx->write(ctx->data, TTY_CELL, gc);
ctx->s->cx++;
u_int i, j;
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. */
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. */
/* Draw blank lines. */
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;
struct grid_cell tc;
u_int i;
if (px != ctx->s->cx || py != ctx->s->cy) {
ctx->s->cx = px;
ctx->s->cy = py;
ctx->write(ctx->data, TTY_CURSORMOVE, ctx->s->cx, ctx->s->cy);
}
for (i = 0; i < screen_size_x(s); i++) {
s->cx = i;
s->cy = py;
gc = grid_view_peek_cell(ctx->s->grid, px, py);
if (screen_check_selection(ctx->s, px, py)) {
memcpy(&tc, &ctx->s->sel.cell, sizeof tc);
tc.data = gc->data;
ctx->write(ctx->data, TTY_CELL, &tc);
} else
ctx->write(ctx->data, TTY_CELL, gc);
ctx->s->cx++;
}
/* 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);
gc = grid_view_peek_cell(s->grid, i, py);
if (screen_check_selection(s, i, py)) {
memcpy(&tc, &s->sel.cell, sizeof tc);
tc.data = gc->data;
tty_write(&c->tty, s, oy, TTY_CELL, &tc);
} else
tty_write(&c->tty, s, oy, TTY_CELL, gc);
}
}

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

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>
@ -21,6 +21,7 @@
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.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>
@ -49,12 +49,11 @@ void server_fill_clients(struct pollfd **);
void server_handle_clients(struct pollfd **);
struct client *server_accept_client(int);
void server_handle_client(struct client *);
void server_handle_window(struct window *);
void server_handle_window(struct window *, int);
void server_lost_client(struct client *);
void server_lost_window(struct window *);
int server_lost_window(struct window *, int);
void server_check_redraw(struct client *);
void server_do_redraw_client(struct client *);
void server_do_redraw_locked(struct client *);
void server_redraw_locked(struct client *);
void server_check_timers(struct client *);
void server_second_timers(void);
int server_update_socket(const char *);
@ -184,7 +183,9 @@ server_main(const char *srv_path, int srv_fd)
pfds = NULL;
while (!sigterm) {
/* Initialise pollfd array. */
nfds = 1 + ARRAY_LENGTH(&windows) + ARRAY_LENGTH(&clients) * 2;
nfds = 1;
nfds += ARRAY_LENGTH(&windows) * 2;
nfds += ARRAY_LENGTH(&clients) * 2;
pfds = xrealloc(pfds, nfds, sizeof *pfds);
pfd = pfds;
@ -279,19 +280,25 @@ server_main(const char *srv_path, int srv_fd)
void
server_fill_windows(struct pollfd **pfd)
{
struct window *w;
u_int i;
struct window *w;
struct window_pane *wp;
u_int i, j;
for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
if ((w = ARRAY_ITEM(&windows, i)) == NULL || w->fd == -1)
(*pfd)->fd = -1;
else {
(*pfd)->fd = w->fd;
(*pfd)->events = POLLIN;
if (BUFFER_USED(w->out) > 0)
(*pfd)->events |= POLLOUT;
w = ARRAY_ITEM(&windows, i);
for (j = 0; j < 2; j++) {
if (w != NULL)
wp = w->panes[j];
if (w == NULL || wp == NULL || wp->fd == -1) {
(*pfd)->fd = -1;
} else {
(*pfd)->fd = wp->fd;
(*pfd)->events = POLLIN;
if (BUFFER_USED(wp->out) > 0)
(*pfd)->events |= POLLOUT;
}
(*pfd)++;
}
(*pfd)++;
}
}
@ -299,17 +306,24 @@ server_fill_windows(struct pollfd **pfd)
void
server_handle_windows(struct pollfd **pfd)
{
struct window *w;
u_int i;
struct window *w;
struct window_pane *wp;
u_int i, j;
for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
if ((w = ARRAY_ITEM(&windows, i)) != NULL && w->fd != -1) {
if (buffer_poll(*pfd, w->in, w->out) != 0)
server_lost_window(w);
else
server_handle_window(w);
w = ARRAY_ITEM(&windows, i);
for (j = 0; j < 2; j++) {
if (w != NULL)
wp = w->panes[j];
if (w != NULL && wp != NULL && wp->fd != -1) {
if (buffer_poll(*pfd, wp->in, wp->out) != 0) {
if (server_lost_window(w, j) != 0)
break;
} else
server_handle_window(w, j);
}
(*pfd)++;
}
(*pfd)++;
}
}
@ -329,7 +343,7 @@ server_check_redraw(struct client *c)
c->tty.flags &= ~TTY_FREEZE;
if (options_get_number(&s->options, "set-titles")) {
title = s->curw->window->base.title;
title = s->curw->window->active->screen->title;
if (c->title == NULL || strcmp(title, c->title) != 0) {
if (c->title != NULL)
xfree(c->title);
@ -338,16 +352,7 @@ server_check_redraw(struct client *c)
}
}
if (c->flags & CLIENT_REDRAW) {
if (server_locked)
server_do_redraw_locked(c);
else
server_do_redraw_client(c);
c->flags |= CLIENT_STATUS;
}
if (c->flags & CLIENT_STATUS) {
if (c->flags & (CLIENT_REDRAW|CLIENT_STATUS)) {
if (c->message_string != NULL)
status_message_redraw(c);
else if (c->prompt_string != NULL)
@ -356,78 +361,47 @@ server_check_redraw(struct client *c)
status_redraw(c);
}
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->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. */
void
server_do_redraw_locked(struct client *c)
server_redraw_locked(struct client *c)
{
struct session *s = c->session;
struct window *w = s->curw->window;
struct screen_write_ctx ctx;
struct screen screen;
u_int colour, xx, yy;
int style;
struct screen_write_ctx ctx;
struct screen screen;
u_int colour, xx, yy;
int style;
xx = c->sx;
yy = c->sy - 1;
if (xx == 0 || yy == 0)
return;
colour = options_get_number(&w->options, "clock-mode-colour");
style = options_get_number(&w->options, "clock-mode-style");
colour = options_get_number(
&global_window_options, "clock-mode-colour");
style = options_get_number(
&global_window_options, "clock-mode-style");
screen_init(&screen, xx, yy, 0);
screen_write_start(&ctx, &screen, tty_write_client, c);
screen_write_start(&ctx, NULL, &screen);
clock_draw(&ctx, colour, style);
screen_write_stop(&ctx);
screen_redraw_screen(c, &screen);
screen_free(&screen);
}
@ -567,6 +541,7 @@ server_accept_client(int srv_fd)
c->session = NULL;
c->sx = 80;
c->sy = 25;
screen_init(&c->status, c->sx, 1, 0);
c->message_string = NULL;
@ -588,9 +563,12 @@ server_accept_client(int srv_fd)
void
server_handle_client(struct client *c)
{
struct window *w = c->session->curw->window;
int key, prefix;
struct winlink *wl = c->session->curw;
struct window_pane *wp = wl->window->active;
int key, prefix;
u_int oy;
/* Process keys. */
prefix = options_get_number(&c->session->options, "prefix");
while (tty_keys_next(&c->tty, &key) == 0) {
server_activity = time(NULL);
@ -610,8 +588,20 @@ server_handle_client(struct client *c)
} else if (key == prefix)
c->flags |= CLIENT_PREFIX;
else
window_key(w, c, key);
window_pane_key(wp, c, key);
}
/* Ensure the cursor is in the right place and correctly on or off. */
if (c->prompt_string == NULL && c->message_string == NULL &&
!server_locked && wp->screen->mode & MODE_CURSOR) {
oy = 0;
if (wp == wl->window->panes[1])
oy = wp->window->sy / 2;
tty_write(&c->tty, wp->screen, 0, TTY_CURSORMODE, 1);
tty_cursor(&c->tty, wp->screen->cx, wp->screen->cy, oy);
} else
tty_write(&c->tty, wp->screen, 0, TTY_CURSORMODE, 0);
}
/* Lost a client. */
@ -654,13 +644,14 @@ server_lost_client(struct client *c)
/* Handle window data. */
void
server_handle_window(struct window *w)
server_handle_window(struct window *w, int pane)
{
struct session *s;
struct client *c;
u_int i;
int action, update;
window_parse(w);
window_pane_parse(w->panes[pane]);
if (!(w->flags & WINDOW_BELL) && !(w->flags & WINDOW_ACTIVITY))
return;
@ -678,12 +669,22 @@ server_handle_window(struct window *w)
action = options_get_number(&s->options, "bell-action");
switch (action) {
case BELL_ANY:
tty_write_session(s, TTY_BELL);
if (s->flags & SESSION_UNATTACHED)
break;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c != NULL && c->session == s)
tty_putcode(&c->tty, TTYC_BEL);
}
break;
case BELL_CURRENT:
if (s->curw->window != w)
if (w->active != w->panes[pane])
break;
tty_write_session(s, TTY_BELL);
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c != NULL && c->session == s)
tty_putcode(&c->tty, TTYC_BEL);
}
break;
}
update = 1;
@ -703,20 +704,27 @@ server_handle_window(struct window *w)
}
/* Lost window: move clients on to next window. */
void
server_lost_window(struct window *w)
int
server_lost_window(struct window *w, int pane)
{
struct client *c;
struct session *s;
struct winlink *wl;
u_int i, j;
int destroyed;
struct client *c;
struct session *s;
struct winlink *wl;
struct window_pane *wp;
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")) {
w->fd = -1;
return;
wp->fd = -1;
return (0);
}
for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
@ -751,18 +759,20 @@ server_lost_window(struct window *w)
}
recalculate_sizes();
return (1);
}
/* Call any once-per-second timers. */
void
server_second_timers(void)
{
struct window *w;
u_int i;
int xtimeout;
struct tm now, then;
static time_t last_t = 0;
time_t t;
struct window *w;
struct window_pane *wp;
u_int i, j;
int xtimeout;
struct tm now, then;
static time_t last_t = 0;
time_t t;
t = time(NULL);
xtimeout = options_get_number(&global_options, "lock-after-time");
@ -771,8 +781,15 @@ server_second_timers(void)
for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
w = ARRAY_ITEM(&windows, i);
if (w->mode != NULL && w->mode->timer != NULL)
w->mode->timer(w);
if (w == NULL)
continue;
for (j = 0; j < 2; j++) {
wp = w->panes[j];
if (wp == NULL)
continue;
if (wp->mode != NULL && wp->mode->timer != NULL)
wp->mode->timer(wp);
}
}
gmtime_r(&t, &now);

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>
@ -39,11 +39,12 @@ char *status_prompt_complete(const char *);
void
status_redraw(struct client *c)
{
struct screen_redraw_ctx ctx;
struct screen_write_ctx ctx;
struct session *s = c->session;
struct winlink *wl;
struct window_pane *wp;
char *left, *right, *text, *ptr;
size_t llen, rlen, offset, xx, yy;
size_t llen, rlen, offset, xx, yy, sy;
size_t size, start, width;
struct grid_cell gc;
int larrow, rarrow;
@ -144,22 +145,28 @@ status_redraw(struct client *c)
width = xx;
draw:
/* Resize the target screen. */
if (screen_size_x(&c->status) != c->sx) {
screen_free(&c->status);
screen_init(&c->status, c->sx, 1, 0);
}
/* Bail here if anything is too small too. XXX. */
if (width == 0 || xx == 0)
goto blank;
/* Begin drawing and move to the starting position. */
screen_redraw_start_client(&ctx, c);
screen_write_start(&ctx, NULL, &c->status);
if (llen != 0) {
ctx.write(ctx.data, TTY_CURSORMOVE, 0, yy);
screen_redraw_puts(&ctx, &gc, "%s ", left);
screen_write_cursormove(&ctx, 0, yy);
screen_write_puts(&ctx, &gc, "%s ", left);
if (larrow)
screen_redraw_putc(&ctx, &gc, ' ');
screen_write_putc(&ctx, &gc, ' ');
} else {
if (larrow)
ctx.write(ctx.data, TTY_CURSORMOVE, 1, yy);
screen_write_cursormove(&ctx, 1, yy);
else
ctx.write(ctx.data, TTY_CURSORMOVE, 0, yy);
screen_write_cursormove(&ctx, 0, yy);
}
/* Draw each character in succession. */
@ -176,7 +183,7 @@ draw:
for (ptr = text; *ptr != '\0'; ptr++) {
if (offset >= start && offset < start + width)
screen_redraw_putc(&ctx, &gc, *ptr);
screen_write_putc(&ctx, &gc, *ptr);
offset++;
}
@ -190,7 +197,7 @@ draw:
gc.attr &= ~GRID_ATTR_REVERSE;
if (offset < start + width) {
if (offset >= start) {
screen_redraw_putc(&ctx, &gc, ' ');
screen_write_putc(&ctx, &gc, ' ');
}
offset++;
}
@ -200,12 +207,12 @@ draw:
/* Fill the remaining space if any. */
while (offset++ < xx)
screen_redraw_putc(&ctx, &gc, ' ');
screen_write_putc(&ctx, &gc, ' ');
/* Draw the last item. */
if (rlen != 0) {
ctx.write(ctx.data, TTY_CURSORMOVE, c->sx - rlen - 1, yy);
screen_redraw_puts(&ctx, &gc, " %s", right);
screen_write_cursormove(&ctx, c->sx - rlen - 1, yy);
screen_write_puts(&ctx, &gc, " %s", right);
}
/* Draw the arrows. */
@ -215,10 +222,10 @@ draw:
else
gc.attr &= ~GRID_ATTR_REVERSE;
if (llen != 0)
ctx.write(ctx.data, TTY_CURSORMOVE, llen + 1, yy);
screen_write_cursormove(&ctx, llen + 1, yy);
else
ctx.write(ctx.data, TTY_CURSORMOVE, 0, yy);
screen_redraw_putc(&ctx, &gc, '<');
screen_write_cursormove(&ctx, 0, yy);
screen_write_putc(&ctx, &gc, '<');
gc.attr &= ~GRID_ATTR_REVERSE;
}
if (rarrow != 0) {
@ -226,12 +233,11 @@ draw:
gc.attr |= GRID_ATTR_REVERSE;
else
gc.attr &= ~GRID_ATTR_REVERSE;
if (rlen != 0) {
ctx.write(
ctx.data, TTY_CURSORMOVE, c->sx - rlen - 2, yy);
} else
ctx.write(ctx.data, TTY_CURSORMOVE, c->sx - 1, yy);
screen_redraw_putc(&ctx, &gc, '>');
if (rlen != 0)
screen_write_cursormove(&ctx, c->sx - rlen - 2, yy);
else
screen_write_cursormove(&ctx, c->sx - 1, yy);
screen_write_putc(&ctx, &gc, '>');
gc.attr &= ~GRID_ATTR_REVERSE;
}
@ -239,10 +245,10 @@ draw:
blank:
/* Just draw the whole line as blank. */
screen_redraw_start_client(&ctx, c);
ctx.write(ctx.data, TTY_CURSORMOVE, 0, yy);
screen_write_start(&ctx, NULL, &c->status);
screen_write_cursormove(&ctx, 0, yy);
for (offset = 0; offset < c->sx; offset++)
screen_redraw_putc(&ctx, &gc, ' ');
screen_write_putc(&ctx, &gc, ' ');
goto out;
@ -251,17 +257,26 @@ off:
* Draw the real window last line. Necessary to wipe over message if
* status is off. Not sure this is the right place for this.
*/
screen_redraw_start_client(&ctx, c);
/* If the screen is too small, use blank. */
if (screen_size_y(c->session->curw->window->screen) < c->sy) {
ctx.write(ctx.data, TTY_CURSORMOVE, 0, c->sy - 1);
screen_write_start(&ctx, NULL, &c->status);
wp = s->curw->window->panes[1];
sy = c->sy - (c->sy / 2);
if (wp == NULL) {
wp = s->curw->window->panes[0];
sy = c->sy;
}
screen_write_cursormove(&ctx, 0, 0);
if (screen_size_y(wp->screen) < sy) {
/* If the screen is too small, use blank. */
for (offset = 0; offset < c->sx; offset++)
screen_redraw_putc(&ctx, &gc, ' ');
} else
screen_redraw_lines(&ctx, c->sy - 1, 1);
screen_write_putc(&ctx, &gc, ' ');
abort();
} else {
screen_write_copy(&ctx, wp->screen, 0, wp->screen->grid->hsize +
screen_size_y(wp->screen) - 1, c->sx, 1);
}
out:
screen_redraw_stop(&ctx);
screen_write_stop(&ctx);
if (left != NULL)
xfree(left);
@ -272,6 +287,7 @@ out:
char *
status_replace(struct session *s, char *fmt, time_t t)
{
struct winlink *wl = s->curw;
static char out[BUFSIZ];
char in[BUFSIZ], ch, *iptr, *optr, *ptr, *endptr;
size_t len;
@ -300,7 +316,7 @@ status_replace(struct session *s, char *fmt, time_t t)
switch (*iptr++) {
case 'T':
ptr = s->curw->window->base.title;
ptr = wl->window->active->base.title;
len = strlen(ptr);
if ((size_t) n < len)
len = n;
@ -333,7 +349,7 @@ status_width(struct winlink *wl)
return (xsnprintf(NULL, 0, "%d:%s ", wl->idx, wl->window->name));
#else
char *s;
size_t n;
size_t n;
xasprintf(&s, "%d:%s ", wl->idx, wl->window->name);
n = strlen(s);
@ -372,64 +388,68 @@ status_print(struct session *s, struct winlink *wl, struct grid_cell *gc)
void
status_message_redraw(struct client *c)
{
struct screen_redraw_ctx ctx;
struct screen_write_ctx ctx;
struct session *s = c->session;
size_t xx, yy;
size_t len;
struct grid_cell gc;
if (c->sx == 0 || c->sy == 0)
return;
if (screen_size_x(&c->status) != c->sx) {
screen_free(&c->status);
screen_init(&c->status, c->sx, 1, 0);
}
xx = strlen(c->message_string);
if (xx > c->sx)
xx = c->sx;
yy = c->sy - 1;
len = strlen(c->message_string);
if (len > c->sx)
len = c->sx;
memcpy(&gc, &grid_default_cell, sizeof gc);
gc.fg = options_get_number(&s->options, "message-fg");
gc.bg = options_get_number(&s->options, "message-bg");
screen_redraw_start_client(&ctx, c);
screen_write_start(&ctx, NULL, &c->status);
ctx.write(ctx.data, TTY_CURSORMOVE, 0, yy);
screen_redraw_puts(&ctx, &gc, "%.*s", (int) xx, c->message_string);
for (; xx < c->sx; xx++)
screen_redraw_putc(&ctx, &gc, ' ');
screen_write_cursormove(&ctx, 0, 0);
screen_write_puts(&ctx, &gc, "%.*s", (int) len, c->message_string);
for (; len < c->sx; len++)
screen_write_putc(&ctx, &gc, ' ');
screen_redraw_stop(&ctx);
tty_write_client(c, TTY_CURSORMODE, 0);
screen_write_stop(&ctx);
}
/* Draw client prompt on status line of present else on last line. */
void
status_prompt_redraw(struct client *c)
{
struct screen_redraw_ctx ctx;
struct screen_write_ctx ctx;
struct session *s = c->session;
size_t i, xx, yy, left, size, offset, n;
size_t i, size, left, len, offset, n;
char ch;
struct grid_cell gc;
if (c->sx == 0 || c->sy == 0)
return;
if (screen_size_x(&c->status) != c->sx) {
screen_free(&c->status);
screen_init(&c->status, c->sx, 1, 0);
}
offset = 0;
xx = strlen(c->prompt_string);
if (xx > c->sx)
xx = c->sx;
yy = c->sy - 1;
len = strlen(c->prompt_string);
if (len > c->sx)
len = c->sx;
memcpy(&gc, &grid_default_cell, sizeof gc);
gc.fg = options_get_number(&s->options, "message-fg");
gc.bg = options_get_number(&s->options, "message-bg");
screen_redraw_start_client(&ctx, c);
screen_write_start(&ctx, NULL, &c->status);
ctx.write(ctx.data, TTY_CURSORMOVE, 0, yy);
screen_redraw_puts(&ctx, &gc, "%.*s", (int) xx, c->prompt_string);
screen_write_cursormove(&ctx, 0, 0);
screen_write_puts(&ctx, &gc, "%.*s", (int) len, c->prompt_string);
left = c->sx - xx;
left = c->sx - len;
if (left != 0) {
if (c->prompt_index < left)
size = strlen(c->prompt_buffer);
@ -444,20 +464,18 @@ status_prompt_redraw(struct client *c)
if (n > left)
n = left;
for (i = 0; i < n; i++)
screen_redraw_putc(&ctx, &gc, '*');
screen_write_putc(&ctx, &gc, '*');
} else {
screen_redraw_puts(&ctx, &gc,
screen_write_puts(&ctx, &gc,
"%.*s", (int) left, c->prompt_buffer + offset);
}
for (i = xx + size; i < c->sx; i++) {
screen_redraw_putc(&ctx, &gc, ' ');
ctx.s->cx++;
}
for (i = len + size; i < c->sx; i++)
screen_write_putc(&ctx, &gc, ' ');
}
/* Draw a fake cursor. */
ctx.write(ctx.data, TTY_CURSORMOVE, xx + c->prompt_index - offset, yy);
screen_write_cursormove(&ctx, len + c->prompt_index - offset, 0);
if (c->prompt_index == strlen(c->prompt_buffer))
ch = ' ';
else
@ -466,11 +484,9 @@ status_prompt_redraw(struct client *c)
ch = ' ';
gc.bg = gc.fg;
gc.fg = options_get_number(&s->options, "message-bg");
screen_redraw_putc(&ctx, &gc, ch);
screen_write_putc(&ctx, &gc, ch);
screen_redraw_stop(&ctx);
tty_write_client(c, TTY_CURSORMODE, 0);
screen_write_stop(&ctx);
}
/* 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>
@ -330,8 +330,6 @@ struct tty_term_code_entry {
/* Output commands. */
enum tty_cmd {
TTY_BELL,
TTY_CARRIAGERETURN,
TTY_CELL,
TTY_CLEARENDOFLINE,
TTY_CLEARENDOFSCREEN,
@ -339,12 +337,7 @@ enum tty_cmd {
TTY_CLEARSCREEN,
TTY_CLEARSTARTOFLINE,
TTY_CLEARSTARTOFSCREEN,
TTY_CURSORDOWN,
TTY_CURSORLEFT,
TTY_CURSORMODE,
TTY_CURSORMOVE,
TTY_CURSORRIGHT,
TTY_CURSORUP,
TTY_DELETECHARACTER,
TTY_DELETELINE,
TTY_INSERTCHARACTER,
@ -355,7 +348,6 @@ enum tty_cmd {
TTY_LINEFEED,
TTY_MOUSEMODE,
TTY_REVERSEINDEX,
TTY_SCROLLREGION,
};
/* Message codes. */
@ -514,17 +506,6 @@ struct screen {
struct screen_sel sel;
};
/* Screen redraw context. */
struct screen_redraw_ctx {
void *data;
void (*write)(void *, enum tty_cmd, ...);
u_int saved_cx;
u_int saved_cy;
struct screen *s;
};
/* Screen write context. */
struct screen_write_ctx {
void *data;
@ -547,7 +528,7 @@ struct input_arg {
/* Input parser context. */
struct input_ctx {
struct window *w;
struct window_pane *wp;
struct screen_write_ctx ctx;
u_char *buf;
@ -584,17 +565,19 @@ struct input_ctx {
* right function to handle input and output.
*/
struct client;
struct window;
struct window_mode {
struct screen *(*init)(struct window *);
void (*free)(struct window *);
void (*resize)(struct window *, u_int, u_int);
void (*key)(struct window *, struct client *, int);
void (*timer)(struct window *);
struct screen *(*init)(struct window_pane *);
void (*free)(struct window_pane *);
void (*resize)(struct window_pane *, u_int, u_int);
void (*key)(struct window_pane *, struct client *, int);
void (*timer)(struct window_pane *);
};
/* Window structure. */
struct window {
char *name;
/* Child window structure. */
struct window_pane {
struct window *window;
char *cmd;
char *cwd;
@ -604,18 +587,29 @@ struct window {
struct input_ctx ictx;
struct options options;
struct screen *screen;
struct screen base;
const struct window_mode *mode;
void *modedata;
};
/* Window structure. */
struct window {
char *name;
struct window_pane *active;
struct window_pane *panes[2];
u_int sx;
u_int sy;
int flags;
#define WINDOW_BELL 0x1
#define WINDOW_HIDDEN 0x2
#define WINDOW_ACTIVITY 0x4
struct screen *screen;
struct screen base;
const struct window_mode *mode;
void *modedata;
struct options options;
u_int references;
};
@ -698,6 +692,14 @@ SLIST_HEAD(tty_terms, tty_term);
struct tty {
char *path;
u_int cx;
u_int cy;
int cursor;
u_int rlower;
u_int rupper;
char *termname;
struct tty_term *term;
@ -742,6 +744,8 @@ struct client {
u_int sx;
u_int sy;
struct screen status;
#define CLIENT_TERMINAL 0x1
#define CLIENT_PREFIX 0x2
#define CLIENT_MOUSE 0x4
@ -973,14 +977,21 @@ void options_set_number(struct options *, const char *, long long);
long long options_get_number(struct options *, const char *);
/* tty.c */
void tty_cursor(struct tty *, u_int, u_int, u_int);
void tty_putcode(struct tty *, enum tty_code_code);
void tty_putcode1(struct tty *, enum tty_code_code, int);
void tty_putcode2(struct tty *, enum tty_code_code, int, int);
void tty_puts(struct tty *, const char *);
void tty_putc(struct tty *, char);
void tty_init(struct tty *, char *, char *);
void tty_set_title(struct tty *, const char *);
int tty_open(struct tty *, char **);
void tty_close(struct tty *);
void tty_free(struct tty *);
void tty_write(struct tty *, struct screen *, enum tty_cmd, ...);
void tty_vwrite(
struct tty *, struct screen *s, enum tty_cmd, va_list);
void tty_write(struct tty *,
struct screen *, u_int, enum tty_cmd, ...);
void tty_vwrite(struct tty *,
struct screen *s, u_int, enum tty_cmd, va_list);
/* tty-term.c */
extern struct tty_terms tty_terms;
@ -1003,12 +1014,8 @@ void tty_keys_free(struct tty *);
int tty_keys_next(struct tty *, int *);
/* tty-write.c */
void tty_write_client(void *, enum tty_cmd, ...);
void tty_vwrite_client(void *, enum tty_cmd, va_list);
void tty_write_window(void *, enum tty_cmd, ...);
void tty_vwrite_window(void *, enum tty_cmd, va_list);
void tty_write_session(void *, enum tty_cmd, ...);
void tty_vwrite_session(void *, enum tty_cmd, va_list);
/* options-cmd.c */
void set_option_string(struct cmd_ctx *,
@ -1102,9 +1109,11 @@ extern const struct cmd_entry cmd_show_buffer_entry;
extern const struct cmd_entry cmd_show_options_entry;
extern const struct cmd_entry cmd_show_window_options_entry;
extern const struct cmd_entry cmd_source_file_entry;
extern const struct cmd_entry cmd_split_window_entry;
extern const struct cmd_entry cmd_start_server_entry;
extern const struct cmd_entry cmd_swap_window_entry;
extern const struct cmd_entry cmd_switch_client_entry;
extern const struct cmd_entry cmd_switch_pane_entry;
extern const struct cmd_entry cmd_unbind_key_entry;
extern const struct cmd_entry cmd_unlink_window_entry;
@ -1200,12 +1209,13 @@ void server_set_client_prompt(struct client *,
void server_clear_client_prompt(struct client *);
struct session *server_extract_session(
struct msg_command_data *, char *, char **);
void server_write(struct client *, enum hdrtype, const void *, size_t);
void server_write_client(
struct client *, enum hdrtype, const void *, size_t);
void server_write_session(
struct session *, enum hdrtype, const void *, size_t);
void server_write_window(
struct window *, enum hdrtype, const void *, size_t);
struct window *, enum hdrtype, const void *, size_t);
void server_redraw_client(struct client *);
void server_status_client(struct client *);
void server_redraw_session(struct session *);
@ -1225,12 +1235,12 @@ void status_prompt_key(struct client *, int);
void recalculate_sizes(void);
/* input.c */
void input_init(struct window *);
void input_free(struct window *);
void input_parse(struct window *);
void input_init(struct window_pane *);
void input_free(struct window_pane *);
void input_parse(struct window_pane *);
/* input-key.c */
void input_key(struct window *, int);
void input_key(struct window_pane *, int);
/* colour.c */
const char *colour_tostring(u_char);
@ -1278,12 +1288,8 @@ void grid_view_insert_cells(struct grid_data *, u_int, u_int, u_int);
void grid_view_delete_cells(struct grid_data *, u_int, u_int, u_int);
/* screen-write.c */
void screen_write_start_window(struct screen_write_ctx *, struct window *);
void screen_write_start_client(struct screen_write_ctx *, struct client *);
void screen_write_start_session(
struct screen_write_ctx *, struct session *);
void screen_write_start(struct screen_write_ctx *,
struct screen *, void (*)(void *, enum tty_cmd, ...), void *);
void screen_write_start(
struct screen_write_ctx *, struct window_pane *, struct screen *);
void screen_write_stop(struct screen_write_ctx *);
void printflike3 screen_write_puts(
struct screen_write_ctx *, struct grid_cell *, const char *, ...);
@ -1318,20 +1324,8 @@ void screen_write_clearscreen(struct screen_write_ctx *);
void screen_write_cell(struct screen_write_ctx *, const struct grid_cell *);
/* screen-redraw.c */
void screen_redraw_start_window(struct screen_redraw_ctx *, struct window *);
void screen_redraw_start_client(struct screen_redraw_ctx *, struct client *);
void screen_redraw_start_session(
struct screen_redraw_ctx *, struct session *);
void screen_redraw_start(struct screen_redraw_ctx *,
struct screen *, void (*)(void *, enum tty_cmd, ...), void *);
void screen_redraw_stop(struct screen_redraw_ctx *);
void printflike3 screen_redraw_puts(
struct screen_redraw_ctx *, struct grid_cell *, const char *, ...);
void screen_redraw_putc(
struct screen_redraw_ctx *, struct grid_cell *, u_char);
void screen_redraw_cell(struct screen_redraw_ctx *, u_int, u_int);
void screen_redraw_lines(struct screen_redraw_ctx *, u_int, u_int);
void screen_redraw_columns(struct screen_redraw_ctx *, u_int, u_int);
void screen_redraw_screen(struct client *, struct screen *);
void screen_redraw_status(struct client *);
/* screen.c */
void screen_init(struct screen *, u_int, u_int, u_int);
@ -1364,14 +1358,19 @@ void winlink_stack_push(struct winlink_stack *, struct winlink *);
void winlink_stack_remove(struct winlink_stack *, struct winlink *);
struct window *window_create(const char *, const char *,
const char *, const char **, u_int, u_int, u_int);
int window_spawn(struct window *,
const char *, const char *, const char **);
void window_destroy(struct window *);
int window_resize(struct window *, u_int, u_int);
int window_set_mode(struct window *, const struct window_mode *);
void window_reset_mode(struct window *);
void window_parse(struct window *);
void window_key(struct window *, struct client *, int);
int window_remove_pane(struct window *, int);
struct window_pane *window_pane_create(struct window *, u_int, u_int, u_int);
void window_pane_destroy(struct window_pane *);
int window_pane_spawn(struct window_pane *,
const char *, const char *, const char **);
int window_pane_resize(struct window_pane *, u_int, u_int);
int window_pane_set_mode(
struct window_pane *, const struct window_mode *);
void window_pane_reset_mode(struct window_pane *);
void window_pane_parse(struct window_pane *);
void window_pane_key(struct window_pane *, struct client *, int);
/* window-clock.c */
extern const struct window_mode window_clock_mode;
@ -1384,8 +1383,8 @@ extern const struct window_mode window_scroll_mode;
/* window-more.c */
extern const struct window_mode window_more_mode;
void window_more_vadd(struct window *, const char *, va_list);
void printflike2 window_more_add(struct window *, const char *, ...);
void window_more_vadd(struct window_pane *, const char *, va_list);
void printflike2 window_more_add(struct window_pane *, const char *, ...);
/* session.c */
extern struct sessions sessions;
@ -1399,7 +1398,7 @@ struct session *session_create(
void session_destroy(struct session *);
int session_index(struct session *, u_int *);
struct winlink *session_new(struct session *,
const char *, const char *, const char *, int);
const char *, const char *, const char *, int);
struct winlink *session_attach(struct session *, struct window *, int);
int session_detach(struct session *, struct winlink *);
int session_has(struct session *, struct window *);

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>
@ -20,26 +20,6 @@
#include "tmux.h"
void
tty_write_client(void *ptr, enum tty_cmd cmd, ...)
{
struct client *c = ptr;
va_list ap;
va_start(ap, cmd);
tty_vwrite_client(c, cmd, ap);
va_end(ap);
}
void
tty_vwrite_client(void *ptr, enum tty_cmd cmd, va_list ap)
{
struct client *c = ptr;
struct screen *s = c->session->curw->window->screen;
tty_vwrite(&c->tty, s, cmd, ap);
}
void
tty_write_window(void *ptr, enum tty_cmd cmd, ...)
{
@ -53,55 +33,28 @@ tty_write_window(void *ptr, enum tty_cmd cmd, ...)
void
tty_vwrite_window(void *ptr, enum tty_cmd cmd, va_list ap)
{
struct window *w = ptr;
struct client *c;
va_list aq;
u_int i;
struct window_pane *wp = ptr;
struct client *c;
va_list aq;
u_int i, oy;
if (w->flags & WINDOW_HIDDEN)
if (wp->window->flags & WINDOW_HIDDEN)
return;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c == NULL || c->session == NULL)
continue;
if (c->session->curw->window != w)
continue;
va_copy(aq, ap);
tty_vwrite_client(c, cmd, aq);
va_end(aq);
}
}
void
tty_write_session(void *ptr, enum tty_cmd cmd, ...)
{
va_list ap;
va_start(ap, cmd);
tty_vwrite_session(ptr, cmd, ap);
va_end(ap);
}
void
tty_vwrite_session(void *ptr, enum tty_cmd cmd, va_list ap)
{
struct session *s = ptr;
struct client *c;
va_list aq;
u_int i;
if (s->flags & SESSION_UNATTACHED)
return;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c == NULL || c->session != s)
continue;
va_copy(aq, ap);
tty_vwrite_client(c, cmd, aq);
va_end(aq);
if (c->session->curw->window == wp->window) {
if (wp == wp->window->panes[0])
oy = 0;
else
oy = wp->window->sy / 2;
va_copy(aq, ap);
tty_vwrite(&c->tty, wp->screen, oy, 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>
@ -34,47 +34,35 @@ void tty_emulate_repeat(
struct tty *, enum tty_code_code, enum tty_code_code, u_int);
void tty_raw(struct tty *, const char *);
void tty_putcode(struct tty *, enum tty_code_code);
void tty_putcode1(struct tty *, enum tty_code_code, int);
void tty_putcode2(struct tty *, enum tty_code_code, int, int);
void tty_puts(struct tty *, const char *);
void tty_putc(struct tty *, char);
void tty_reset(struct tty *);
void tty_region(struct tty *, struct screen *, u_int);
void tty_attributes(struct tty *, const struct grid_cell *);
void tty_attributes_fg(struct tty *, const struct grid_cell *);
void tty_attributes_bg(struct tty *, const struct grid_cell *);
void tty_cmd_bell(struct tty *, struct screen *, va_list);
void tty_cmd_carriagereturn(struct tty *, struct screen *, va_list);
void tty_cmd_cell(struct tty *, struct screen *, va_list);
void tty_cmd_clearendofline(struct tty *, struct screen *, va_list);
void tty_cmd_clearendofscreen(struct tty *, struct screen *, va_list);
void tty_cmd_clearline(struct tty *, struct screen *, va_list);
void tty_cmd_clearscreen(struct tty *, struct screen *, va_list);
void tty_cmd_clearstartofline(struct tty *, struct screen *, va_list);
void tty_cmd_clearstartofscreen(struct tty *, struct screen *, va_list);
void tty_cmd_cursordown(struct tty *, struct screen *, va_list);
void tty_cmd_cursorleft(struct tty *, struct screen *, va_list);
void tty_cmd_cursormode(struct tty *, struct screen *, va_list);
void tty_cmd_cursormove(struct tty *, struct screen *, va_list);
void tty_cmd_cursorright(struct tty *, struct screen *, va_list);
void tty_cmd_cursorup(struct tty *, struct screen *, va_list);
void tty_cmd_deletecharacter(struct tty *, struct screen *, va_list);
void tty_cmd_deleteline(struct tty *, struct screen *, va_list);
void tty_cmd_insertcharacter(struct tty *, struct screen *, va_list);
void tty_cmd_insertline(struct tty *, struct screen *, va_list);
void tty_cmd_insertmode(struct tty *, struct screen *, va_list);
void tty_cmd_kcursormode(struct tty *, struct screen *, va_list);
void tty_cmd_kkeypadmode(struct tty *, struct screen *, va_list);
void tty_cmd_linefeed(struct tty *, struct screen *, va_list);
void tty_cmd_mousemode(struct tty *, struct screen *, va_list);
void tty_cmd_reverseindex(struct tty *, struct screen *, va_list);
void tty_cmd_scrollregion(struct tty *, struct screen *, va_list);
void tty_cmd_bell(struct tty *, struct screen *, u_int, va_list);
void tty_cmd_carriagereturn(struct tty *, struct screen *, u_int, va_list);
void tty_cmd_cell(struct tty *, struct screen *, u_int, va_list);
void tty_cmd_clearendofline(struct tty *, struct screen *, u_int, va_list);
void tty_cmd_clearendofscreen(struct tty *, struct screen *, u_int, va_list);
void tty_cmd_clearline(struct tty *, struct screen *, u_int, va_list);
void tty_cmd_clearscreen(struct tty *, struct screen *, u_int, va_list);
void tty_cmd_clearstartofline(struct tty *, struct screen *, u_int, va_list);
void tty_cmd_clearstartofscreen(struct tty *, struct screen *, u_int, va_list);
void tty_cmd_cursormode(struct tty *, struct screen *, u_int, va_list);
void tty_cmd_deletecharacter(struct tty *, struct screen *, u_int, va_list);
void tty_cmd_deleteline(struct tty *, struct screen *, u_int, va_list);
void tty_cmd_insertcharacter(struct tty *, struct screen *, u_int, va_list);
void tty_cmd_insertline(struct tty *, struct screen *, u_int, va_list);
void tty_cmd_insertmode(struct tty *, struct screen *, u_int, va_list);
void tty_cmd_kcursormode(struct tty *, struct screen *, u_int, va_list);
void tty_cmd_kkeypadmode(struct tty *, struct screen *, u_int, va_list);
void tty_cmd_linefeed(struct tty *, struct screen *, u_int, va_list);
void tty_cmd_mousemode(struct tty *, struct screen *, u_int, va_list);
void tty_cmd_reverseindex(struct tty *, struct screen *, u_int, va_list);
void (*tty_cmds[])(struct tty *, struct screen *, va_list) = {
tty_cmd_bell,
tty_cmd_carriagereturn,
void (*tty_cmds[])(struct tty *, struct screen *, u_int, va_list) = {
tty_cmd_cell,
tty_cmd_clearendofline,
tty_cmd_clearendofscreen,
@ -82,12 +70,7 @@ void (*tty_cmds[])(struct tty *, struct screen *, va_list) = {
tty_cmd_clearscreen,
tty_cmd_clearstartofline,
tty_cmd_clearstartofscreen,
tty_cmd_cursordown,
tty_cmd_cursorleft,
tty_cmd_cursormode,
tty_cmd_cursormove,
tty_cmd_cursorright,
tty_cmd_cursorup,
tty_cmd_deletecharacter,
tty_cmd_deleteline,
tty_cmd_insertcharacter,
@ -98,7 +81,6 @@ void (*tty_cmds[])(struct tty *, struct screen *, va_list) = {
tty_cmd_linefeed,
tty_cmd_mousemode,
tty_cmd_reverseindex,
tty_cmd_scrollregion,
};
void
@ -138,6 +120,9 @@ tty_open(struct tty *tty, char **cause)
else
tty->log_fd = -1;
tty->cx = UINT_MAX;
tty->cy = UINT_MAX;
if ((tty->term = tty_term_find(tty->termname, tty->fd, cause)) == NULL)
goto error;
@ -314,6 +299,8 @@ tty_putc(struct tty *tty, char ch)
ch = tty_get_acs(tty, ch);
buffer_write8(tty->out, ch);
tty->cx++; /* This is right most of the time. */
if (tty->log_fd != -1)
write(tty->log_fd, &ch, 1);
}
@ -344,72 +331,35 @@ tty_emulate_repeat(
}
void
tty_write(struct tty *tty, struct screen *s, enum tty_cmd cmd, ...)
tty_write(struct tty *tty, struct screen *s, u_int oy, enum tty_cmd cmd, ...)
{
va_list ap;
va_start(ap, cmd);
tty_vwrite(tty, s, cmd, ap);
tty_vwrite(tty, s, oy, cmd, ap);
va_end(ap);
}
void
tty_vwrite(struct tty *tty, struct screen *s, enum tty_cmd cmd, va_list ap)
tty_vwrite(
struct tty *tty, struct screen *s, u_int oy, enum tty_cmd cmd, va_list ap)
{
if (tty->flags & TTY_FREEZE || tty->term == NULL)
return;
if (tty_cmds[cmd] != NULL)
tty_cmds[cmd](tty, s, ap);
tty_cmds[cmd](tty, s, oy, ap);
}
void
tty_cmd_cursorup(struct tty *tty, unused struct screen *s, va_list ap)
{
u_int ua;
ua = va_arg(ap, u_int);
tty_emulate_repeat(tty, TTYC_CUU, TTYC_CUU1, ua);
}
void
tty_cmd_cursordown(struct tty *tty, unused struct screen *s, va_list ap)
{
u_int ua;
ua = va_arg(ap, u_int);
tty_emulate_repeat(tty, TTYC_CUD, TTYC_CUD1, ua);
}
void
tty_cmd_cursorright(struct tty *tty, unused struct screen *s, va_list ap)
{
u_int ua;
ua = va_arg(ap, u_int);
tty_emulate_repeat(tty, TTYC_CUF, TTYC_CUF1, ua);
}
void
tty_cmd_cursorleft(struct tty *tty, unused struct screen *s, va_list ap)
{
u_int ua;
ua = va_arg(ap, u_int);
tty_emulate_repeat(tty, TTYC_CUB, TTYC_CUB1, ua);
}
void
tty_cmd_insertcharacter(struct tty *tty, unused struct screen *s, va_list ap)
tty_cmd_insertcharacter(
struct tty *tty, unused struct screen *s, u_int oy, va_list ap)
{
u_int ua;
ua = va_arg(ap, u_int);
tty_reset(tty);
tty_cursor(tty, s->cx, s->cy, oy);
if (tty_term_has(tty->term, TTYC_ICH) ||
tty_term_has(tty->term, TTYC_ICH1))
@ -419,117 +369,125 @@ tty_cmd_insertcharacter(struct tty *tty, unused struct screen *s, va_list ap)
while (ua-- > 0)
tty_putc(tty, ' ');
tty_putcode(tty, TTYC_RMIR);
tty_putcode2(tty, TTYC_CUP, s->cy, s->cx);
tty_putcode2(tty, TTYC_CUP, oy + s->cy, s->cx);
}
}
void
tty_cmd_deletecharacter(struct tty *tty, unused struct screen *s, va_list ap)
tty_cmd_deletecharacter(
struct tty *tty, unused struct screen *s, u_int oy, va_list ap)
{
u_int ua;
ua = va_arg(ap, u_int);
tty_reset(tty);
tty_cursor(tty, s->cx, s->cy, oy);
tty_emulate_repeat(tty, TTYC_DCH, TTYC_DCH1, ua);
}
void
tty_cmd_insertline(struct tty *tty, unused struct screen *s, va_list ap)
tty_cmd_insertline(
struct tty *tty, unused struct screen *s, u_int oy, va_list ap)
{
u_int ua;
ua = va_arg(ap, u_int);
tty_reset(tty);
tty_region(tty, s, oy);
tty_cursor(tty, s->cx, s->cy, oy);
tty_emulate_repeat(tty, TTYC_IL, TTYC_IL1, ua);
}
void
tty_cmd_deleteline(struct tty *tty, unused struct screen *s, va_list ap)
tty_cmd_deleteline(
struct tty *tty, unused struct screen *s, u_int oy, va_list ap)
{
u_int ua;
ua = va_arg(ap, u_int);
tty_reset(tty);
tty_region(tty, s, oy);
tty_cursor(tty, s->cx, s->cy, oy);
tty_emulate_repeat(tty, TTYC_DL, TTYC_DL1, ua);
}
void
tty_cmd_clearline(struct tty *tty, struct screen *s, unused va_list ap)
tty_cmd_clearline(
struct tty *tty, struct screen *s, u_int oy, unused va_list ap)
{
u_int i;
tty_reset(tty);
tty_cursor(tty, s->cx, s->cy, oy);
if (tty_term_has(tty->term, TTYC_EL)) {
tty_putcode2(tty, TTYC_CUP, s->cy, 0);
tty_putcode2(tty, TTYC_CUP, oy + s->cy, 0);
tty_putcode(tty, TTYC_EL);
tty_putcode2(tty, TTYC_CUP, s->cy, s->cx);
tty_putcode2(tty, TTYC_CUP, oy + s->cy, s->cx);
} else {
tty_putcode2(tty, TTYC_CUP, s->cy, 0);
tty_putcode2(tty, TTYC_CUP, oy + s->cy, 0);
for (i = 0; i < screen_size_x(s); i++)
tty_putc(tty, ' ');
tty_putcode2(tty, TTYC_CUP, s->cy, s->cx);
tty_putcode2(tty, TTYC_CUP, oy + s->cy, s->cx);
}
}
void
tty_cmd_clearendofline(struct tty *tty, struct screen *s, unused va_list ap)
tty_cmd_clearendofline(
struct tty *tty, struct screen *s, u_int oy, unused va_list ap)
{
u_int i;
tty_reset(tty);
tty_cursor(tty, s->cx, s->cy, oy);
if (tty_term_has(tty->term, TTYC_EL))
tty_putcode(tty, TTYC_EL);
else {
tty_putcode2(tty, TTYC_CUP, s->cy, s->cx);
tty_putcode2(tty, TTYC_CUP, oy + s->cy, s->cx);
for (i = s->cx; i < screen_size_x(s); i++)
tty_putc(tty, ' ');
tty_putcode2(tty, TTYC_CUP, s->cy, s->cx);
tty_putcode2(tty, TTYC_CUP, oy + s->cy, s->cx);
}
}
void
tty_cmd_clearstartofline(struct tty *tty, struct screen *s, unused va_list ap)
tty_cmd_clearstartofline(
struct tty *tty, struct screen *s, u_int oy, unused va_list ap)
{
u_int i;
tty_reset(tty);
tty_cursor(tty, s->cx, s->cy, oy);
if (tty_term_has(tty->term, TTYC_EL1))
tty_putcode(tty, TTYC_EL1);
else {
tty_putcode2(tty, TTYC_CUP, s->cy, 0);
tty_putcode2(tty, TTYC_CUP, oy + s->cy, 0);
for (i = 0; i < s->cx + 1; i++)
tty_putc(tty, ' ');
tty_putcode2(tty, TTYC_CUP, s->cy, s->cx);
tty_putcode2(tty, TTYC_CUP, oy + s->cy, s->cx);
}
}
void
tty_cmd_cursormove(struct tty *tty, unused struct screen *s, va_list ap)
tty_cmd_cursormode(
struct tty *tty, unused struct screen *s, unused u_int oy, va_list ap)
{
u_int ua, ub;
ua = va_arg(ap, u_int);
ub = va_arg(ap, u_int);
tty_putcode2(tty, TTYC_CUP, ub, ua);
}
void
tty_cmd_cursormode(struct tty *tty, unused struct screen *s, va_list ap)
{
u_int ua;
int ua;
ua = va_arg(ap, int);
if (tty->cursor == ua)
return;
tty->cursor = ua;
if (ua && !(tty->flags & TTY_NOCURSOR))
tty_putcode(tty, TTYC_CNORM);
else
@ -538,28 +496,21 @@ tty_cmd_cursormode(struct tty *tty, unused struct screen *s, va_list ap)
void
tty_cmd_reverseindex(
struct tty *tty, unused struct screen *s, unused va_list ap)
struct tty *tty, struct screen *s, u_int oy, unused va_list ap)
{
tty_reset(tty);
tty_region(tty, s, oy);
tty_cursor(tty, s->cx, s->cy, oy);
tty_putcode(tty, TTYC_RI);
}
void
tty_cmd_scrollregion(struct tty *tty, unused struct screen *s, va_list ap)
tty_cmd_insertmode(unused struct tty *tty,
unused struct screen *s, unused u_int oy, va_list ap)
{
u_int ua, ub;
ua = va_arg(ap, u_int);
ub = va_arg(ap, u_int);
tty_putcode2(tty, TTYC_CSR, ua, ub);
}
void
tty_cmd_insertmode(unused struct tty *tty, unused struct screen *s, va_list ap)
{
u_int ua;
int ua;
ua = va_arg(ap, int);
@ -573,9 +524,10 @@ tty_cmd_insertmode(unused struct tty *tty, unused struct screen *s, va_list ap)
}
void
tty_cmd_mousemode(struct tty *tty, unused struct screen *s, va_list ap)
tty_cmd_mousemode(
struct tty *tty, unused struct screen *s, unused u_int oy, va_list ap)
{
u_int ua;
int ua;
if (!tty_term_has(tty->term, TTYC_KMOUS))
return;
@ -589,52 +541,45 @@ tty_cmd_mousemode(struct tty *tty, unused struct screen *s, va_list ap)
}
void
tty_cmd_kcursormode(
unused struct tty *tty, unused struct screen *s, unused va_list ap)
tty_cmd_kcursormode(unused struct tty *tty,
unused struct screen *s, unused u_int oy, unused va_list ap)
{
}
void
tty_cmd_kkeypadmode(
unused struct tty *tty, unused struct screen *s, unused va_list ap)
tty_cmd_kkeypadmode(unused struct tty *tty,
unused struct screen *s, unused u_int oy, unused va_list ap)
{
}
void
tty_cmd_linefeed(struct tty *tty, unused struct screen *s, unused va_list ap)
tty_cmd_linefeed(struct tty *tty, struct screen *s, u_int oy, unused va_list ap)
{
tty_reset(tty);
tty_region(tty, s, oy);
tty_cursor(tty, s->cx, s->cy, oy);
tty_putc(tty, '\n');
}
void
tty_cmd_carriagereturn(
struct tty *tty, unused struct screen *s, unused va_list ap)
{
tty_reset(tty);
if (tty_term_has(tty->term, TTYC_CR))
tty_putcode(tty, TTYC_CR);
else
tty_putc(tty, '\r');
}
void
tty_cmd_bell(struct tty *tty, unused struct screen *s, unused va_list ap)
tty_cmd_bell(struct tty *tty,
unused struct screen *s, unused u_int oy, unused va_list ap)
{
tty_putcode(tty, TTYC_BEL);
}
void
tty_cmd_clearendofscreen(struct tty *tty, struct screen *s, unused va_list ap)
tty_cmd_clearendofscreen(
struct tty *tty, struct screen *s, u_int oy, unused va_list ap)
{
u_int i, j;
tty_reset(tty);
tty_cursor(tty, s->cx, s->cy, oy);
if (tty_term_has(tty->term, TTYC_EL)) {
for (i = s->cy; i < screen_size_y(s); i++) {
for (i = oy + s->cy; i < oy + screen_size_y(s); i++) {
tty_putcode(tty, TTYC_EL);
if (i != screen_size_y(s) - 1)
tty_emulate_repeat(tty, TTYC_CUD, TTYC_CUD1, 1);
@ -642,47 +587,51 @@ tty_cmd_clearendofscreen(struct tty *tty, struct screen *s, unused va_list ap)
} else {
for (i = s->cx; i < screen_size_y(s); i++)
tty_putc(tty, ' ');
for (j = s->cy; j < screen_size_y(s); j++) {
for (j = oy + s->cy; j < oy + screen_size_y(s); j++) {
for (i = 0; i < screen_size_x(s); i++)
tty_putc(tty, ' ');
}
}
tty_putcode2(tty, TTYC_CUP, s->cy, s->cx);
tty_putcode2(tty, TTYC_CUP, oy + s->cy, s->cx);
}
void
tty_cmd_clearstartofscreen(struct tty *tty, struct screen *s, unused va_list ap)
tty_cmd_clearstartofscreen(
struct tty *tty, struct screen *s, u_int oy, unused va_list ap)
{
u_int i, j;
tty_reset(tty);
tty_cursor(tty, s->cx, s->cy, oy);
tty_putcode2(tty, TTYC_CUP, 0, 0);
tty_putcode2(tty, TTYC_CUP, oy, 0);
if (tty_term_has(tty->term, TTYC_EL)) {
for (i = 0; i < s->cy; i++) {
for (i = 0; i < oy + s->cy; i++) {
tty_putcode(tty, TTYC_EL);
tty_emulate_repeat(tty, TTYC_CUD, TTYC_CUD1, 1);
}
tty_putcode2(tty, TTYC_CUP, s->cy, 0);
tty_putcode2(tty, TTYC_CUP, oy + s->cy, 0);
} else {
for (j = 0; j < s->cy; j++) {
for (j = 0; j < oy + s->cy; j++) {
for (i = 0; i < screen_size_x(s); i++)
tty_putc(tty, ' ');
}
}
for (i = 0; i < s->cx; i++)
tty_putc(tty, ' ');
tty_putcode2(tty, TTYC_CUP, s->cy, s->cx);
tty_putcode2(tty, TTYC_CUP, oy + s->cy, s->cx);
}
void
tty_cmd_clearscreen(struct tty *tty, struct screen *s, unused va_list ap)
tty_cmd_clearscreen(
struct tty *tty, struct screen *s, u_int oy, unused va_list ap)
{
u_int i, j;
tty_reset(tty);
tty_cursor(tty, s->cx, s->cy, oy);
tty_putcode2(tty, TTYC_CUP, 0, 0);
tty_putcode2(tty, TTYC_CUP, oy, 0);
if (tty_term_has(tty->term, TTYC_EL)) {
for (i = 0; i < screen_size_y(s); i++) {
tty_putcode(tty, TTYC_EL);
@ -695,16 +644,18 @@ tty_cmd_clearscreen(struct tty *tty, struct screen *s, unused va_list ap)
tty_putc(tty, ' ');
}
}
tty_putcode2(tty, TTYC_CUP, s->cy, s->cx);
tty_putcode2(tty, TTYC_CUP, oy + s->cy, s->cx);
}
void
tty_cmd_cell(struct tty *tty, unused struct screen *s, va_list ap)
tty_cmd_cell(struct tty *tty, struct screen *s, u_int oy, va_list ap)
{
struct grid_cell *gc;
u_int i, width;
u_char out[4];
tty_cursor(tty, s->cx, s->cy, oy);
gc = va_arg(ap, struct grid_cell *);
/* If this is a padding character, do nothing. */
@ -756,6 +707,28 @@ tty_reset(struct tty *tty)
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
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>
@ -23,13 +23,13 @@
#include "tmux.h"
struct screen *window_clock_init(struct window *);
void window_clock_free(struct window *);
void window_clock_resize(struct window *, u_int, u_int);
void window_clock_key(struct window *, struct client *, int);
void window_clock_timer(struct window *);
struct screen *window_clock_init(struct window_pane *);
void window_clock_free(struct window_pane *);
void window_clock_resize(struct window_pane *, u_int, u_int);
void window_clock_key(struct window_pane *, struct client *, int);
void window_clock_timer(struct window_pane *);
void window_clock_draw_screen(struct window *);
void window_clock_draw_screen(struct window_pane *);
const struct window_mode window_clock_mode = {
window_clock_init,
@ -45,52 +45,53 @@ struct window_clock_mode_data {
};
struct screen *
window_clock_init(struct window *w)
window_clock_init(struct window_pane *wp)
{
struct window_clock_mode_data *data;
struct screen *s;
w->modedata = data = xmalloc(sizeof *data);
wp->modedata = data = xmalloc(sizeof *data);
data->tim = time(NULL);
s = &data->screen;
screen_init(s, screen_size_x(&w->base), screen_size_y(&w->base), 0);
screen_init(s, screen_size_x(&wp->base), screen_size_y(&wp->base), 0);
s->mode &= ~MODE_CURSOR;
window_clock_draw_screen(w);
window_clock_draw_screen(wp);
return (s);
}
void
window_clock_free(struct window *w)
window_clock_free(struct window_pane *wp)
{
struct window_clock_mode_data *data = w->modedata;
struct window_clock_mode_data *data = wp->modedata;
screen_free(&data->screen);
xfree(data);
}
void
window_clock_resize(struct window *w, u_int sx, u_int sy)
window_clock_resize(struct window_pane *wp, u_int sx, u_int sy)
{
struct window_clock_mode_data *data = w->modedata;
struct window_clock_mode_data *data = wp->modedata;
struct screen *s = &data->screen;
screen_resize(s, sx, sy);
window_clock_draw_screen(w);
window_clock_draw_screen(wp);
}
void
window_clock_key(struct window *w, unused struct client *c, unused int key)
window_clock_key(
struct window_pane *wp, unused struct client *c, unused int key)
{
window_reset_mode(w);
window_pane_reset_mode(wp);
}
void
window_clock_timer(struct window *w)
window_clock_timer(struct window_pane *wp)
{
struct window_clock_mode_data *data = w->modedata;
struct window_clock_mode_data *data = wp->modedata;
struct tm *now, *then;
time_t t;
@ -101,22 +102,22 @@ window_clock_timer(struct window *w)
return;
data->tim = t;
window_clock_draw_screen(w);
server_redraw_window(w);
window_clock_draw_screen(wp);
server_redraw_window(wp->window);
}
void
window_clock_draw_screen(struct window *w)
window_clock_draw_screen(struct window_pane *wp)
{
struct window_clock_mode_data *data = w->modedata;
struct window_clock_mode_data *data = wp->modedata;
struct screen_write_ctx ctx;
u_int colour;
int style;
colour = options_get_number(&w->options, "clock-mode-colour");
style = options_get_number(&w->options, "clock-mode-style");
colour = options_get_number(&wp->window->options, "clock-mode-colour");
style = options_get_number(&wp->window->options, "clock-mode-style");
screen_write_start(&ctx, &data->screen, NULL, NULL);
screen_write_start(&ctx, NULL, &data->screen);
clock_draw(&ctx, colour, style);
screen_write_stop(&ctx);
}

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

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

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

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>
@ -46,16 +46,17 @@
#include "tmux.h"
/*
* Each window is attached to a pty. This file contains code to handle them.
* Each window is attached to one or two panes, each of which is a pty. This
* file contains code to handle them.
*
* A window has two buffers attached, these are filled and emptied by the main
* A pane has two buffers attached, these are filled and emptied by the main
* server poll loop. Output data is received from pty's in screen format,
* translated and returned as a series of escape sequences and strings via
* input_parse (in input.c). Input data is received as key codes and written
* directly via input_key.
*
* Each window also has a "virtual" screen (screen.c) which contains the
* current state and is redisplayed when the window is reattached to a client.
* Each pane also has a "virtual" screen (screen.c) which contains the current
* state and is redisplayed when the window is reattached to a client.
*
* Windows are stored directly on a global array and wrapped in any number of
* winlink structs to be linked onto local session RB trees. A reference count
@ -211,20 +212,15 @@ window_create(const char *name, const char *cmd,
char *ptr, *copy;
w = xmalloc(sizeof *w);
w->cmd = NULL;
w->cwd = NULL;
w->fd = -1;
w->in = buffer_create(BUFSIZ);
w->out = buffer_create(BUFSIZ);
w->mode = NULL;
w->flags = 0;
w->panes[0] = window_pane_create(w, sx, sy, hlimit);
w->panes[1] = NULL;
screen_init(&w->base, sx, sy, hlimit);
w->screen = &w->base;
w->sx = sx;
w->sy = sy;
w->active = w->panes[0];
input_init(w);
options_init(&w->options, &global_window_options);
if (name == NULL) {
@ -253,60 +249,13 @@ window_create(const char *name, const char *cmd,
ARRAY_ADD(&windows, w);
w->references = 0;
if (window_spawn(w, cmd, cwd, envp) != 0) {
if (window_pane_spawn(w->active, cmd, cwd, envp) != 0) {
window_destroy(w);
return (NULL);
}
return (w);
}
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
window_destroy(struct window *w)
{
@ -318,87 +267,207 @@ window_destroy(struct window *w)
}
ARRAY_REMOVE(&windows, i);
if (w->fd != -1)
close(w->fd);
input_free(w);
window_reset_mode(w);
options_free(&w->options);
screen_free(&w->base);
buffer_destroy(w->in);
buffer_destroy(w->out);
if (w->cwd != NULL)
xfree(w->cwd);
if (w->cmd != NULL)
xfree(w->cmd);
window_pane_destroy(w->panes[0]);
if (w->panes[1] != NULL)
window_pane_destroy(w->panes[1]);
xfree(w->name);
xfree(w);
}
int
window_resize(struct window *w, u_int sx, u_int sy)
{
if (w->panes[1] != NULL) {
window_pane_resize(w->panes[0], sx, sy / 2 - 1);
window_pane_resize(w->panes[1], sx, sy - (sy / 2));
} else
window_pane_resize(w->panes[0], sx, sy);
w->sx = sx;
w->sy = sy;
return (0);
}
int
window_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;
if (sx == screen_size_x(&w->base) && sy == screen_size_y(&w->base))
if (sx == screen_size_x(&wp->base) && sy == screen_size_y(&wp->base))
return (-1);
memset(&ws, 0, sizeof ws);
ws.ws_col = sx;
ws.ws_row = sy;
screen_resize(&w->base, sx, sy);
if (w->mode != NULL)
w->mode->resize(w, sx, sy);
screen_resize(&wp->base, sx, sy);
if (wp->mode != NULL)
wp->mode->resize(wp, sx, sy);
if (w->fd != -1 && ioctl(w->fd, TIOCSWINSZ, &ws) == -1)
if (wp->fd != -1 && ioctl(wp->fd, TIOCSWINSZ, &ws) == -1)
fatal("ioctl failed");
return (0);
}
int
window_set_mode(struct window *w, const struct window_mode *mode)
window_pane_set_mode(struct window_pane *wp, const struct window_mode *mode)
{
struct screen *s;
if (w->mode != NULL || w->mode == mode)
if (wp->mode != NULL || wp->mode == mode)
return (1);
w->mode = mode;
wp->mode = mode;
if ((s = w->mode->init(w)) != NULL)
w->screen = s;
server_redraw_window(w);
if ((s = wp->mode->init(wp)) != NULL)
wp->screen = s;
server_redraw_window(wp->window);
return (0);
}
void
window_reset_mode(struct window *w)
window_pane_reset_mode(struct window_pane *wp)
{
if (w->mode == NULL)
if (wp->mode == NULL)
return;
w->mode->free(w);
w->mode = NULL;
wp->mode->free(wp);
wp->mode = NULL;
w->screen = &w->base;
server_redraw_window(w);
wp->screen = &wp->base;
server_redraw_window(wp->window);
}
void
window_parse(struct window *w)
window_pane_parse(struct window_pane *wp)
{
input_parse(w);
input_parse(wp);
}
void
window_key(struct window *w, struct client *c, int key)
window_pane_key(struct window_pane *wp, struct client *c, int key)
{
if (w->mode != NULL)
w->mode->key(w, c, key);
if (wp->mode != NULL)
wp->mode->key(wp, c, key);
else
input_key(w, key);
input_key(wp, key);
}