Reorg window data structures. Add an intermediate data type (struct winlink) to hold index and make sessions hold a RB tree of them rather than a fixed array.

This commit is contained in:
Nicholas Marriott 2007-10-26 12:29:07 +00:00
parent 9f06104c3a
commit 4ba3cf60be
18 changed files with 347 additions and 349 deletions

View File

@ -1,3 +1,10 @@
26 October 2007
* (nicm) Redo window data structures. The global array remains, but each per-
session list is now a RB tree of winlink structures. This disassociates the
window index from the array size (allowing arbitrary indexes) which still
allowing windows to have multiple indexes.
25 October 2007 25 October 2007
* (nicm) has-session command: checks if session exists. * (nicm) has-session command: checks if session exists.
@ -163,5 +170,5 @@
(including mutt, emacs). No status bar yet and no key remapping or other (including mutt, emacs). No status bar yet and no key remapping or other
customisation. customisation.
$Id: CHANGES,v 1.51 2007-10-25 17:44:24 nicm Exp $ $Id: CHANGES,v 1.52 2007-10-26 12:29:07 nicm Exp $

3
TODO
View File

@ -1,4 +1,3 @@
- decide if TIOCPKT is necessary and either handle it or remove the code
- it would be nice if there wasn't so much copying buffers about, audit uses - it would be nice if there wasn't so much copying buffers about, audit uses
- useful env vars like WINDOW - useful env vars like WINDOW
- sort out who controls the buffers in local.c a bit - sort out who controls the buffers in local.c a bit
@ -20,8 +19,6 @@
- profile/optimise, particularly (i suspect) input.c - profile/optimise, particularly (i suspect) input.c
- tidy up input.c a bit - tidy up input.c a bit
- decide about customised status line - decide about customised status line
- rethink data structures. window->index is O(n), could have a w->idx member
or use queues/trees and avoid NULLs?
- client could pass term/tty fd up to server and then do nothing. what problems - client could pass term/tty fd up to server and then do nothing. what problems
would this cause? -- need access to all terminfo data at once... signals? would this cause? -- need access to all terminfo data at once... signals?
- cleanup/redesign IPC - cleanup/redesign IPC

View File

