summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--TODO6
-rw-r--r--server-fn.c66
-rw-r--r--server.c57
-rw-r--r--status.c60
-rw-r--r--tmux.h15
5 files changed, 139 insertions, 65 deletions
diff --git a/TODO b/TODO
index 55e52fd1..fcbba555 100644
--- a/TODO
+++ b/TODO
@@ -37,8 +37,6 @@
- function groups, bind-key ^W { select-window 0; send-key ^W } etc ***
- allow fnmatch for -c, so that you can, eg, detach all clients
- bind non prefix keys
-- stuff like rename would be nice to be able to do in-client like screen, if
- it could be implemented in a non-icky way
- there is too much redrawing. use flags?
- command mode (! + type tmux command)
- garbage collect window history (100 lines at a time?) if it hasn't been used
@@ -86,3 +84,7 @@ option to pass through to xterm window when switching window
session not being watched?
- document status-left/status-right/status-interval/set-titles
- enhance paste buffers. per-session buffers, lots of command love
+- stuff like rename would be nice to be able to do in-client like screen, if
+ it could be implemented in a non-icky way (we have control over the tty fd
+ now in the server so should be easier...)
+- tidy up window modes
diff --git a/server-fn.c b/server-fn.c
index 8547fbf7..9893d409 100644
--- a/server-fn.c
+++ b/server-fn.c
@@ -1,4 +1,4 @@
-/* $Id: server-fn.c,v 1.42 2008-06-16 17:35:40 nicm Exp $ */
+/* $Id: server-fn.c,v 1.43 2008-06-19 18:27:55 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -24,6 +24,31 @@
#include "tmux.h"
void
+server_set_client_message(struct client *c, const char *msg)
+{
+ struct timespec ts = { 0, 750000000L };
+
+ c->message_string = xstrdup(msg);
+ if (clock_gettime(CLOCK_REALTIME, &c->message_timer) != 0)
+ fatal("clock_gettime");
+ timespecadd(&c->message_timer, &ts, &c->message_timer);
+
+ c->flags |= CLIENT_STATUS;
+}
+
+void
+server_clear_client_message(struct client *c)
+{
+ if (c->message_string == NULL)
+ return;
+
+ xfree(c->message_string);
+ c->message_string = NULL;
+
+ c->flags |= CLIENT_STATUS;
+}
+
+void
server_write_client(
struct client *c, enum hdrtype type, const void *buf, size_t len)
{
@@ -150,47 +175,14 @@ server_status_window(struct window *w)
void printflike2
server_write_message(struct client *c, const char *fmt, ...)
{
- struct screen_redraw_ctx ctx;
- va_list ap;
- char *msg;
- size_t size;
- u_int slines;
-
- slines = options_get_number(&c->session->options, "status-lines");
-
- screen_redraw_start_client(&ctx, c);
+ va_list ap;
+ char *msg;
va_start(ap, fmt);
xvasprintf(&msg, fmt, ap);
va_end(ap);
- msg = xrealloc(msg, 1, c->sx + 1);
- msg[c->sx] = '\0';
-
- size = strlen(msg);
- if (size < c->sx)
- memset(msg + size, ' ', c->sx - size);
-
- screen_redraw_move_cursor(&ctx, 0, c->sy - 1);
- screen_redraw_set_attributes(&ctx, ATTR_REVERSE, 0x88);
- screen_redraw_write_string(&ctx, "%s", msg);
-
- buffer_flush(c->tty.fd, c->tty.in, c->tty.out);
- usleep(750000);
-
- memset(msg, ' ', c->sx);
-
- screen_redraw_move_cursor(&ctx, 0, c->sy - 1);
- screen_redraw_set_attributes(&ctx, 0, 0x88);
- screen_redraw_write_string(&ctx, "%s", msg);
+ server_set_client_message(c, msg);
xfree(msg);
-
- if (slines == 0) {
- screen_redraw_lines(&ctx, c->sy - 1, 1);
- screen_redraw_stop(&ctx);
- } else {
- screen_redraw_stop(&ctx);
- server_status_client(c);
- }
}
diff --git a/server.c b/server.c
index 3b63b69b..b10cf476 100644
--- a/server.c
+++ b/server.c
@@ -1,4 +1,4 @@
-/* $Id: server.c,v 1.68 2008-06-18 22:21:51 nicm Exp $ */
+/* $Id: server.c,v 1.69 2008-06-19 18:27:55 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -54,7 +54,7 @@ void server_handle_window(struct window *);
void server_lost_client(struct client *);
void server_lost_window(struct window *);
void server_check_redraw(struct client *);
-void server_check_status(struct client *);
+void server_check_timers(struct client *);
void server_update_socket(const char *);
/* Fork new server. */
@@ -322,7 +322,7 @@ server_check_redraw(struct client *c)
}
xx = c->sx;
- yy = c->sy - options_get_number(&s->options, "status-lines");
+ yy = c->sy - 1; //options_get_number(&s->options, "status-lines");
if (c->flags & CLIENT_REDRAW) {
sx = screen_size_x(s->curw->window->screen);
sy = screen_size_y(s->curw->window->screen);
@@ -351,33 +351,47 @@ server_check_redraw(struct client *c)
screen_redraw_lines(&ctx, 0, screen_size_y(ctx.s));
screen_redraw_stop(&ctx);
- status_redraw(c);
- } else if (c->flags & CLIENT_STATUS)
- status_redraw(c);
+ c->flags |= CLIENT_STATUS;
+ }
- c->flags &= ~(CLIENT_CLEAR|CLIENT_REDRAW|CLIENT_STATUS);
+ if (c->flags & CLIENT_STATUS) {
+ if (c->message_string != NULL)
+ status_message_redraw(c);
+ else
+ status_redraw(c);
+ }
+
+ c->flags &= ~(CLIENT_REDRAW|CLIENT_STATUS);
}
-/* Check for status line redraw on client. */
+/* Check for timers on client. */
void
-server_check_status(struct client *c)
+server_check_timers(struct client *c)
{
- struct timespec ts;
+ struct session *s;
+ struct timespec ts, ts2;
u_int nlines, interval;
if (c == NULL || c->session == NULL)
return;
-
- nlines = options_get_number(&c->session->options, "status-lines");
- interval = options_get_number(&c->session->options, "status-interval");
- if (nlines == 0 || interval == 0)
- return;
+ s = c->session;
if (clock_gettime(CLOCK_REALTIME, &ts) != 0)
fatal("clock_gettime");
- ts.tv_sec -= interval;
+
+ if (c->message_string != NULL && timespeccmp(&ts, &c->message_timer, >))
+ server_clear_client_message(c);
- if (timespeccmp(&c->status_ts, &ts, <))
+ nlines = options_get_number(&s->options, "status-lines");
+ if (nlines == 0)
+ return;
+ interval = options_get_number(&s->options, "status-interval");
+ if (interval == 0)
+ return;
+
+ memcpy(&ts2, &ts, sizeof ts2);
+ ts2.tv_sec -= interval;
+ if (timespeccmp(&c->status_timer, &ts2, <))
c->flags |= CLIENT_STATUS;
}
@@ -391,8 +405,8 @@ server_fill_clients(struct pollfd **pfd)
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
+ server_check_timers(c);
server_check_redraw(c);
- server_check_status(c);
if (c == NULL)
(*pfd)->fd = -1;
@@ -483,6 +497,12 @@ server_accept_client(int srv_fd)
c->sx = 80;
c->sy = 25;
+ c->message_string = NULL;
+
+ c->prompt_string = NULL;
+ c->prompt_buffer = NULL;
+ c->prompt_size = 0;
+
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
if (ARRAY_ITEM(&clients, i) == NULL) {
ARRAY_SET(&clients, i, c);
@@ -502,6 +522,7 @@ server_handle_client(struct client *c)
prefix = options_get_key(&c->session->options, "prefix-key");
while (tty_keys_next(&c->tty, &key) == 0) {
+ server_clear_client_message(c);
if (c->flags & CLIENT_PREFIX) {
key_bindings_dispatch(key, c);
c->flags &= ~CLIENT_PREFIX;
diff --git a/status.c b/status.c
index a9dbfb5e..20e3282c 100644
--- a/status.c
+++ b/status.c
@@ -1,4 +1,4 @@
-/* $Id: status.c,v 1.30 2008-06-18 22:21:51 nicm Exp $ */
+/* $Id: status.c,v 1.31 2008-06-19 18:27:55 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -39,14 +39,15 @@ status_redraw(struct client *c)
size_t llen, rlen, offset, xx, yy;
size_t size, start, width;
u_char attr, colr;
+ struct tm *tm;
int larrow, rarrow;
yy = options_get_number(&s->options, "status-lines");
if (c->sy == 0 || yy == 0)
- return;
+ goto off;
larrow = rarrow = 0;
- if (clock_gettime(CLOCK_REALTIME, &c->status_ts) != 0)
+ if (clock_gettime(CLOCK_REALTIME, &c->status_timer) != 0)
fatal("clock_gettime failed");
colr = options_get_colours(&s->options, "status-colour");
@@ -54,11 +55,12 @@ status_redraw(struct client *c)
if (yy == 0)
goto blank;
+ tm = localtime(&(c->status_timer.tv_sec));
left = options_get_string(&s->options, "status-left");
- strftime(lbuf, sizeof lbuf, left, localtime(&(c->status_ts.tv_sec)));
+ strftime(lbuf, sizeof lbuf, left, tm);
llen = strlen(lbuf);
right = options_get_string(&s->options, "status-right");
- strftime(rbuf, sizeof rbuf, right, localtime(&(c->status_ts.tv_sec)));
+ strftime(rbuf, sizeof rbuf, right, tm);
rlen = strlen(rbuf);
/*
@@ -229,6 +231,26 @@ blank:
for (offset = 0; offset < c->sx; offset++)
ctx.write(ctx.data, TTY_CHARACTER, ' ');
screen_redraw_stop(&ctx);
+
+ return;
+
+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) {
+ screen_redraw_move_cursor(&ctx, 0, c->sy - 1);
+ screen_redraw_set_attributes(&ctx, 0, 0x88);
+ for (offset = 0; offset < c->sx; offset++)
+ ctx.write(ctx.data, TTY_CHARACTER, ' ');
+ } else
+ screen_redraw_lines(&ctx, c->sy - 1, 1);
+ screen_redraw_stop(&ctx);
+
+ return;
}
size_t
@@ -261,3 +283,31 @@ status_print(struct session *s, struct winlink *wl, u_char *attr)
xasprintf(&text, "%d:%s%c", wl->idx, wl->window->name, flag);
return (text);
}
+
+/* Draw client message on status line of present else on last line. */
+void
+status_message_redraw(struct client *c)
+{
+ struct screen_redraw_ctx ctx;
+ size_t xx, yy;
+
+ if (c->sx == 0 || c->sy == 0)
+ return;
+
+ xx = strlen(c->message_string);
+ if (xx > c->sx)
+ xx = c->sx;
+ yy = c->sy - 1;
+
+ screen_redraw_start_client(&ctx, c);
+ screen_redraw_set_attributes(&ctx, ATTR_REVERSE, 0x88);
+
+ screen_redraw_move_cursor(&ctx, 0, yy);
+ screen_redraw_write_string(&ctx, "%.*s", (int) xx, c->message_string);
+ for (; xx < c->sx; xx++)
+ ctx.write(ctx.data, TTY_CHARACTER, ' ');
+ screen_redraw_stop(&ctx);
+
+ /* Force cursor off. */
+ tty_write_client(c, TTY_CURSOROFF);
+}
diff --git a/tmux.h b/tmux.h
index 5038d84b..83e0f643 100644
--- a/tmux.h
+++ b/tmux.h
@@ -1,4 +1,4 @@
-/* $Id: tmux.h,v 1.151 2008-06-18 20:58:03 nicm Exp $ */
+/* $Id: tmux.h,v 1.152 2008-06-19 18:27:55 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -664,7 +664,7 @@ struct client {
char *title;
struct tty tty;
- struct timespec status_ts;
+ struct timespec status_timer;
u_int sx;
u_int sy;
@@ -674,9 +674,15 @@ struct client {
#define CLIENT_MOUSE 0x4
#define CLIENT_REDRAW 0x8
#define CLIENT_STATUS 0x10
-#define CLIENT_CLEAR 0x20
int flags;
+ char *message_string;
+ struct timespec message_timer;
+
+ char *prompt_string;
+ char *prompt_buffer;
+ size_t prompt_size;
+
struct session *session;
};
ARRAY_DECL(clients, struct client *);
@@ -949,6 +955,8 @@ int server_start(const char *);
int server_msg_dispatch(struct client *);
/* server-fn.c */
+void server_set_client_message(struct client *, const char *);
+void server_clear_client_message(struct client *);
struct session *server_extract_session(
struct msg_command_data *, char *, char **);
void server_write_client(
@@ -967,6 +975,7 @@ void printflike2 server_write_message(struct client *, const char *, ...);
/* status.c */
void status_redraw(struct client *c);
+void status_message_redraw(struct client *c);
/* resize.c */
void recalculate_sizes(void);