aboutsummaryrefslogtreecommitdiff
path: root/server.c
diff options
context:
space:
mode:
Diffstat (limited to 'server.c')
-rw-r--r--server.c247
1 files changed, 132 insertions, 115 deletions
diff --git a/server.c b/server.c
index 1c617092..c9139ba9 100644
--- a/server.c
+++ b/server.c
@@ -1,4 +1,4 @@
-/* $Id: server.c,v 1.94 2009-01-11 00:48:42 nicm Exp $ */
+/* $Id: server.c,v 1.95 2009-01-11 23:31:46 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -49,12 +49,11 @@ void server_fill_clients(struct pollfd **);
void server_handle_clients(struct pollfd **);
struct client *server_accept_client(int);
void server_handle_client(struct client *);
-void server_handle_window(struct window *);
+void server_handle_window(struct window *, int);
void server_lost_client(struct client *);
-void server_lost_window(struct window *);
+int server_lost_window(struct window *, int);
void server_check_redraw(struct client *);
-void server_do_redraw_client(struct client *);
-void server_do_redraw_locked(struct client *);
+void server_redraw_locked(struct client *);
void server_check_timers(struct client *);
void server_second_timers(void);
int server_update_socket(const char *);
@@ -184,7 +183,9 @@ server_main(const char *srv_path, int srv_fd)
pfds = NULL;
while (!sigterm) {
/* Initialise pollfd array. */
- nfds = 1 + ARRAY_LENGTH(&windows) + ARRAY_LENGTH(&clients) * 2;
+ nfds = 1;
+ nfds += ARRAY_LENGTH(&windows) * 2;
+ nfds += ARRAY_LENGTH(&clients) * 2;
pfds = xrealloc(pfds, nfds, sizeof *pfds);
pfd = pfds;
@@ -279,19 +280,25 @@ server_main(const char *srv_path, int srv_fd)
void
server_fill_windows(struct pollfd **pfd)
{
- struct window *w;
- u_int i;
+ struct window *w;
+ struct window_pane *wp;
+ u_int i, j;
for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
- if ((w = ARRAY_ITEM(&windows, i)) == NULL || w->fd == -1)
- (*pfd)->fd = -1;
- else {
- (*pfd)->fd = w->fd;
- (*pfd)->events = POLLIN;
- if (BUFFER_USED(w->out) > 0)
- (*pfd)->events |= POLLOUT;
+ w = ARRAY_ITEM(&windows, i);
+ for (j = 0; j < 2; j++) {
+ if (w != NULL)
+ wp = w->panes[j];
+ if (w == NULL || wp == NULL || wp->fd == -1) {
+ (*pfd)->fd = -1;
+ } else {
+ (*pfd)->fd = wp->fd;
+ (*pfd)->events = POLLIN;
+ if (BUFFER_USED(wp->out) > 0)
+ (*pfd)->events |= POLLOUT;
+ }
+ (*pfd)++;
}
- (*pfd)++;
}
}
@@ -299,17 +306,24 @@ server_fill_windows(struct pollfd **pfd)
void
server_handle_windows(struct pollfd **pfd)
{
- struct window *w;
- u_int i;
+ struct window *w;
+ struct window_pane *wp;
+ u_int i, j;
for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
- if ((w = ARRAY_ITEM(&windows, i)) != NULL && w->fd != -1) {
- if (buffer_poll(*pfd, w->in, w->out) != 0)
- server_lost_window(w);
- else
- server_handle_window(w);
+ w = ARRAY_ITEM(&windows, i);
+ for (j = 0; j < 2; j++) {
+ if (w != NULL)
+ wp = w->panes[j];
+ if (w != NULL && wp != NULL && wp->fd != -1) {
+ if (buffer_poll(*pfd, wp->in, wp->out) != 0) {
+ if (server_lost_window(w, j) != 0)
+ break;
+ } else
+ server_handle_window(w, j);
+ }
+ (*pfd)++;
}
- (*pfd)++;
}
}
@@ -329,7 +343,7 @@ server_check_redraw(struct client *c)
c->tty.flags &= ~TTY_FREEZE;
if (options_get_number(&s->options, "set-titles")) {
- title = s->curw->window->base.title;
+ title = s->curw->window->active->screen->title;
if (c->title == NULL || strcmp(title, c->title) != 0) {
if (c->title != NULL)
xfree(c->title);
@@ -338,16 +352,7 @@ server_check_redraw(struct client *c)
}
}
- if (c->flags & CLIENT_REDRAW) {
- if (server_locked)
- server_do_redraw_locked(c);
- else
- server_do_redraw_client(c);
-
- c->flags |= CLIENT_STATUS;
- }
-
- if (c->flags & CLIENT_STATUS) {
+ if (c->flags & (CLIENT_REDRAW|CLIENT_STATUS)) {
if (c->message_string != NULL)
status_message_redraw(c);
else if (c->prompt_string != NULL)
@@ -356,78 +361,47 @@ server_check_redraw(struct client *c)
status_redraw(c);
}
- c->tty.flags |= flags;
+ if (c->flags & CLIENT_REDRAW) {
+ if (server_locked)
+ server_redraw_locked(c);
+ else
+ screen_redraw_screen(c, NULL);
+ }
- c->flags &= ~(CLIENT_REDRAW|CLIENT_STATUS);
-}
+ if (c->flags & CLIENT_STATUS)
+ screen_redraw_status(c);
-/* Redraw client normally. */
-void
-server_do_redraw_client(struct client *c)
-{
- struct session *s = c->session;
- struct screen_redraw_ctx ctx;
- struct screen screen;
- struct grid_cell gc;
- u_int xx, yy, sx, sy;
-
- xx = c->sx;
- yy = c->sy - 1;
+ c->tty.flags |= flags;
- sx = screen_size_x(s->curw->window->screen);
- sy = screen_size_y(s->curw->window->screen);
-
- if (sx < xx || sy < yy) {
- /*
- * Fake up a blank(ish) screen and use it to draw the empty
- * regions. NOTE: because this uses tty_write_client but
- * doesn't write the client's screen, this can't use anything
- * which relies on cursor position.
- */
-
- screen_init(&screen, xx, yy, 0);
- screen_redraw_start(&ctx, &screen, tty_write_client, c);
- if (sx < xx)
- screen_redraw_columns(&ctx, sx, xx - sx);
- if (sy < yy) {
- memcpy(&gc, &grid_default_cell, sizeof gc);
- gc.data = '-';
- grid_view_fill(screen.grid, &gc, 0, sy, xx, 1);
- screen_redraw_lines(&ctx, sy, yy - sy);
- }
- screen_redraw_stop(&ctx);
- screen_free(&screen);
- }
-
- screen_redraw_start_client(&ctx, c);
- screen_redraw_lines(&ctx, 0, screen_size_y(ctx.s));
- screen_redraw_stop(&ctx);
+ c->flags &= ~(CLIENT_REDRAW|CLIENT_STATUS);
}
/* Redraw client when locked. */
void
-server_do_redraw_locked(struct client *c)
+server_redraw_locked(struct client *c)
{
- struct session *s = c->session;
- struct window *w = s->curw->window;
- struct screen_write_ctx ctx;
- struct screen screen;
- u_int colour, xx, yy;
- int style;
+ struct screen_write_ctx ctx;
+ struct screen screen;
+ u_int colour, xx, yy;
+ int style;
xx = c->sx;
yy = c->sy - 1;
if (xx == 0 || yy == 0)
return;
- colour = options_get_number(&w->options, "clock-mode-colour");
- style = options_get_number(&w->options, "clock-mode-style");
+ colour = options_get_number(
+ &global_window_options, "clock-mode-colour");
+ style = options_get_number(
+ &global_window_options, "clock-mode-style");
screen_init(&screen, xx, yy, 0);
- screen_write_start(&ctx, &screen, tty_write_client, c);
+ screen_write_start(&ctx, NULL, &screen);
clock_draw(&ctx, colour, style);
screen_write_stop(&ctx);
+ screen_redraw_screen(c, &screen);
+
screen_free(&screen);
}
@@ -567,6 +541,7 @@ server_accept_client(int srv_fd)
c->session = NULL;
c->sx = 80;
c->sy = 25;
+ screen_init(&c->status, c->sx, 1, 0);
c->message_string = NULL;
@@ -588,9 +563,12 @@ server_accept_client(int srv_fd)
void
server_handle_client(struct client *c)
{
- struct window *w = c->session->curw->window;
- int key, prefix;
+ struct winlink *wl = c->session->curw;
+ struct window_pane *wp = wl->window->active;
+ int key, prefix;
+ u_int oy;
+ /* Process keys. */
prefix = options_get_number(&c->session->options, "prefix");
while (tty_keys_next(&c->tty, &key) == 0) {
server_activity = time(NULL);
@@ -610,8 +588,20 @@ server_handle_client(struct client *c)
} else if (key == prefix)
c->flags |= CLIENT_PREFIX;
else
- window_key(w, c, key);
+ window_pane_key(wp, c, key);
}
+
+ /* Ensure the cursor is in the right place and correctly on or off. */
+ if (c->prompt_string == NULL && c->message_string == NULL &&
+ !server_locked && wp->screen->mode & MODE_CURSOR) {
+ oy = 0;
+ if (wp == wl->window->panes[1])
+ oy = wp->window->sy / 2;
+
+ tty_write(&c->tty, wp->screen, 0, TTY_CURSORMODE, 1);
+ tty_cursor(&c->tty, wp->screen->cx, wp->screen->cy, oy);
+ } else
+ tty_write(&c->tty, wp->screen, 0, TTY_CURSORMODE, 0);
}
/* Lost a client. */
@@ -654,13 +644,14 @@ server_lost_client(struct client *c)
/* Handle window data. */
void
-server_handle_window(struct window *w)
+server_handle_window(struct window *w, int pane)
{
struct session *s;
+ struct client *c;
u_int i;
int action, update;
- window_parse(w);
+ window_pane_parse(w->panes[pane]);
if (!(w->flags & WINDOW_BELL) && !(w->flags & WINDOW_ACTIVITY))
return;
@@ -678,12 +669,22 @@ server_handle_window(struct window *w)
action = options_get_number(&s->options, "bell-action");
switch (action) {
case BELL_ANY:
- tty_write_session(s, TTY_BELL);
+ if (s->flags & SESSION_UNATTACHED)
+ break;
+ for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
+ c = ARRAY_ITEM(&clients, i);
+ if (c != NULL && c->session == s)
+ tty_putcode(&c->tty, TTYC_BEL);
+ }
break;
case BELL_CURRENT:
- if (s->curw->window != w)
+ if (w->active != w->panes[pane])
break;
- tty_write_session(s, TTY_BELL);
+ for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
+ c = ARRAY_ITEM(&clients, i);
+ if (c != NULL && c->session == s)
+ tty_putcode(&c->tty, TTYC_BEL);
+ }
break;
}
update = 1;
@@ -703,20 +704,27 @@ server_handle_window(struct window *w)
}
/* Lost window: move clients on to next window. */
-void
-server_lost_window(struct window *w)
+int
+server_lost_window(struct window *w, int pane)
{
- struct client *c;
- struct session *s;
- struct winlink *wl;
- u_int i, j;
- int destroyed;
-
- log_debug("lost window %d", w->fd);
+ struct client *c;
+ struct session *s;
+ struct winlink *wl;
+ struct window_pane *wp;
+ u_int i, j;
+ int destroyed;
+
+ wp = w->panes[pane];
+ log_debug("lost window %d (%s pane %d)", wp->fd, w->name, pane);
+
+ if (window_remove_pane(w, pane) == 0) {
+ server_redraw_window(w);
+ return (0);
+ }
if (options_get_number(&w->options, "remain-on-exit")) {
- w->fd = -1;
- return;
+ wp->fd = -1;
+ return (0);
}
for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
@@ -751,18 +759,20 @@ server_lost_window(struct window *w)
}
recalculate_sizes();
+ return (1);
}
/* Call any once-per-second timers. */
void
server_second_timers(void)
{
- struct window *w;
- u_int i;
- int xtimeout;
- struct tm now, then;
- static time_t last_t = 0;
- time_t t;
+ struct window *w;
+ struct window_pane *wp;
+ u_int i, j;
+ int xtimeout;
+ struct tm now, then;
+ static time_t last_t = 0;
+ time_t t;
t = time(NULL);
xtimeout = options_get_number(&global_options, "lock-after-time");
@@ -771,8 +781,15 @@ server_second_timers(void)
for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
w = ARRAY_ITEM(&windows, i);
- if (w->mode != NULL && w->mode->timer != NULL)
- w->mode->timer(w);
+ if (w == NULL)
+ continue;
+ for (j = 0; j < 2; j++) {
+ wp = w->panes[j];
+ if (wp == NULL)
+ continue;
+ if (wp->mode != NULL && wp->mode->timer != NULL)
+ wp->mode->timer(wp);
+ }
}
gmtime_r(&t, &now);