@ -1,4 +1,4 @@
/* $Id: cmd-kill-window.c,v 1.1 2007-10-19 11:10:35 nicm Exp $ */ /* $Id: cmd-kill-window.c,v 1.2 2007-10-26 12:29:07 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -92,7 +92,7 @@ cmd_kill_window_exec(void *ptr, struct cmd_ctx *ctx)
struct cmd_kill_window_data *data = ptr, std = { -1 }; struct cmd_kill_window_data *data = ptr, std = { -1 };
struct client *c = ctx->client; struct client *c = ctx->client;
struct session *s = ctx->session; struct session *s = ctx->session;
struct window *w; struct winlink *wl;
u_int i; u_int i;
int destroyed; int destroyed;
@ -100,13 +100,13 @@ cmd_kill_window_exec(void *ptr, struct cmd_ctx *ctx)
data = &std; data = &std;
if (data->idx == -1) if (data->idx == -1)
w = s->window; wl = s->curw;
else if ((w = window_at(&s->windows, data->idx)) == NULL) { else if ((wl = winlink_find_by_index(&s->windows, data->idx)) == NULL) {
ctx->error(ctx, "no window %u", data->idx); ctx->error(ctx, "no window %u", data->idx);
return; return;
} }
destroyed = session_detach(s, w); destroyed = session_detach(s, wl);
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i); c = ARRAY_ITEM(&clients, i);
if (c == NULL || c->session != s) if (c == NULL || c->session != s)

View File

@ -1,4 +1,4 @@
/* $Id: cmd-list-sessions.c,v 1.6 2007-10-23 09:36:07 nicm Exp $ */ /* $Id: cmd-list-sessions.c,v 1.7 2007-10-26 12:29:07 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -45,8 +45,9 @@ cmd_list_sessions_exec(unused void *ptr, struct cmd_ctx *ctx)
{ {
struct client *c = ctx->client; struct client *c = ctx->client;
struct session *s = ctx->session; struct session *s = ctx->session;
struct winlink *wl;
char *tim; char *tim;
u_int i, j, n; u_int i, n;
for (i = 0; i < ARRAY_LENGTH(&sessions); i++) { for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
s = ARRAY_ITEM(&sessions, i); s = ARRAY_ITEM(&sessions, i);
@ -54,10 +55,8 @@ cmd_list_sessions_exec(unused void *ptr, struct cmd_ctx *ctx)
continue; continue;
n = 0; n = 0;
for (j = 0; j < ARRAY_LENGTH(&s->windows); j++) { RB_FOREACH(wl, winlinks, &s->windows)
if (ARRAY_ITEM(&s->windows, j) != NULL) n++;
n++;
}
tim = ctime(&s->tim); tim = ctime(&s->tim);
*strchr(tim, '\n') = '\0'; *strchr(tim, '\n') = '\0';

View File

@ -1,4 +1,4 @@
/* $Id: cmd-list-windows.c,v 1.3 2007-10-23 09:36:07 nicm Exp $ */ /* $Id: cmd-list-windows.c,v 1.4 2007-10-26 12:29:07 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -44,17 +44,14 @@ cmd_list_windows_exec(unused void *ptr, struct cmd_ctx *ctx)
{ {
struct client *c = ctx->client; struct client *c = ctx->client;
struct session *s = ctx->session; struct session *s = ctx->session;
struct winlink *wl;
struct window *w; struct window *w;
u_int i;
for (i = 0; i < ARRAY_LENGTH(&s->windows); i++) { RB_FOREACH(wl, winlinks, &s->windows) {
w = ARRAY_ITEM(&s->windows, i); w = wl->window;
if (w == NULL) ctx->print(ctx, "%u: %s \"%s\" (%s) [%ux%u]", wl->idx,
continue; w->name, w->screen.title, ttyname(w->fd),
w->screen.sx, w->screen.sy);
ctx->print(ctx,
"%u: %s \"%s\" (%s) [%ux%u]", i, w->name, w->screen.title,
ttyname(w->fd), w->screen.sx, w->screen.sy);
} }
if (!(ctx->flags & CMD_KEY)) if (!(ctx->flags & CMD_KEY))

View File

@ -1,4 +1,4 @@
/* $Id: cmd-new-session.c,v 1.13 2007-10-19 17:15:29 nicm Exp $ */ /* $Id: cmd-new-session.c,v 1.14 2007-10-26 12:29:07 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -133,8 +133,8 @@ cmd_new_session_exec(void *ptr, struct cmd_ctx *ctx)
if (c->session == NULL) if (c->session == NULL)
fatalx("session_create failed"); fatalx("session_create failed");
if (data->winname != NULL) { if (data->winname != NULL) {
xfree(c->session->window->name); xfree(c->session->curw->window->name);
c->session->window->name = xstrdup(data->winname); c->session->curw->window->name = xstrdup(data->winname);
} }
if (data->flag_detached) if (data->flag_detached)

View File

@ -1,4 +1,4 @@
/* $Id: cmd-new-window.c,v 1.9 2007-10-19 09:21:25 nicm Exp $ */ /* $Id: cmd-new-window.c,v 1.10 2007-10-26 12:29:07 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -19,6 +19,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <getopt.h> #include <getopt.h>
#include <stdlib.h>
#include "tmux.h" #include "tmux.h"
@ -35,11 +36,12 @@ void cmd_new_window_free(void *);
struct cmd_new_window_data { struct cmd_new_window_data {
char *name; char *name;
char *cmd; char *cmd;
int idx;
int flag_detached; int flag_detached;
}; };
const struct cmd_entry cmd_new_window_entry = { const struct cmd_entry cmd_new_window_entry = {
"new-window", "neww", "[-d] [-n name] [command]", "new-window", "neww", "[-d] [-i index] [-n name] [command]",
0, 0,
cmd_new_window_parse, cmd_new_window_parse,
cmd_new_window_exec, cmd_new_window_exec,
@ -52,15 +54,24 @@ int
cmd_new_window_parse(void **ptr, int argc, char **argv, char **cause) cmd_new_window_parse(void **ptr, int argc, char **argv, char **cause)
{ {
struct cmd_new_window_data *data; struct cmd_new_window_data *data;
const char *errstr;
int opt; int opt;
*ptr = data = xmalloc(sizeof *data); *ptr = data = xmalloc(sizeof *data);
data->idx = -1;
data->flag_detached = 0; data->flag_detached = 0;
data->name = NULL; data->name = NULL;
data->cmd = NULL; data->cmd = NULL;
while ((opt = getopt(argc, argv, "dn:")) != EOF) { while ((opt = getopt(argc, argv, "di:n:")) != EOF) {
switch (opt) { switch (opt) {
case 'i':
data->idx = strtonum(optarg, 0, UINT_MAX, &errstr);
if (errstr != NULL) {
xasprintf(cause, "index %s", errstr);
goto error;
}
break;
case 'n': case 'n':
data->name = xstrdup(optarg); data->name = xstrdup(optarg);
break; break;
@ -85,6 +96,7 @@ usage:
usage(cause, "%s %s", usage(cause, "%s %s",
cmd_new_window_entry.name, cmd_new_window_entry.usage); cmd_new_window_entry.name, cmd_new_window_entry.usage);
error:
cmd_new_window_free(data); cmd_new_window_free(data);
return (-1); return (-1);
} }
@ -92,11 +104,12 @@ usage:
void void
cmd_new_window_exec(void *ptr, struct cmd_ctx *ctx) cmd_new_window_exec(void *ptr, struct cmd_ctx *ctx)
{ {
struct cmd_new_window_data *data = ptr, std = { NULL, NULL, 0 }; struct cmd_new_window_data *data = ptr;
struct cmd_new_window_data std = { NULL, NULL, -1, 0 };
struct client *c = ctx->client; struct client *c = ctx->client;
struct session *s = ctx->session; struct session *s = ctx->session;
struct winlink *wl;
char *cmd; char *cmd;
u_int i;
if (data == NULL) if (data == NULL)
data = &std; data = &std;
@ -105,12 +118,14 @@ cmd_new_window_exec(void *ptr, struct cmd_ctx *ctx)
if (cmd == NULL) if (cmd == NULL)
cmd = default_command; cmd = default_command;
if (session_new(s, data->name, cmd, &i) != 0) { if (data->idx < 0)
data->idx = -1;
if ((wl = session_new(s, data->name, cmd, data->idx)) == NULL) {
ctx->error(ctx, "command failed: %s", cmd); ctx->error(ctx, "command failed: %s", cmd);
return; return;
} }
if (!data->flag_detached) { if (!data->flag_detached) {
session_select(s, i); session_select(s, wl->idx);
server_redraw_session(s); server_redraw_session(s);
} else } else
server_status_session(s); server_status_session(s);

View File

@ -1,4 +1,4 @@
/* $Id: cmd-rename-window.c,v 1.7 2007-10-19 17:15:29 nicm Exp $ */ /* $Id: cmd-rename-window.c,v 1.8 2007-10-26 12:29:07 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -96,19 +96,19 @@ cmd_rename_window_exec(void *ptr, struct cmd_ctx *ctx)
struct cmd_rename_window_data *data = ptr; struct cmd_rename_window_data *data = ptr;
struct client *c = ctx->client; struct client *c = ctx->client;
struct session *s = ctx->session; struct session *s = ctx->session;
struct window *w; struct winlink *wl;
if (data == NULL) if (data == NULL)
return; return;
if (data->idx == -1) if (data->idx == -1)
w = s->window; wl = s->curw;
else if ((w = window_at(&s->windows, data->idx)) == NULL) { else if ((wl = winlink_find_by_index(&s->windows, data->idx)) == NULL) {
ctx->error(ctx, "no window %u", data->idx); ctx->error(ctx, "no window %u", data->idx);
return; return;
} }
xfree(w->name); xfree(wl->window->name);
w->name = xstrdup(data->newname); wl->window->name = xstrdup(data->newname);
server_status_session(s); server_status_session(s);

View File

@ -1,4 +1,4 @@
/* $Id: cmd-select-window.c,v 1.4 2007-10-19 09:21:26 nicm Exp $ */ /* $Id: cmd-select-window.c,v 1.5 2007-10-26 12:29:07 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -108,10 +108,16 @@ cmd_select_window_exec(void *ptr, struct cmd_ctx *ctx)
if (data == NULL) if (data == NULL)
return; return;
if (session_select(s, data->idx) == 0) switch (session_select(s, data->idx)) {
case 0:
server_redraw_session(s); server_redraw_session(s);
else break;
case 1:
break;
default:
ctx->error(ctx, "no window %u", data->idx); ctx->error(ctx, "no window %u", data->idx);
break;
}
if (!(ctx->flags & CMD_KEY)) if (!(ctx->flags & CMD_KEY))
server_write_client(c, MSG_EXIT, NULL, 0); server_write_client(c, MSG_EXIT, NULL, 0);

View File

@ -1,4 +1,4 @@
/* $Id: cmd-send-prefix.c,v 1.2 2007-10-19 23:33:20 nicm Exp $ */ /* $Id: cmd-send-prefix.c,v 1.3 2007-10-26 12:29:07 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -49,5 +49,5 @@ cmd_send_prefix_exec(unused void *ptr, struct cmd_ctx *ctx)
return; return;
} }
window_key(c->session->window, prefix_key); input_translate_key(c->session->curw->window->out, prefix_key);
} }

View File

@ -1,4 +1,4 @@
/* $Id: key-bindings.c,v 1.11 2007-10-23 10:25:57 nicm Exp $ */ /* $Id: key-bindings.c,v 1.12 2007-10-26 12:29:07 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -177,7 +177,7 @@ key_bindings_print(struct cmd_ctx *ctx, const char *fmt, ...)
if (!(c->flags & CLIENT_HOLD)) { if (!(c->flags & CLIENT_HOLD)) {
input_store_zero(c->out, CODE_CURSOROFF); input_store_zero(c->out, CODE_CURSOROFF);
for (i = 0; i < c->session->window->screen.sy; i++) { for (i = 0; i < c->session->curw->window->screen.sy; i++) {
input_store_two(c->out, CODE_CURSORMOVE, i + 1, 1); input_store_two(c->out, CODE_CURSORMOVE, i + 1, 1);
input_store_zero(c->out, CODE_CLEARLINE); input_store_zero(c->out, CODE_CLEARLINE);
} }

View File

@ -1,4 +1,4 @@
/* $Id: server-fn.c,v 1.22 2007-10-23 10:48:23 nicm Exp $ */ /* $Id: server-fn.c,v 1.23 2007-10-26 12:29:07 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -114,7 +114,7 @@ server_write_window_cur(
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i); c = ARRAY_ITEM(&clients, i);
if (c != NULL && if (c != NULL &&
c->session != NULL && c->session->window == w) { c->session != NULL && c->session->curw->window == w) {
if (c->flags & CLIENT_HOLD) /* XXX OUTPUT only */ if (c->flags & CLIENT_HOLD) /* XXX OUTPUT only */
continue; continue;
server_write_client(c, type, buf, len); server_write_client(c, type, buf, len);
@ -165,7 +165,7 @@ server_status_client(struct client *c)
void void
server_clear_client(struct client *c) server_clear_client(struct client *c)
{ {
struct screen *s = &c->session->window->screen; struct screen *s = &c->session->curw->window->screen;
struct hdr hdr; struct hdr hdr;
size_t size; size_t size;
u_int i; u_int i;
@ -192,7 +192,7 @@ server_clear_client(struct client *c)
void void
server_redraw_client(struct client *c) server_redraw_client(struct client *c)
{ {
struct screen *s = &c->session->window->screen; struct screen *s = &c->session->curw->window->screen;
struct hdr hdr; struct hdr hdr;
size_t size; size_t size;
@ -248,7 +248,8 @@ server_clear_window_cur(struct window *w)
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i); c = ARRAY_ITEM(&clients, i);
if (c != NULL && c->session != NULL && c->session->window == w) if (c != NULL &&
c->session != NULL && c->session->curw->window == w)
server_clear_client(c); server_clear_client(c);
} }
} }
@ -276,7 +277,8 @@ server_redraw_window_cur(struct window *w)
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i); c = ARRAY_ITEM(&clients, i);
if (c != NULL && c->session != NULL && c->session->window == w) if (c != NULL &&
c->session != NULL && c->session->curw->window == w)
server_redraw_client(c); server_redraw_client(c);
} }
} }
@ -304,7 +306,8 @@ server_status_window_cur(struct window *w)
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i); c = ARRAY_ITEM(&clients, i);
if (c != NULL && c->session != NULL && c->session->window == w) if (c != NULL &&
c->session != NULL && c->session->curw->window == w)
server_status_client(c); server_status_client(c);
} }
} }
@ -327,6 +330,7 @@ server_status_window_all(struct window *w)
void void
server_write_message(struct client *c, const char *fmt, ...) server_write_message(struct client *c, const char *fmt, ...)
{ {
struct screen *s = &c->session->curw->window->screen;
struct hdr hdr; struct hdr hdr;
va_list ap; va_list ap;
char *msg; char *msg;
@ -364,8 +368,7 @@ server_write_message(struct client *c, const char *fmt, ...)
size = BUFFER_USED(c->out); size = BUFFER_USED(c->out);
if (status_lines == 0) { if (status_lines == 0) {
screen_draw( screen_draw(s, c->out, c->sy - 1, c->sy - 1);
&c->session->window->screen, c->out, c->sy - 1, c->sy - 1);
} else } else
status_write(c); status_write(c);

View File

@ -1,4 +1,4 @@
/* $Id: server-msg.c,v 1.29 2007-10-23 10:48:23 nicm Exp $ */ /* $Id: server-msg.c,v 1.30 2007-10-26 12:29:07 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -223,7 +223,7 @@ server_msg_fn_keys(struct hdr *hdr, struct client *c)
if (key == prefix_key) if (key == prefix_key)
c->flags |= CLIENT_PREFIX; c->flags |= CLIENT_PREFIX;
else else
window_key(c->session->window, key); input_translate_key(c->session->curw->window->out, key);
} }
return (0); return (0);

View File

@ -1,4 +1,4 @@
/* $Id: server.c,v 1.34 2007-10-24 11:30:02 nicm Exp $ */ /* $Id: server.c,v 1.35 2007-10-26 12:29:07 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -228,7 +228,7 @@ server_handle_windows(struct pollfd **pfd)
for (i = 0; i < ARRAY_LENGTH(&windows); i++) { for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
if ((w = ARRAY_ITEM(&windows, i)) != NULL) { if ((w = ARRAY_ITEM(&windows, i)) != NULL) {
if (window_poll(w, *pfd) != 0) if (buffer_poll(*pfd, w->in, w->out) != 0)
server_lost_window(w); server_lost_window(w);
else else
server_handle_window(w); server_handle_window(w);
@ -259,14 +259,14 @@ server_fill_clients(struct pollfd **pfd)
/* Handle client pollfds. */ /* Handle client pollfds. */
void void
server_handle_clients(struct pollfd *(*pfd)) server_handle_clients(struct pollfd **pfd)
{ {
struct client *c; struct client *c;
u_int i; u_int i;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) { for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
if ((c = ARRAY_ITEM(&clients, i)) != NULL) { if ((c = ARRAY_ITEM(&clients, i)) != NULL) {
if (buffer_poll((*pfd), c->in, c->out) != 0) if (buffer_poll(*pfd, c->in, c->out) != 0)
server_lost_client(c); server_lost_client(c);
else else
server_msg_dispatch(c); server_msg_dispatch(c);
@ -345,7 +345,7 @@ server_handle_window(struct window *w)
u_int i; u_int i;
b = buffer_create(BUFSIZ); b = buffer_create(BUFSIZ);
window_data(w, b); input_parse(w, b);
if (BUFFER_USED(b) != 0) { if (BUFFER_USED(b) != 0) {
server_write_window_cur( server_write_window_cur(
w, MSG_DATA, BUFFER_OUT(b), BUFFER_USED(b)); w, MSG_DATA, BUFFER_OUT(b), BUFFER_USED(b));
@ -368,7 +368,7 @@ server_handle_window(struct window *w)
case BELL_CURRENT: case BELL_CURRENT:
for (i = 0; i < ARRAY_LENGTH(&sessions); i++) { for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
s = ARRAY_ITEM(&sessions, i); s = ARRAY_ITEM(&sessions, i);
if (s != NULL && s->window == w) if (s != NULL && s->curw->window == w)
server_write_session(s, MSG_DATA, "\007", 1); server_write_session(s, MSG_DATA, "\007", 1);
} }
break; break;
@ -384,6 +384,7 @@ server_lost_window(struct window *w)
{ {
struct client *c; struct client *c;
struct session *s; struct session *s;
struct winlink *wl;
u_int i, j; u_int i, j;
int destroyed; int destroyed;
@ -397,16 +398,23 @@ server_lost_window(struct window *w)
continue; continue;
/* Detach window and either redraw or kill clients. */ /* Detach window and either redraw or kill clients. */
destroyed = session_detach(s, w); restart:
for (j = 0; j < ARRAY_LENGTH(&clients); j++) { RB_FOREACH(wl, winlinks, &s->windows) {
c = ARRAY_ITEM(&clients, j); if (wl->window != w)
if (c == NULL || c->session != s)
continue; continue;
if (destroyed) { destroyed = session_detach(s, wl);
for (j = 0; j < ARRAY_LENGTH(&clients); j++) {
c = ARRAY_ITEM(&clients, j);
if (c == NULL || c->session != s)
continue;
if (!destroyed) {
server_redraw_client(c);
continue;
}
c->session = NULL; c->session = NULL;
server_write_client(c, MSG_EXIT, NULL, 0); server_write_client(c, MSG_EXIT, NULL, 0);
} else }
server_redraw_client(c); goto restart;
} }
} }

173
session.c
View File

@ -1,4 +1,4 @@
/* $Id: session.c,v 1.24 2007-10-24 11:05:59 nicm Exp $ */ /* $Id: session.c,v 1.25 2007-10-26 12:29:07 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -29,33 +29,41 @@
struct sessions sessions; struct sessions sessions;
void void
session_cancelbell(struct session *s, struct window *w) session_cancelbell(struct session *s, struct winlink *wl)
{ {
u_int i; u_int i;
if (window_index(&s->bells, w, &i) == 0) for (i = 0; i < ARRAY_LENGTH(&s->bells); i++) {
window_remove(&s->bells, w); if (ARRAY_ITEM(&s->bells, i) == wl) {
ARRAY_REMOVE(&s->bells, i);
break;
}
}
} }
void void
session_addbell(struct session *s, struct window *w) session_addbell(struct session *s, struct window *w)
{ {
u_int i; struct winlink *wl;
/* Never bell in the current window. */ RB_FOREACH(wl, winlinks, &s->windows) {
if (w == s->window || !session_has(s, w)) if (wl == s->curw)
return; continue;
if (wl->window == w && !session_hasbell(s, wl))
if (window_index(&s->bells, w, &i) != 0) ARRAY_ADD(&s->bells, wl);
window_add(&s->bells, w); }
} }
int int
session_hasbell(struct session *s, struct window *w) session_hasbell(struct session *s, struct winlink *wl)
{ {
u_int i; u_int i;
return (window_index(&s->bells, w, &i) == 0); for (i = 0; i < ARRAY_LENGTH(&s->bells); i++) {
if (ARRAY_ITEM(&s->bells, i) == wl)
return (1);
}
return (0);
} }
/* Find session by name. */ /* Find session by name. */
@ -83,8 +91,8 @@ session_create(const char *name, const char *cmd, u_int sx, u_int sy)
s = xmalloc(sizeof *s); s = xmalloc(sizeof *s);
s->tim = time(NULL); s->tim = time(NULL);
s->window = s->last = NULL; s->curw = s->lastw = NULL;
ARRAY_INIT(&s->windows); RB_INIT(&s->windows);
ARRAY_INIT(&s->bells); ARRAY_INIT(&s->bells);
s->sx = sx; s->sx = sx;
@ -103,7 +111,7 @@ session_create(const char *name, const char *cmd, u_int sx, u_int sy)
s->name = xstrdup(name); s->name = xstrdup(name);
else else
xasprintf(&s->name, "%u", i); xasprintf(&s->name, "%u", i);
if (session_new(s, NULL, cmd, &i) != 0) { if (session_new(s, NULL, cmd, -1) == NULL) {
session_destroy(s); session_destroy(s);
return (NULL); return (NULL);
} }
@ -116,7 +124,8 @@ session_create(const char *name, const char *cmd, u_int sx, u_int sy)
void void
session_destroy(struct session *s) session_destroy(struct session *s)
{ {
u_int i; struct winlink *wl;
u_int i;
if (session_index(s, &i) != 0) if (session_index(s, &i) != 0)
fatalx("session not found"); fatalx("session not found");
@ -124,11 +133,11 @@ session_destroy(struct session *s)
while (!ARRAY_EMPTY(&sessions) && ARRAY_LAST(&sessions) == NULL) while (!ARRAY_EMPTY(&sessions) && ARRAY_LAST(&sessions) == NULL)
ARRAY_TRUNC(&sessions, 1); ARRAY_TRUNC(&sessions, 1);
for (i = 0; i < ARRAY_LENGTH(&s->windows); i++) { while (!RB_EMPTY(&s->windows)) {
if (ARRAY_ITEM(&s->windows, i) != NULL) wl = RB_ROOT(&s->windows);
window_remove(&s->windows, ARRAY_ITEM(&s->windows, i)); RB_REMOVE(winlinks, &s->windows, wl);
winlink_remove(&s->windows, wl);
} }
ARRAY_FREE(&s->windows);
xfree(s->name); xfree(s->name);
xfree(s); xfree(s);
@ -146,44 +155,43 @@ session_index(struct session *s, u_int *i)
} }
/* Create a new window on a session. */ /* Create a new window on a session. */
int struct winlink *
session_new(struct session *s, const char *name, const char *cmd, u_int *i) session_new(struct session *s, const char *name, const char *cmd, int idx)
{ {
struct window *w; struct window *w;
const char *environ[] = { NULL, "TERM=screen", NULL }; const char *environ[] = { NULL, "TERM=screen", NULL };
char buf[256]; char buf[256];
u_int i;
if (session_index(s, i) != 0) if (session_index(s, &i) != 0)
fatalx("session not found"); fatalx("session not found");
xsnprintf(buf, sizeof buf, "TMUX=%ld,%u", (long) getpid(), *i); xsnprintf(buf, sizeof buf, "TMUX=%ld,%u", (long) getpid(), i);
environ[0] = buf; environ[0] = buf;
if ((w = window_create(name, cmd, environ, s->sx, s->sy)) == NULL) if ((w = window_create(name, cmd, environ, s->sx, s->sy)) == NULL)
return (-1); return (NULL);
session_attach(s, w); return (session_attach(s, w, idx));
window_index(&s->windows, w, i);
return (0);
} }
/* Attach a window to a session. */ /* Attach a window to a session. */
void struct winlink *
session_attach(struct session *s, struct window *w) session_attach(struct session *s, struct window *w, int idx)
{ {
window_add(&s->windows, w); return (winlink_add(&s->windows, w, idx));
} }
/* Detach a window from a session. */ /* Detach a window from a session. */
int int
session_detach(struct session *s, struct window *w) session_detach(struct session *s, struct winlink *wl)
{ {
if (s->window == w && session_last(s) != 0 && session_previous(s) != 0) if (s->curw == wl && session_last(s) != 0 && session_previous(s) != 0)
session_next(s); session_next(s);
if (s->last == w) if (s->lastw == wl)
s->last = NULL; s->lastw = NULL;
window_remove(&s->windows, w); session_cancelbell(s, wl);
if (ARRAY_EMPTY(&s->windows)) { winlink_remove(&s->windows, wl);
if (RB_EMPTY(&s->windows)) {
session_destroy(s); session_destroy(s);
return (1); return (1);
} }
@ -194,34 +202,32 @@ session_detach(struct session *s, struct window *w)
int int
session_has(struct session *s, struct window *w) session_has(struct session *s, struct window *w)
{ {
u_int i; struct winlink *wl;
return (window_index(&s->windows, w, &i) == 0); RB_FOREACH(wl, winlinks, &s->windows) {
if (wl->window == w)
return (1);
}
return (0);
} }
/* Move session to next window. */ /* Move session to next window. */
int int
session_next(struct session *s) session_next(struct session *s)
{ {
struct window *w; struct winlink *wl;
u_int n;
if (s->window == NULL) if (s->curw == NULL)
return (-1); return (-1);
w = window_next(&s->windows, s->window); wl = winlink_next(&s->windows, s->curw);
if (w == NULL) { if (wl == NULL)
n = 0; wl = RB_MIN(winlinks, &s->windows);
while ((w = ARRAY_ITEM(&s->windows, n)) == NULL) if (wl == s->curw)
n++; return (1);
if (w == s->window) s->lastw = s->curw;
return (1); s->curw = wl;
} session_cancelbell(s, wl);
if (w == s->window)
return (0);
s->last = s->window;
s->window = w;
session_cancelbell(s, w);
return (0); return (0);
} }
@ -229,22 +235,19 @@ session_next(struct session *s)
int int
session_previous(struct session *s) session_previous(struct session *s)
{ {
struct window *w; struct winlink *wl;
if (s->window == NULL) if (s->curw == NULL)
return (-1); return (-1);
w = window_previous(&s->windows, s->window); wl = winlink_previous(&s->windows, s->curw);
if (w == NULL) { if (wl == NULL)
w = ARRAY_LAST(&s->windows); wl = RB_MAX(winlinks, &s->windows);
if (w == s->window) if (wl == s->curw)
return (1); return (1);
} s->lastw = s->curw;
if (w == s->window) s->curw = wl;
return (0); session_cancelbell(s, wl);
s->last = s->window;
s->window = w;
session_cancelbell(s, w);
return (0); return (0);
} }
@ -252,16 +255,16 @@ session_previous(struct session *s)
int int
session_select(struct session *s, u_int i) session_select(struct session *s, u_int i)
{ {
struct window *w; struct winlink *wl;
w = window_at(&s->windows, i); wl = winlink_find_by_index(&s->windows, i);
if (w == NULL) if (wl == NULL)
return (-1); return (-1);
if (w == s->window) if (wl == s->curw)
return (0); return (1);
s->last = s->window; s->lastw = s->curw;
s->window = w; s->curw = wl;
session_cancelbell(s, w); session_cancelbell(s, wl);
return (0); return (0);
} }
@ -269,16 +272,16 @@ session_select(struct session *s, u_int i)
int int
session_last(struct session *s) session_last(struct session *s)
{ {
struct window *w; struct winlink *wl;
w = s->last; wl = s->lastw;
if (w == NULL) if (wl == NULL)
return (-1); return (-1);
if (w == s->window) if (wl == s->curw)
return (1); return (1);
s->last = s->window; s->lastw = s->curw;
s->window = w; s->curw = wl;
session_cancelbell(s, w); session_cancelbell(s, wl);
return (0); return (0);
} }

View File

@ -1,4 +1,4 @@
/* $Id: status.c,v 1.6 2007-10-12 12:37:48 nicm Exp $ */ /* $Id: status.c,v 1.7 2007-10-26 12:29:07 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -27,11 +27,10 @@ void status_print(struct buffer *, size_t *, const char *, ...);
void void
status_write(struct client *c) status_write(struct client *c)
{ {
struct screen *s = &c->session->window->screen; struct screen *s = &c->session->curw->window->screen;
struct buffer *b = c->out; struct buffer *b = c->out;
struct window *w; struct winlink *wl;
size_t size; size_t size;
u_int i;
char flag; char flag;
input_store_zero(b, CODE_CURSOROFF); input_store_zero(b, CODE_CURSOROFF);
@ -39,19 +38,16 @@ status_write(struct client *c)
input_store_two(b, CODE_ATTRIBUTES, 0, status_colour); input_store_two(b, CODE_ATTRIBUTES, 0, status_colour);
size = c->sx; size = c->sx;
for (i = 0; i < ARRAY_LENGTH(&c->session->windows); i++) { RB_FOREACH(wl, winlinks, &c->session->windows) {
w = ARRAY_ITEM(&c->session->windows, i);
if (w == NULL)
continue;
flag = ' '; flag = ' ';
if (w == c->session->last) if (wl == c->session->lastw)
flag = '-'; flag = '-';
if (w == c->session->window) if (wl == c->session->curw)
flag = '*'; flag = '*';
if (session_hasbell(c->session, w)) if (session_hasbell(c->session, wl))
flag = '!'; flag = '!';
status_print(b, &size, "%u:%s%c ", i, w->name, flag); status_print(
b, &size, "%u:%s%c ", wl->idx, wl->window->name, flag);
if (size == 0) if (size == 0)
break; break;

60
tmux.h
View File

@ -1,4 +1,4 @@
/* $Id: tmux.h,v 1.70 2007-10-25 17:44:24 nicm Exp $ */ /* $Id: tmux.h,v 1.71 2007-10-26 12:29:07 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -19,6 +19,9 @@
#ifndef TMUX_H #ifndef TMUX_H
#define TMUX_H #define TMUX_H
/* Shut up gcc warnings about empty if bodies. */
#define RB_AUGMENT(x) do {} while (0)
#include <sys/param.h> #include <sys/param.h>
#include <sys/tree.h> #include <sys/tree.h>
#include <sys/queue.h> #include <sys/queue.h>
@ -385,9 +388,6 @@ struct input_ctx {
ARRAY_DECL(, struct input_arg) args; ARRAY_DECL(, struct input_arg) args;
}; };
/* Input context macros. */
#define INPUT_FLAGS(ictx) ((ictx)->flags)
/* Window structure. */ /* Window structure. */
struct window { struct window {
char *name; char *name;
@ -396,17 +396,26 @@ struct window {
struct buffer *in; struct buffer *in;
struct buffer *out; struct buffer *out;
u_int references;
struct input_ctx ictx; struct input_ctx ictx;
int flags; int flags;
#define WINDOW_BELL 0x1 #define WINDOW_BELL 0x1
struct screen screen; struct screen screen;
u_int references;
}; };
ARRAY_DECL(windows, struct window *); ARRAY_DECL(windows, struct window *);
/* Entry on local window list. */
struct winlink {
int idx;
struct window *window;
RB_ENTRY(winlink) entry;
};
RB_HEAD(winlinks, winlink);
/* Client session. */ /* Client session. */
struct session { struct session {
char *name; char *name;
@ -415,11 +424,11 @@ struct session {
u_int sx; u_int sx;
u_int sy; u_int sy;
struct window *window; struct winlink *curw;
struct window *last; struct winlink *lastw;
struct windows windows; struct winlinks windows;
struct windows bells; /* windows with bells */ ARRAY_DECL(, struct winlink *) bells; /* windows with bells */
#define SESSION_UNATTACHED 0x1 /* not attached to any clients */ #define SESSION_UNATTACHED 0x1 /* not attached to any clients */
int flags; int flags;
@ -665,33 +674,34 @@ void local_output(struct buffer *, size_t);
/* window.c */ /* window.c */
extern struct windows windows; extern struct windows windows;
int window_cmp(struct window *, struct window *);
int winlink_cmp(struct winlink *, struct winlink *);
RB_PROTOTYPE(windows, window, entry, window_cmp);
RB_PROTOTYPE(winlinks, winlink, entry, winlink_cmp);
struct winlink *winlink_find_by_index(struct winlinks *, int);
struct winlink *winlink_find_by_window(struct winlinks *, struct window *);
int winlink_next_index(struct winlinks *);
struct winlink *winlink_add(struct winlinks *, struct window *, int);
void winlink_remove(struct winlinks *, struct winlink *);
struct winlink *winlink_next(struct winlinks *, struct winlink *);
struct winlink *winlink_previous(struct winlinks *, struct winlink *);
struct window *window_create( struct window *window_create(
const char *, const char *, const char **, u_int, u_int); const char *, const char *, const char **, u_int, u_int);
int window_index(struct windows *, struct window *, u_int *);
void window_add(struct windows *, struct window *);
void window_remove(struct windows *, struct window *);
void window_destroy(struct window *); void window_destroy(struct window *);
struct window *window_next(struct windows *, struct window *);
struct window *window_previous(struct windows *, struct window *);
struct window *window_at(struct windows *, u_int);
int window_resize(struct window *, u_int, u_int); int window_resize(struct window *, u_int, u_int);
int window_poll(struct window *, struct pollfd *);
void window_key(struct window *, int);
void window_data(struct window *, struct buffer *);
/* session.c */ /* session.c */
extern struct sessions sessions; extern struct sessions sessions;
void session_cancelbell(struct session *, struct window *); void session_cancelbell(struct session *, struct winlink *);
void session_addbell(struct session *, struct window *); void session_addbell(struct session *, struct window *);
int session_hasbell(struct session *, struct window *); int session_hasbell(struct session *, struct winlink *);
struct session *session_find(const char *); struct session *session_find(const char *);
struct session *session_create(const char *, const char *, u_int, u_int); struct session *session_create(const char *, const char *, u_int, u_int);
void session_destroy(struct session *); void session_destroy(struct session *);
int session_index(struct session *, u_int *); int session_index(struct session *, u_int *);
int session_new( struct winlink *session_new(struct session *, const char *, const char *, int);
struct session *, const char *, const char *, u_int *); struct winlink *session_attach(struct session *, struct window *, int);
void session_attach(struct session *, struct window *); int session_detach(struct session *, struct winlink *);
int session_detach(struct session *, struct window *);
int session_has(struct session *, struct window *); int session_has(struct session *, struct window *);
int session_next(struct session *); int session_next(struct session *);
int session_previous(struct session *); int session_previous(struct session *);

265
window.c
View File

@ -1,4 +1,4 @@
/* $Id: window.c,v 1.23 2007-10-24 15:29:29 nicm Exp $ */ /* $Id: window.c,v 1.24 2007-10-26 12:29:07 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -22,6 +22,7 @@
#include <fcntl.h> #include <fcntl.h>
#include <paths.h> #include <paths.h>
#include <signal.h> #include <signal.h>
#include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <termios.h> #include <termios.h>
@ -47,15 +48,109 @@
* Each window also has a "virtual" screen (screen.c) which contains the * 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. * current state and is redisplayed when the window is reattached to a client.
* *
* A global list of windows is maintained, and a window may also be a member * Windows are stored directly on a global array and wrapped in any number of
* of any number of sessions. A reference count is maintained and a window * winlink structs to be linked onto local session RB trees A reference count
* removed from the global list and destroyed when it reaches zero. * is maintained and a window removed from the global list and destroyed when
* it reaches zero
*/ */
/* Global window list. */ /* Global window list. */
struct windows windows; struct windows windows;
RB_GENERATE(winlinks, winlink, entry, winlink_cmp);
int
winlink_cmp(struct winlink *wl1, struct winlink *wl2)
{
return (wl1->idx - wl2->idx);
}
struct winlink *
winlink_find_by_index(struct winlinks *wwl, int idx)
{
struct winlink wl;
if (idx < 0)
fatalx("bad index");
wl.idx = idx;
return (RB_FIND(winlinks, wwl, &wl));
}
int
winlink_next_index(struct winlinks *wwl)
{
u_int i;
for (i = 0; i < INT_MAX; i++) {
if (winlink_find_by_index(wwl, i) == NULL)
return (i);
}
fatalx("no free indexes");
}
struct winlink *
winlink_add(struct winlinks *wwl, struct window *w, int idx)
{
struct winlink *wl;
if (idx == -1)
idx = winlink_next_index(wwl);
else if (winlink_find_by_index(wwl, idx) != NULL)
return (NULL);
if (idx < 0)
fatalx("bad index");
wl = xcalloc(1, sizeof *wl);
wl->idx = idx;
wl->window = w;
RB_INSERT(winlinks, wwl, wl);
w->references++;
return (wl);
}
void
winlink_remove(struct winlinks *wwl, struct winlink *wl)
{
struct window *w = wl->window;
RB_REMOVE(winlinks, wwl, wl);
xfree(wl);
if (w->references == 0)
fatal("bad reference count");
w->references--;
if (w->references == 0)
window_destroy(w);
}
struct winlink *
winlink_next(unused struct winlinks *wwl, struct winlink *wl)
{
return (RB_NEXT(winlinks, wwl, wl));
}
struct winlink *
winlink_previous(struct winlinks *wwl, struct winlink *wl)
{
struct winlink *wk;
int idx = wl->idx;
wk = NULL;
wl = RB_MIN(winlinks, wwl);
while (wl != NULL && wl->idx < idx) {
wk = wl;
wl = RB_NEXT(winlinks, wwl, wl);
}
if (wl == NULL)
return (NULL);
return (wk);
}
/* Create a new window. */
struct window * struct window *
window_create( window_create(
const char *name, const char *cmd, const char **environ, u_int sx, u_int sy) const char *name, const char *cmd, const char **environ, u_int sx, u_int sy)
@ -92,10 +187,6 @@ window_create(
if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
fatal("fcntl failed"); fatal("fcntl failed");
mode = 1;
if (ioctl(fd, TIOCPKT, &mode) == -1)
fatal("ioctl failed");
w = xmalloc(sizeof *w); w = xmalloc(sizeof *w);
w->fd = fd; w->fd = fd;
w->in = buffer_create(BUFSIZ); w->in = buffer_create(BUFSIZ);
@ -126,60 +217,23 @@ window_create(
} else } else
w->name = xstrdup(name); w->name = xstrdup(name);
window_add(&windows, w); ARRAY_ADD(&windows, w);
w->references = 1; w->references = 0;
return (w); return (w);
} }
/* Find window index in list. */
int
window_index(struct windows *ww, struct window *w, u_int *i)
{
for (*i = 0; *i < ARRAY_LENGTH(ww); (*i)++) {
if (w == ARRAY_ITEM(ww, *i))
return (0);
}
return (-1);
}
/* Add a window to a list. */
void
window_add(struct windows *ww, struct window *w)
{
u_int i;
if (window_index(ww, NULL, &i) != 0)
ARRAY_ADD(ww, w);
else
ARRAY_SET(ww, i, w);
w->references++;
}
/* Remove a window from a list. */
void
window_remove(struct windows *ww, struct window *w)
{
u_int i;
if (window_index(ww, w, &i) != 0)
fatalx("window not found");
ARRAY_SET(ww, i, NULL);
while (!ARRAY_EMPTY(ww) && ARRAY_LAST(ww) == NULL)
ARRAY_TRUNC(ww, 1);
w->references--;
if (w->references == 0)
window_destroy(w);
if (w->references == 1)
window_remove(&windows, w);
}
/* Destroy a window. */
void void
window_destroy(struct window *w) window_destroy(struct window *w)
{ {
u_int i;
for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
if (ARRAY_ITEM(&windows, i) == w)
break;
}
ARRAY_REMOVE(&windows, i);
close(w->fd); close(w->fd);
input_free(w); input_free(w);
@ -193,55 +247,6 @@ window_destroy(struct window *w)
xfree(w); xfree(w);
} }
/* Locate next window in list. */
struct window *
window_next(struct windows *ww, struct window *w)
{
u_int i;
if (window_index(ww, w, &i) != 0)
fatalx("window not found");
if (i == ARRAY_LENGTH(ww) - 1)
return (NULL);
do {
i++;
w = window_at(ww, i);
if (w != NULL)
return (w);
} while (i != ARRAY_LENGTH(ww) - 1);
return (NULL);
}
/* Locate previous window in list. */
struct window *
window_previous(struct windows *ww, struct window *w)
{
u_int i;
if (window_index(ww, w, &i) != 0)
fatalx("window not found");
if (i == 0)
return (NULL);
do {
i--;
w = window_at(ww, i);
if (w != NULL)
return (w);
} while (i != 0);
return (NULL);
}
/* Locate window at specific position in list. */
struct window *
window_at(struct windows *ww, u_int i)
{
if (i >= ARRAY_LENGTH(ww))
return (NULL);
return (ARRAY_ITEM(ww, i));
}
/* Resize a window. */
int int
window_resize(struct window *w, u_int sx, u_int sy) window_resize(struct window *w, u_int sx, u_int sy)
{ {
@ -261,51 +266,3 @@ window_resize(struct window *w, u_int sx, u_int sy)
return (0); return (0);
} }
/* Handle window poll results. This is special because of TIOCPKT. */
int
window_poll(struct window *w, struct pollfd *pfd)
{
struct termios tio;
size_t size;
u_char *ptr;
size = BUFFER_USED(w->in);
if (buffer_poll(pfd, w->in, w->out) != 0)
return (-1);
if (BUFFER_USED(w->in) == size)
return (0);
ptr = BUFFER_IN(w->in) - (BUFFER_USED(w->in) - size);
log_debug("window packet: %hhu", *ptr);
switch (*ptr) {
case TIOCPKT_DATA:
case TIOCPKT_FLUSHREAD:
case TIOCPKT_FLUSHWRITE:
case TIOCPKT_STOP:
case TIOCPKT_START:
case TIOCPKT_DOSTOP:
case TIOCPKT_NOSTOP:
buffer_delete_range(w->in, size, 1);
break;
case TIOCPKT_IOCTL:
buffer_delete_range(w->in, size, 1 + sizeof tio);
break;
}
return (0);
}
/* Process window key. */
void
window_key(struct window *w, int key)
{
input_translate_key(w->out, key);
}
/* Process output data from child process. */
void
window_data(struct window *w, struct buffer *b)
{
input_parse(w, b);
}