diff options
author | Thomas Adam <thomas@xteddy.org> | 2015-08-30 21:44:01 +0100 |
---|---|---|
committer | Thomas Adam <thomas@xteddy.org> | 2015-08-30 21:44:01 +0100 |
commit | cb89f2f2a197db5bf7e1acc8248f381c6f0410cd (patch) | |
tree | 9074f8aa373b1bcb857fee46a47d305152cacf06 | |
parent | 486421ceff1b4d618d84ac3cb8c4dd9135b7960d (diff) | |
parent | b87dc608d9b5b470926aaf77c5956befdfb7bc7b (diff) | |
download | rtmux-cb89f2f2a197db5bf7e1acc8248f381c6f0410cd.tar.gz rtmux-cb89f2f2a197db5bf7e1acc8248f381c6f0410cd.tar.bz2 rtmux-cb89f2f2a197db5bf7e1acc8248f381c6f0410cd.zip |
Merge branch 'obsd-master'
Conflicts:
Makefile
format.c
-rw-r--r-- | Makefile.am | 2 | ||||
-rw-r--r-- | alerts.c (renamed from server-window.c) | 167 | ||||
-rw-r--r-- | arguments.c | 6 | ||||
-rw-r--r-- | cmd-choose-buffer.c | 4 | ||||
-rw-r--r-- | cmd-paste-buffer.c | 33 | ||||
-rw-r--r-- | cmd-save-buffer.c | 23 | ||||
-rw-r--r-- | cmd-set-buffer.c | 39 | ||||
-rw-r--r-- | cmd-set-option.c | 6 | ||||
-rw-r--r-- | cmd-show-environment.c | 2 | ||||
-rw-r--r-- | cmd-swap-pane.c | 2 | ||||
-rw-r--r-- | format.c | 352 | ||||
-rw-r--r-- | input.c | 9 | ||||
-rw-r--r-- | layout-set.c | 6 | ||||
-rw-r--r-- | log.c | 9 | ||||
-rw-r--r-- | names.c | 65 | ||||
-rw-r--r-- | paste.c | 63 | ||||
-rw-r--r-- | screen.c | 8 | ||||
-rw-r--r-- | server-client.c | 8 | ||||
-rw-r--r-- | server.c | 3 | ||||
-rw-r--r-- | session.c | 1 | ||||
-rw-r--r-- | status.c | 16 | ||||
-rw-r--r-- | tmux.c | 4 | ||||
-rw-r--r-- | tmux.h | 75 | ||||
-rw-r--r-- | window-copy.c | 32 | ||||
-rw-r--r-- | window.c | 47 | ||||
-rw-r--r-- | xterm-keys.c | 2 |
26 files changed, 595 insertions, 389 deletions
diff --git a/Makefile.am b/Makefile.am index 3173ba99..e9a6bd33 100644 --- a/Makefile.am +++ b/Makefile.am @@ -57,6 +57,7 @@ endif # List of sources. dist_tmux_SOURCES = \ + alerts.c \ arguments.c \ attributes.c \ cfg.c \ @@ -156,7 +157,6 @@ dist_tmux_SOURCES = \ screen.c \ server-client.c \ server-fn.c \ - server-window.c \ server.c \ session.c \ signal.c \ diff --git a/server-window.c b/alerts.c index c96c2602..cfdd30e3 100644 --- a/server-window.c +++ b/alerts.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* - * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> + * Copyright (c) 2015 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 @@ -19,42 +19,133 @@ #include <sys/types.h> #include <event.h> -#include <stdlib.h> -#include <unistd.h> #include "tmux.h" -int server_window_check_bell(struct session *, struct winlink *); -int server_window_check_activity(struct session *, struct winlink *); -int server_window_check_silence(struct session *, struct winlink *); -void ring_bell(struct session *); +int alerts_fired; + +void alerts_timer(int, short, void *); +int alerts_enabled(struct window *, int); +void alerts_callback(int, short, void *); +void alerts_reset(struct window *); + +int alerts_check_bell(struct session *, struct winlink *); +int alerts_check_activity(struct session *, struct winlink *); +int alerts_check_silence(struct session *, struct winlink *); +void alerts_ring_bell(struct session *); + +void +alerts_timer(unused int fd, unused short events, void *arg) +{ + struct window *w = arg; + + log_debug("@%u alerts timer expired", w->id); + alerts_reset(w); + alerts_queue(w, WINDOW_SILENCE); +} -/* Window functions that need to happen every loop. */ void -server_window_loop(void) +alerts_callback(unused int fd, unused short events, unused void *arg) { struct window *w; struct session *s; struct winlink *wl; + int flags, alerts; RB_FOREACH(w, windows, &windows) { RB_FOREACH(s, sessions, &sessions) { RB_FOREACH(wl, winlinks, &s->windows) { if (wl->window != w) continue; + flags = w->flags; - if (server_window_check_bell(s, wl) || - server_window_check_activity(s, wl) || - server_window_check_silence(s, wl)) + alerts = alerts_check_bell(s, wl); + alerts |= alerts_check_activity(s, wl); + alerts |= alerts_check_silence(s, wl); + if (alerts != 0) server_status_session(s); + + log_debug("%s:%d @%u alerts check, alerts %#x, " + "flags %#x", s->name, wl->idx, w->id, + alerts, flags); } } } + alerts_fired = 0; } -/* Check for bell in window. */ int -server_window_check_bell(struct session *s, struct winlink *wl) +alerts_enabled(struct window *w, int flags) +{ + struct session *s; + + if (flags & WINDOW_ACTIVITY) { + if (options_get_number(&w->options, "monitor-activity")) + return (1); + } + if (flags & WINDOW_SILENCE) { + if (options_get_number(&w->options, "monitor-silence") != 0) + return (1); + } + if (~flags & WINDOW_BELL) + return (0); + RB_FOREACH(s, sessions, &sessions) { + if (!session_has(s, w)) + continue; + if (options_get_number(&s->options, "bell-action") != BELL_NONE) + return (1); + } + return (0); +} + +void +alerts_reset_all(void) +{ + struct window *w; + + RB_FOREACH(w, windows, &windows) + alerts_reset(w); +} + +void +alerts_reset(struct window *w) +{ + struct timeval tv; + + w->flags &= ~WINDOW_SILENCE; + event_del(&w->alerts_timer); + + timerclear(&tv); + tv.tv_sec = options_get_number(&w->options, "monitor-silence"); + + log_debug("@%u alerts timer reset %u", w->id, (u_int)tv.tv_sec); + if (tv.tv_sec != 0) + event_add(&w->alerts_timer, &tv); +} + +void +alerts_queue(struct window *w, int flags) +{ + if (!event_initialized(&w->alerts_timer)) + evtimer_set(&w->alerts_timer, alerts_timer, w); + + if (w->flags & flags) + return; + w->flags |= flags; + log_debug("@%u alerts flags added %#x", w->id, flags); + + if (!alerts_fired && alerts_enabled(w, flags)) { + log_debug("alerts check queued (by @%u)", w->id); + event_once(-1, EV_TIMEOUT, alerts_callback, NULL, NULL); + alerts_fired = 1; + } + + if (flags & WINDOW_ACTIVITY) + alerts_reset(w); +} + +int +alerts_check_bell(struct session *s, struct winlink *wl) { struct client *c; struct window *w = wl->window; @@ -69,10 +160,11 @@ server_window_check_bell(struct session *s, struct winlink *wl) if (s->curw->window == w) w->flags &= ~WINDOW_BELL; - visual = options_get_number(&s->options, "visual-bell"); action = options_get_number(&s->options, "bell-action"); if (action == BELL_NONE) return (0); + + visual = options_get_number(&s->options, "visual-bell"); TAILQ_FOREACH(c, &clients, entry) { if (c->session != s || c->flags & CLIENT_CONTROL) continue; @@ -92,12 +184,11 @@ server_window_check_bell(struct session *s, struct winlink *wl) status_message_set(c, "Bell in window %d", wl->idx); } - return (1); + return (WINDOW_BELL); } -/* Check for activity in window. */ int -server_window_check_activity(struct session *s, struct winlink *wl) +alerts_check_activity(struct session *s, struct winlink *wl) { struct client *c; struct window *w = wl->window; @@ -114,7 +205,7 @@ server_window_check_activity(struct session *s, struct winlink *wl) return (0); if (options_get_number(&s->options, "bell-on-alert")) - ring_bell(s); + alerts_ring_bell(s); wl->flags |= WINLINK_ACTIVITY; if (options_get_number(&s->options, "visual-activity")) { @@ -125,45 +216,28 @@ server_window_check_activity(struct session *s, struct winlink *wl) } } - return (1); + return (WINDOW_ACTIVITY); } -/* Check for silence in window. */ int -server_window_check_silence(struct session *s, struct winlink *wl) +alerts_check_silence(struct session *s, struct winlink *wl) { struct client *c; struct window *w = wl->window; - struct timeval timer; - int silence_interval, timer_difference; - - if (!(w->flags & WINDOW_SILENCE) || wl->flags & WINLINK_SILENCE) - return (0); - if (s->curw == wl && !(s->flags & SESSION_UNATTACHED)) { - /* - * Reset the timer for this window if we've focused it. We - * don't want the timer tripping as soon as we've switched away - * from this window. - */ - if (gettimeofday(&w->silence_timer, NULL) != 0) - fatal("gettimeofday failed"); + if (s->curw->window == w) + w->flags &= ~WINDOW_SILENCE; + if (!(w->flags & WINDOW_SILENCE) || wl->flags & WINLINK_SILENCE) return (0); - } - - silence_interval = options_get_number(&w->options, "monitor-silence"); - if (silence_interval == 0) + if (s->curw == wl && !(s->flags & SESSION_UNATTACHED)) return (0); - if (gettimeofday(&timer, NULL) != 0) - fatal("gettimeofday"); - timer_difference = timer.tv_sec - w->silence_timer.tv_sec; - if (timer_difference <= silence_interval) + if (options_get_number(&w->options, "monitor-silence") == 0) return (0); if (options_get_number(&s->options, "bell-on-alert")) - ring_bell(s); + alerts_ring_bell(s); wl->flags |= WINLINK_SILENCE; if (options_get_number(&s->options, "visual-silence")) { @@ -174,12 +248,11 @@ server_window_check_silence(struct session *s, struct winlink *wl) } } - return (1); + return (WINDOW_SILENCE); } -/* Ring terminal bell. */ void -ring_bell(struct session *s) +alerts_ring_bell(struct session *s) { struct client *c; diff --git a/arguments.c b/arguments.c index ca6cc760..9f080f52 100644 --- a/arguments.c +++ b/arguments.c @@ -28,6 +28,12 @@ * Manipulate command arguments. */ +struct args_entry { + u_char flag; + char *value; + RB_ENTRY(args_entry) entry; +}; + struct args_entry *args_find(struct args *, u_char); RB_GENERATE(args_tree, args_entry, entry, args_cmp); diff --git a/cmd-choose-buffer.c b/cmd-choose-buffer.c index af178976..b4590306 100644 --- a/cmd-choose-buffer.c +++ b/cmd-choose-buffer.c @@ -65,7 +65,7 @@ cmd_choose_buffer_exec(struct cmd *self, struct cmd_q *cmdq) return (CMD_RETURN_ERROR); utf8flag = options_get_number(&wl->window->options, "utf8"); - if (paste_get_top() == NULL) + if (paste_get_top(NULL) == NULL) return (CMD_RETURN_NORMAL); if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0) @@ -85,7 +85,7 @@ cmd_choose_buffer_exec(struct cmd *self, struct cmd_q *cmdq) cdata->ft_template = xstrdup(template); format_defaults_paste_buffer(cdata->ft, pb, utf8flag); - xasprintf(&action_data, "%s", pb->name); + xasprintf(&action_data, "%s", paste_buffer_name(pb)); cdata->command = cmd_template_replace(action, action_data, 1); free(action_data); diff --git a/cmd-paste-buffer.c b/cmd-paste-buffer.c index 5d91aeff..5027a4f8 100644 --- a/cmd-paste-buffer.c +++ b/cmd-paste-buffer.c @@ -47,7 +47,9 @@ cmd_paste_buffer_exec(struct cmd *self, struct cmd_q *cmdq) struct window_pane *wp; struct session *s; struct paste_buffer *pb; - const char *sepstr, *bufname; + const char *sepstr, *bufname, *bufdata, *bufend, *line; + size_t seplen, bufsize; + int bracket = args_has(args, 'p'); if (cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp) == NULL) return (CMD_RETURN_ERROR); @@ -57,7 +59,7 @@ cmd_paste_buffer_exec(struct cmd *self, struct cmd_q *cmdq) bufname = args_get(args, 'b'); if (bufname == NULL) - pb = paste_get_top(); + pb = paste_get_top(NULL); else { pb = paste_get_name(bufname); if (pb == NULL) { @@ -66,7 +68,7 @@ cmd_paste_buffer_exec(struct cmd *self, struct cmd_q *cmdq) } } - if (pb != NULL) { + if (pb != NULL && ~wp->flags & PANE_INPUTOFF) { sepstr = args_get(args, 's'); if (sepstr == NULL) { if (args_has(args, 'r')) @@ -74,10 +76,31 @@ cmd_paste_buffer_exec(struct cmd *self, struct cmd_q *cmdq) else sepstr = "\r"; } - paste_send_pane(pb, wp, sepstr, args_has(args, 'p')); + seplen = strlen(sepstr); + + if (bracket && (wp->screen->mode & MODE_BRACKETPASTE)) + bufferevent_write(wp->event, "\033[200~", 6); + + bufdata = paste_buffer_data(pb, &bufsize); + bufend = bufdata + bufsize; + + for (;;) { + line = memchr(bufdata, '\n', bufend - bufdata); + if (line == NULL) + break; + + bufferevent_write(wp->event, bufdata, line - bufdata); + bufferevent_write(wp->event, sepstr, seplen); + + bufdata = line + 1; + } + if (bufdata != bufend) + bufferevent_write(wp->event, bufdata, bufend - bufdata); + + if (bracket && (wp->screen->mode & MODE_BRACKETPASTE)) + bufferevent_write(wp->event, "\033[201~", 6); } - /* Delete the buffer if -d. */ if (args_has(args, 'd')) { if (bufname == NULL) paste_free_top(); diff --git a/cmd-save-buffer.c b/cmd-save-buffer.c index 86e302ae..1e020934 100644 --- a/cmd-save-buffer.c +++ b/cmd-save-buffer.c @@ -56,14 +56,14 @@ cmd_save_buffer_exec(struct cmd *self, struct cmd_q *cmdq) struct client *c = cmdq->client; struct session *s; struct paste_buffer *pb; - const char *path, *bufname; - char *start, *end, *msg; - size_t size, used, msglen; + const char *path, *bufname, *bufdata, *start, *end; + char *msg; + size_t size, used, msglen, bufsize; int cwd, fd; FILE *f; if (!args_has(args, 'b')) { - if ((pb = paste_get_top()) == NULL) { + if ((pb = paste_get_top(NULL)) == NULL) { cmdq_error(cmdq, "no buffers"); return (CMD_RETURN_ERROR); } @@ -75,6 +75,7 @@ cmd_save_buffer_exec(struct cmd *self, struct cmd_q *cmdq) return (CMD_RETURN_ERROR); } } + bufdata = paste_buffer_data(pb, &bufsize); if (self->entry == &cmd_show_buffer_entry) path = "-"; @@ -113,7 +114,7 @@ cmd_save_buffer_exec(struct cmd *self, struct cmd_q *cmdq) cmdq_error(cmdq, "%s: %s", path, strerror(errno)); return (CMD_RETURN_ERROR); } - if (fwrite(pb->data, 1, pb->size, f) != pb->size) { + if (fwrite(bufdata, 1, bufsize, f) != bufsize) { cmdq_error(cmdq, "%s: fwrite error", path); fclose(f); return (CMD_RETURN_ERROR); @@ -123,25 +124,25 @@ cmd_save_buffer_exec(struct cmd *self, struct cmd_q *cmdq) return (CMD_RETURN_NORMAL); do_stdout: - evbuffer_add(c->stdout_data, pb->data, pb->size); + evbuffer_add(c->stdout_data, bufdata, bufsize); server_push_stdout(c); return (CMD_RETURN_NORMAL); do_print: - if (pb->size > (INT_MAX / 4) - 1) { + if (bufsize > (INT_MAX / 4) - 1) { cmdq_error(cmdq, "buffer too big"); return (CMD_RETURN_ERROR); } msg = NULL; used = 0; - while (used != pb->size) { - start = pb->data + used; - end = memchr(start, '\n', pb->size - used); + while (used != bufsize) { + start = bufdata + used; + end = memchr(start, '\n', bufsize - used); if (end != NULL) size = end - start; else - size = pb->size - used; + size = bufsize - used; msglen = size * 4 + 1; msg = xrealloc(msg, msglen); diff --git a/cmd-set-buffer.c b/cmd-set-buffer.c index 0ec362b3..4fa7ca11 100644 --- a/cmd-set-buffer.c +++ b/cmd-set-buffer.c @@ -42,9 +42,9 @@ cmd_set_buffer_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; struct paste_buffer *pb; - char *pdata, *cause; - const char *bufname; - size_t psize, newsize; + char *bufdata, *cause; + const char *bufname, *olddata; + size_t bufsize, newsize; bufname = NULL; @@ -58,12 +58,11 @@ cmd_set_buffer_exec(struct cmd *self, struct cmd_q *cmdq) bufname = args_get(args, 'b'); if (bufname == NULL) { - pb = paste_get_top(); + pb = paste_get_top(&bufname); if (pb == NULL) { cmdq_error(cmdq, "no buffer"); return (CMD_RETURN_ERROR); } - bufname = pb->name; } if (paste_rename(bufname, args_get(args, 'n'), &cause) != 0) { @@ -79,37 +78,33 @@ cmd_set_buffer_exec(struct cmd *self, struct cmd_q *cmdq) cmdq_error(cmdq, "no data specified"); return (CMD_RETURN_ERROR); } - - psize = 0; - pdata = NULL; - pb = NULL; + bufsize = 0; + bufdata = NULL; + if ((newsize = strlen(args->argv[0])) == 0) return (CMD_RETURN_NORMAL); if (args_has(args, 'b')) { bufname = args_get(args, 'b'); pb = paste_get_name(bufname); - } else if (args_has(args, 'a')) { - pb = paste_get_top(); - if (pb != NULL) - bufname = pb->name; - } + } else if (args_has(args, 'a')) + pb = paste_get_top(&bufname); if (args_has(args, 'a') && pb != NULL) { - psize = pb->size; - pdata = xmalloc(psize); - memcpy(pdata, pb->data, psize); + olddata = paste_buffer_data(pb, &bufsize); + bufdata = xmalloc(bufsize); + memcpy(bufdata, olddata, bufsize); } - pdata = xrealloc(pdata, psize + newsize); - memcpy(pdata + psize, args->argv[0], newsize); - psize += newsize; + bufdata = xrealloc(bufdata, bufsize + newsize); + memcpy(bufdata + bufsize, args->argv[0], newsize); + bufsize += newsize; - if (paste_set(pdata, psize, bufname, &cause) != 0) { + if (paste_set(bufdata, bufsize, bufname, &cause) != 0) { cmdq_error(cmdq, "%s", cause); - free(pdata); + free(bufdata); free(cause); return (CMD_RETURN_ERROR); } diff --git a/cmd-set-option.c b/cmd-set-option.c index 56ca91e0..98ab2513 100644 --- a/cmd-set-option.c +++ b/cmd-set-option.c @@ -180,14 +180,14 @@ cmd_set_option_exec(struct cmd *self, struct cmd_q *cmdq) if (strcmp(oe->name, "automatic-rename") == 0) { RB_FOREACH(w, windows, &windows) { if (options_get_number(&w->options, "automatic-rename")) - queue_window_name(w); - else if (event_initialized(&w->name_timer)) - evtimer_del(&w->name_timer); + w->active->flags |= PANE_CHANGED; } } if (strcmp(oe->name, "status") == 0 || strcmp(oe->name, "status-interval") == 0) status_timer_start_all(); + if (strcmp(oe->name, "monitor-silence") == 0) + alerts_reset_all(); /* Update sizes and redraw. May not need it but meh. */ recalculate_sizes(); diff --git a/cmd-show-environment.c b/cmd-show-environment.c index a61cf3f4..af24d91b 100644 --- a/cmd-show-environment.c +++ b/cmd-show-environment.c @@ -56,7 +56,7 @@ cmd_show_environment_escape(struct environ_entry *envent) } *out = '\0'; - return ret; + return (ret); } void diff --git a/cmd-swap-pane.c b/cmd-swap-pane.c index c4751c36..dc2b7246 100644 --- a/cmd-swap-pane.c +++ b/cmd-swap-pane.c @@ -58,12 +58,10 @@ cmd_swap_pane_exec(struct cmd *self, struct cmd_q *cmdq) src_wp = TAILQ_NEXT(dst_wp, entry); if (src_wp == NULL) src_wp = TAILQ_FIRST(&dst_w->panes); - src_wl = dst_wl; } else if (args_has(self->args, 'U')) { src_wp = TAILQ_PREV(dst_wp, window_panes, entry); if (src_wp == NULL) src_wp = TAILQ_LAST(&dst_w->panes, window_panes); - src_wl = dst_wl; } else { src_wl = cmd_find_pane_marked(cmdq, NULL, NULL, &src_wp); @@ -36,14 +36,27 @@ * string. */ +struct format_entry; +typedef void (*format_cb)(struct format_tree *, struct format_entry *); + void format_job_callback(struct job *); const char *format_job_get(struct format_tree *, const char *); void format_job_timer(int, short, void *); +void format_cb_host(struct format_tree *, struct format_entry *); +void format_cb_host_short(struct format_tree *, struct format_entry *); +void format_cb_pid(struct format_tree *, struct format_entry *); +void format_cb_session_alerts(struct format_tree *, struct format_entry *); +void format_cb_window_layout(struct format_tree *, struct format_entry *); +void format_cb_start_command(struct format_tree *, struct format_entry *); +void format_cb_current_command(struct format_tree *, struct format_entry *); +void format_cb_history_bytes(struct format_tree *, struct format_entry *); +void format_cb_pane_tabs(struct format_tree *, struct format_entry *); + +void format_add_cb(struct format_tree *, const char *, format_cb); int format_replace(struct format_tree *, const char *, size_t, char **, size_t *, size_t *); char *format_time_string(time_t); -char *format_get_command(struct window_pane *); void format_defaults_pane_tabs(struct format_tree *, struct window_pane *); void format_defaults_session(struct format_tree *, struct session *); @@ -80,18 +93,19 @@ format_job_cmp(struct format_job *fj1, struct format_job *fj2) /* Entry in format tree. */ struct format_entry { - char *key; - char *value; - - RB_ENTRY(format_entry) entry; + char *key; + char *value; + format_cb cb; + RB_ENTRY(format_entry) entry; }; /* Format entry tree. */ struct format_tree { - struct window *w; - struct session *s; + struct window *w; + struct session *s; + struct window_pane *wp; - int status; + int status; RB_HEAD(format_entry_tree, format_entry) tree; }; @@ -258,6 +272,170 @@ format_job_timer(unused int fd, unused short events, unused void *arg) evtimer_add(&format_job_event, &tv); } +/* Callback for host. */ +void +format_cb_host(unused struct format_tree *ft, struct format_entry *fe) +{ + char host[HOST_NAME_MAX + 1]; + + if (gethostname(host, sizeof host) != 0) + fe->value = xstrdup(""); + else + fe->value = xstrdup(host); +} + +/* Callback for host_short. */ +void +format_cb_host_short(unused struct format_tree *ft, struct format_entry *fe) +{ + char host[HOST_NAME_MAX + 1], *cp; + + if (gethostname(host, sizeof host) != 0) + fe->value = xstrdup(""); + else { + if ((cp = strchr(host, '.')) != NULL) + *cp = '\0'; + fe->value = xstrdup(host); + } +} + +/* Callback for pid. */ +void +format_cb_pid(unused struct format_tree *ft, struct format_entry *fe) +{ + xasprintf(&fe->value, "%ld", (long)getpid()); +} + +/* Callback for session_alerts. */ +void +format_cb_session_alerts(struct format_tree *ft, struct format_entry *fe) +{ + struct session *s = ft->s; + struct winlink *wl; + char alerts[256], tmp[16]; + + if (s == NULL) + return; + + *alerts = '\0'; + RB_FOREACH(wl, winlinks, &s->windows) { + if ((wl->flags & WINLINK_ALERTFLAGS) == 0) + continue; + xsnprintf(tmp, sizeof tmp, "%u", wl->idx); + + if (*alerts != '\0') + strlcat(alerts, ",", sizeof alerts); + strlcat(alerts, tmp, sizeof alerts); + if (wl->flags & WINLINK_ACTIVITY) + strlcat(alerts, "#", sizeof alerts); + if (wl->flags & WINLINK_BELL) + strlcat(alerts, "!", sizeof alerts); + if (wl->flags & WINLINK_SILENCE) + strlcat(alerts, "~", sizeof alerts); + } + fe->value = xstrdup(alerts); +} + +/* Callback for window_layout. */ +void +format_cb_window_layout(struct format_tree *ft, struct format_entry *fe) +{ + struct window *w = ft->w; + + if (w == NULL) + return; + + if (w->saved_layout_root != NULL) + fe->value = layout_dump(w->saved_layout_root); + else + fe->value = layout_dump(w->layout_root); +} + +/* Callback for pane_start_command. */ +void +format_cb_start_command(struct format_tree *ft, struct format_entry *fe) +{ + struct window_pane *wp = ft->wp; + + if (wp == NULL) + return; + + fe->value = cmd_stringify_argv(wp->argc, wp->argv); +} + +/* Callback for pane_current_command. */ +void +format_cb_current_command(struct format_tree *ft, struct format_entry *fe) +{ + struct window_pane *wp = ft->wp; + char *cmd; + + if (wp == NULL) + return; + + cmd = get_proc_name(wp->fd, wp->tty); + if (cmd == NULL || *cmd == '\0') { + free(cmd); + cmd = cmd_stringify_argv(wp->argc, wp->argv); + if (cmd == NULL || *cmd == '\0') { + free(cmd); + cmd = xstrdup(wp->shell); + } + } + fe->value = parse_window_name(cmd); + free(cmd); +} + +/* Callback for history_bytes. */ +void +format_cb_history_bytes(struct format_tree *ft, struct format_entry *fe) +{ + struct window_pane *wp = ft->wp; + struct grid *gd; + struct grid_line *gl; + unsigned long long size; + u_int i; + + if (wp == NULL) + return; + gd = wp->base.grid; + + size = 0; + for (i = 0; i < gd->hsize; i++) { + gl = &gd->linedata[i]; + size += gl->cellsize * sizeof *gl->celldata; + } + size += gd->hsize * sizeof *gd->linedata; + + xasprintf(&fe->value, "%llu", size); +} + +/* Callback for pane_tabs. */ +void +format_cb_pane_tabs(struct format_tree *ft, struct format_entry *fe) +{ + struct window_pane *wp = ft->wp; + struct evbuffer *buffer; + u_int i; + int size; + + if (wp == NULL) + return; + + buffer = evbuffer_new(); + for (i = 0; i < wp->base.grid->sx; i++) { + if (!bit_test(wp->base.tabs, i)) + continue; + + if (EVBUFFER_LENGTH(buffer) > 0) + evbuffer_add(buffer, ",", 1); + evbuffer_add_printf(buffer, "%u", i); + } + size = EVBUFFER_LENGTH(buffer); + xasprintf(&fe->value, "%.*s", size, EVBUFFER_DATA(buffer)); + evbuffer_free(buffer); +} + /* Create a new tree. */ struct format_tree * format_create(void) @@ -270,7 +448,6 @@ struct format_tree * format_create_status(int status) { struct format_tree *ft; - char host[HOST_NAME_MAX + 1], *ptr; if (!event_initialized(&format_job_event)) { evtimer_set(&format_job_event, format_job_timer, NULL); @@ -281,13 +458,9 @@ format_create_status(int status) RB_INIT(&ft->tree); ft->status = status; - if (gethostname(host, sizeof host) == 0) { - format_add(ft, "host", "%s", host); - if ((ptr = strchr(host, '.')) != NULL) - *ptr = '\0'; - format_add(ft, "host_short", "%s", host); - } - format_add(ft, "pid", "%ld", (long) getpid()); + format_add_cb(ft, "host", format_cb_host); + format_add_cb(ft, "host_short", format_cb_host_short); + format_add_cb(ft, "pid", format_cb_pid); return (ft); } @@ -319,17 +492,42 @@ format_add(struct format_tree *ft, const char *key, const char *fmt, ...) fe = xmalloc(sizeof *fe); fe->key = xstrdup(key); + fe_now = RB_INSERT(format_entry_tree, &ft->tree, fe); + if (fe_now != NULL) { + free(fe->key); + free(fe); + free(fe_now->value); + fe = fe_now; + } + + fe->cb = NULL; + va_start(ap, fmt); xvasprintf(&fe->value, fmt, ap); va_end(ap); +} + +/* Add a key and function. */ +void +format_add_cb(struct format_tree *ft, const char *key, format_cb cb) +{ + struct format_entry *fe; + struct format_entry *fe_now; + + fe = xmalloc(sizeof *fe); + fe->key = xstrdup(key); fe_now = RB_INSERT(format_entry_tree, &ft->tree, fe); if (fe_now != NULL) { - free(fe_now->value); - fe_now->value = fe->value; free(fe->key); free(fe); + free(fe_now->value); + fe = fe_now; } + + fe->cb = cb; + + fe->value = NULL; } /* Find a format entry. */ @@ -364,8 +562,11 @@ format_find(struct format_tree *ft, const char *key) fe_find.key = (char *) key; fe = RB_FIND(format_entry_tree, &ft->tree, &fe_find); - if (fe != NULL) + if (fe != NULL) { + if (fe->value == NULL && fe->cb != NULL) + fe->cb(ft, fe); return (fe->value); + } envent = NULL; if (ft->s != NULL) @@ -507,7 +708,7 @@ char * format_expand(struct format_tree *ft, const char *fmt) { char *buf, *tmp, *cmd; - const char *ptr, *s; + const char *ptr, *s, *saved = fmt; size_t off, len, n, slen; int ch, brackets; @@ -611,29 +812,10 @@ format_expand(struct format_tree *ft, const char *fmt) } buf[off] = '\0'; + log_debug("format '%s' -> '%s'", saved, buf); return (buf); } -/* Get command name for format. */ -char * -format_get_command(struct window_pane *wp) -{ - char *cmd, *out; - - cmd = osdep_get_name(wp->fd, wp->tty); - if (cmd == NULL || *cmd == '\0') { - free(cmd); - cmd = cmd_stringify_argv(wp->argc, wp->argv); - if (cmd == NULL || *cmd == '\0') { - free(cmd); - cmd = xstrdup(wp->shell); - } - } - out = parse_window_name(cmd); - free(cmd); - return (out); -} - /* Get time as a string. */ char * format_time_string(time_t t) @@ -674,8 +856,6 @@ format_defaults_session(struct format_tree *ft, struct session *s) { struct session_group *sg; time_t t; - struct winlink *wl; - char alerts[256], tmp[16]; ft->s = s; @@ -701,23 +881,7 @@ format_defaults_session(struct format_tree *ft, struct session *s) format_add(ft, "session_attached", "%u", s->attached); format_add(ft, "session_many_attached", "%d", s->attached > 1); - *alerts = '\0'; - RB_FOREACH (wl, winlinks, &s->windows) { - if ((wl->flags & WINLINK_ALERTFLAGS) == 0) - continue; - xsnprintf(tmp, sizeof tmp, "%u", wl->idx); - - if (*alerts != '\0') - strlcat(alerts, ",", sizeof alerts); - strlcat(alerts, tmp, sizeof alerts); - if (wl->flags & WINLINK_ACTIVITY) - strlcat(alerts, "#", sizeof alerts); - if (wl->flags & WINLINK_BELL) - strlcat(alerts, "!", sizeof alerts); - if (wl->flags & WINLINK_SILENCE) - strlcat(alerts, "~", sizeof alerts); - } - format_add(ft, "session_alerts", "%s", alerts); + format_add_cb(ft, "session_alerts", format_cb_session_alerts); } /* Set default format keys for a client. */ @@ -776,16 +940,10 @@ format_defaults_client(struct format_tree *ft, struct client *c) void format_defaults_window(struct format_tree *ft, struct window *w) { - char *layout; time_t t; ft->w = w; - if (w->saved_layout_root != NULL) - layout = layout_dump(w->saved_layout_root); - else - layout = layout_dump(w->layout_root); - t = w->activity_time.tv_sec; format_add(ft, "window_activity", "%lld", (long long) t); format_add(ft, "window_activity_string", "%s", format_time_string(t)); @@ -794,12 +952,10 @@ format_defaults_window(struct format_tree *ft, struct window *w) format_add(ft, "window_name", "%s", w->name); format_add(ft, "window_width", "%u", w->sx); format_add(ft, "window_height", "%u", w->sy); - format_add(ft, "window_layout", "%s", layout); + format_add_cb(ft, "window_layout", format_cb_window_layout); format_add(ft, "window_panes", "%u", window_count_panes(w)); format_add(ft, "window_zoomed_flag", "%d", !!(w->flags & WINDOW_ZOOMED)); - - free(layout); } /* Set default format keys for a winlink. */ @@ -834,51 +990,21 @@ format_defaults_winlink(struct format_tree *ft, struct session *s, free(flags); } -/* Add window pane tabs. */ -void -format_defaults_pane_tabs(struct format_tree *ft, struct window_pane *wp) -{ - struct evbuffer *buffer; - u_int i; - - buffer = evbuffer_new(); - for (i = 0; i < wp->base.grid->sx; i++) { - if (!bit_test(wp->base.tabs, i)) - continue; - - if (EVBUFFER_LENGTH(buffer) > 0) - evbuffer_add(buffer, ",", 1); - evbuffer_add_printf(buffer, "%u", i); - } - - format_add(ft, "pane_tabs", "%.*s", (int) EVBUFFER_LENGTH(buffer), - EVBUFFER_DATA(buffer)); - evbuffer_free(buffer); -} - /* Set default format keys for a window pane. */ void format_defaults_pane(struct format_tree *ft, struct window_pane *wp) { - struct grid *gd = wp->base.grid; - struct grid_line *gl; - unsigned long long size; - u_int i, idx; - char *cmd, *cwd; - int status; + struct grid *gd = wp->base.grid; + u_int idx; + int status; if (ft->w == NULL) ft->w = wp->window; + ft->wp = wp; - size = 0; - for (i = 0; i < gd->hsize; i++) { - gl = &gd->linedata[i]; - size += gl->cellsize * sizeof *gl->celldata; - } - size += gd->hsize * sizeof *gd->linedata; format_add(ft, "history_size", "%u", gd->hsize); format_add(ft, "history_limit", "%u", gd->hlimit); - format_add(ft, "history_bytes", "%llu", size); + format_add_cb(ft, "history_bytes", format_cb_history_bytes); if (window_pane_index(wp, &idx) != 0) fatalx("index not found"); @@ -909,16 +1035,8 @@ format_defaults_pane(struct format_tree *ft, struct window_pane *wp) format_add(ft, "pane_tty", "%s", wp->tty); format_add(ft, "pane_pid", "%ld", (long) wp->pid); - if ((cwd = osdep_get_cwd(wp->fd)) != NULL) - format_add(ft, "pane_current_path", "%s", cwd); - if ((cmd = cmd_stringify_argv(wp->argc, wp->argv)) != NULL) { - format_add(ft, "pane_start_command", "%s", cmd); - free(cmd); - } - if ((cmd = format_get_command(wp)) != NULL) { - format_add(ft, "pane_current_command", "%s", cmd); - free(cmd); - } + format_add_cb(ft, "pane_start_command", format_cb_start_command); + format_add_cb(ft, "pane_current_command", format_cb_current_command); format_add(ft, "cursor_x", "%u", wp->base.cx); format_add(ft, "cursor_y", "%u", wp->base.cy); @@ -949,7 +1067,7 @@ format_defaults_pane(struct format_tree *ft, struct window_pane *wp) format_add(ft, "mouse_utf8_flag", "%d", !!(wp->base.mode & MODE_MOUSE_UTF8)); - format_defaults_pane_tabs(ft, wp); + format_add_cb(ft, "pane_tabs", format_cb_pane_tabs); } /* Set default format keys for paste buffer. */ @@ -957,10 +1075,12 @@ void format_defaults_paste_buffer(struct format_tree *ft, struct paste_buffer *pb, int utf8flag) { + size_t bufsize; char *s; - format_add(ft, "buffer_size", "%zu", pb->size); - format_add(ft, "buffer_name", "%s", pb->name); + paste_buffer_data(pb, &bufsize); + format_add(ft, "buffer_size", "%zu", bufsize); + format_add(ft, "buffer_name", "%s", paste_buffer_name(pb)); s = paste_make_sample(pb, utf8flag); format_add(ft, "buffer_sample", "%s", s); @@ -844,14 +844,9 @@ input_parse(struct window_pane *wp) if (EVBUFFER_LENGTH(evb) == 0) return; + window_update_activity(wp->window); wp->flags |= PANE_CHANGED; - wp->window->flags |= WINDOW_ACTIVITY; - wp->window->flags &= ~WINDOW_SILENCE; - - if (gettimeofday(&wp->window->activity_time, NULL) != 0) - fatal("gettimeofday failed"); - /* * Open the screen. Use NULL wp if there is a mode set as don't want to * update the tty. @@ -1081,7 +1076,7 @@ input_c0_dispatch(struct input_ctx *ictx) case '\000': /* NUL */ break; case '\007': /* BEL */ - wp->window->flags |= WINDOW_BELL; + alerts_queue(wp->window, WINDOW_BELL); break; case '\010': /* BS */ screen_write_backspace(sctx); diff --git a/layout-set.c b/layout-set.c index 64b655a0..da94cff2 100644 --- a/layout-set.c +++ b/layout-set.c @@ -44,12 +44,6 @@ const struct { { "tiled", layout_set_tiled }, }; -const char * -layout_set_name(u_int layout) -{ - return (layout_sets[layout].name); -} - int layout_set_lookup(const char *name) { @@ -67,14 +67,15 @@ log_close(void) void log_vwrite(const char *msg, va_list ap) { - char *fmt; - time_t t; + char *fmt; + struct timeval tv; if (log_file == NULL) return; - t = time(NULL); - if (asprintf(&fmt, "%lld %s\n", (long long)t, msg) == -1) + gettimeofday(&tv, NULL); + if (asprintf(&fmt, "%lld.%06d %s\n", (long long)tv.tv_sec, + (int)tv.tv_usec, msg) == -1) exit(1); if (vfprintf(log_file, fmt, ap) == -1) exit(1); @@ -25,47 +25,76 @@ #include "tmux.h" -void window_name_callback(unused int, unused short, void *); +void name_time_callback(int, short, void *); +int name_time_expired(struct window *, struct timeval *); void -queue_window_name(struct window *w) +name_time_callback(unused int fd, unused short events, void *arg) { - struct timeval tv; + struct window *w = arg; - tv.tv_sec = 0; - tv.tv_usec = NAME_INTERVAL * 1000L; + /* The event loop will call check_window_name for us on the way out. */ + log_debug("@%u name timer expired", w->id); +} + +int +name_time_expired(struct window *w, struct timeval *tv) +{ + struct timeval offset; - if (event_initialized(&w->name_timer)) - evtimer_del(&w->name_timer); - evtimer_set(&w->name_timer, window_name_callback, w); - evtimer_add(&w->name_timer, &tv); + timersub(tv, &w->name_time, &offset); + if (offset.tv_sec != 0 || offset.tv_usec > NAME_INTERVAL) + return (0); + return (NAME_INTERVAL - offset.tv_usec); } void -window_name_callback(unused int fd, unused short events, void *data) +check_window_name(struct window *w) { - struct window *w = data; + struct timeval tv, next; char *name; + int left; if (w->active == NULL) return; - if (!options_get_number(&w->options, "automatic-rename")) { - if (event_initialized(&w->name_timer)) - event_del(&w->name_timer); + if (!options_get_number(&w->options, "automatic-rename")) return; - } - queue_window_name(w); - if (~w->active->flags & PANE_CHANGED) + if (~w->active->flags & PANE_CHANGED) { + log_debug("@%u active pane not changed", w->id); + return; + } + log_debug("@%u active pane changed", w->id); + + gettimeofday(&tv, NULL); + left = name_time_expired(w, &tv); + if (left != 0) { + if (!event_initialized(&w->name_event)) + evtimer_set(&w->name_event, name_time_callback, w); + if (!evtimer_pending(&w->name_event, NULL)) { + log_debug("@%u name timer queued (%d left)", w->id, left); + timerclear(&next); + next.tv_usec = left; + event_add(&w->name_event, &next); + } else + log_debug("@%u name timer already queued (%d left)", w->id, left); return; + } + memcpy(&w->name_time, &tv, sizeof w->name_time); + if (event_initialized(&w->name_event)) + evtimer_del(&w->name_event); + w->active->flags &= ~PANE_CHANGED; name = format_window_name(w); if (strcmp(name, w->name) != 0) { + log_debug("@%u new name %s (was %s)", w->id, name, w->name); window_set_name(w, name); server_status_window(w); - } + } else + log_debug("@%u name not changed (still %s)", w->id, w->name); + free(name); } @@ -29,6 +29,18 @@ * string! */ +struct paste_buffer { + char *data; + size_t size; + + char *name; + int automatic; + u_int order; + + RB_ENTRY(paste_buffer) name_entry; + RB_ENTRY(paste_buffer) time_entry; +}; + u_int paste_next_index; u_int paste_next_order; u_int paste_num_automatic; @@ -59,6 +71,22 @@ paste_cmp_times(const struct paste_buffer *a, const struct paste_buffer *b) return (0); } +/* Get paste buffer name. */ +const char * +paste_buffer_name(struct paste_buffer *pb) +{ + return (pb->name); +} + +/* Get paste buffer data. */ +const char * +paste_buffer_data(struct paste_buffer *pb, size_t *size) +{ + if (size != NULL) + *size = pb->size; + return (pb->data); +} + /* Walk paste buffers by name. */ struct paste_buffer * paste_walk(struct paste_buffer *pb) @@ -70,13 +98,15 @@ paste_walk(struct paste_buffer *pb) /* Get the most recent automatic buffer. */ struct paste_buffer * -paste_get_top(void) +paste_get_top(const char **name) { struct paste_buffer *pb; pb = RB_MIN(paste_time_tree, &paste_by_time); if (pb == NULL) return (NULL); + if (name != NULL) + *name = pb->name; return (pb); } @@ -86,7 +116,7 @@ paste_free_top(void) { struct paste_buffer *pb; - pb = paste_get_top(); + pb = paste_get_top(NULL); if (pb == NULL) return (-1); return (paste_free_name(pb->name)); @@ -288,32 +318,3 @@ paste_make_sample(struct paste_buffer *pb, int utf8flag) strlcpy(buf + width, "...", 4); return (buf); } - -/* Paste into a window pane, filtering '\n' according to separator. */ -void -paste_send_pane(struct paste_buffer *pb, struct window_pane *wp, - const char *sep, int bracket) -{ - const char *data = pb->data, *end = data + pb->size, *lf; - size_t seplen; - - if (wp->flags & PANE_INPUTOFF) - return; - - if (bracket && (wp->screen->mode & MODE_BRACKETPASTE)) - bufferevent_write(wp->event, "\033[200~", 6); - - seplen = strlen(sep); - while ((lf = memchr(data, '\n', end - data)) != NULL) { - if (lf != data) - bufferevent_write(wp->event, data, lf - data); - bufferevent_write(wp->event, sep, seplen); - data = lf + 1; - } - - if (end != data) - bufferevent_write(wp->event, data, end - data); - - if (bracket && (wp->screen->mode & MODE_BRACKETPASTE)) - bufferevent_write(wp->event, "\033[201~", 6); -} @@ -32,14 +32,8 @@ void screen_resize_y(struct screen *, u_int); void screen_init(struct screen *s, u_int sx, u_int sy, u_int hlimit) { - char host[HOST_NAME_MAX+1]; - s->grid = grid_create(sx, sy, hlimit); - - if (gethostname(host, sizeof(host)) == 0) - s->title = xstrdup(host); - else - s->title = xstrdup(""); + s->title = xstrdup(""); s->cstyle = 0; s->ccolour = xstrdup(""); diff --git a/server-client.c b/server-client.c index 1faf5968..632c5f99 100644 --- a/server-client.c +++ b/server-client.c @@ -550,13 +550,6 @@ server_client_handle_key(struct client *c, int key) w = s->curw->window; wp = w->active; - /* No session, do nothing. */ - if (c->session == NULL) - return; - s = c->session; - w = c->session->curw->window; - wp = w->active; - /* Update the activity timer. */ if (gettimeofday(&c->activity_time, NULL) != 0) fatal("gettimeofday failed"); @@ -716,6 +709,7 @@ server_client_loop(void) } wp->flags &= ~PANE_REDRAW; } + check_window_name(w); } } @@ -251,9 +251,10 @@ void server_loop(void) { while (!server_should_shutdown()) { + log_debug("event dispatch enter"); event_loop(EVLOOP_ONCE); + log_debug("event dispatch exit"); - server_window_loop(); server_client_loop(); } } @@ -518,6 +518,7 @@ session_set_current(struct session *s, struct winlink *wl) winlink_stack_push(&s->lastw, s->curw); s->curw = wl; winlink_clear_flags(wl); + window_update_activity(wl->window); return (0); } @@ -815,10 +815,9 @@ status_prompt_key(struct client *c, int key) struct options *oo = &sess->options; struct paste_buffer *pb; char *s, *first, *last, word[64], swapc; - const char *histstr; - const char *wsep = NULL; + const char *histstr, *bufdata, *wsep = NULL; u_char ch; - size_t size, n, off, idx; + size_t size, n, off, idx, bufsize; size = strlen(c->prompt_buffer); switch (mode_key_lookup(&c->prompt_mdata, key, NULL)) { @@ -1067,24 +1066,25 @@ status_prompt_key(struct client *c, int key) c->flags |= CLIENT_STATUS; break; case MODEKEYEDIT_PASTE: - if ((pb = paste_get_top()) == NULL) + if ((pb = paste_get_top(NULL)) == NULL) break; - for (n = 0; n < pb->size; n++) { - ch = (u_char) pb->data[n]; + bufdata = paste_buffer_data(pb, &bufsize); + for (n = 0; n < bufsize; n++) { + ch = (u_char)bufdata[n]; if (ch < 32 || ch == 127) break; } c->prompt_buffer = xrealloc(c->prompt_buffer, size + n + 1); if (c->prompt_index == size) { - memcpy(c->prompt_buffer + c->prompt_index, pb->data, n); + memcpy(c->prompt_buffer + c->prompt_index, bufdata, n); c->prompt_index += n; c->prompt_buffer[c->prompt_index] = '\0'; } else { memmove(c->prompt_buffer + c->prompt_index + n, c->prompt_buffer + c->prompt_index, size + 1 - c->prompt_index); - memcpy(c->prompt_buffer + c->prompt_index, pb->data, n); + memcpy(c->prompt_buffer + c->prompt_index, bufdata, n); c->prompt_index += n; } @@ -200,7 +200,7 @@ shell_exec(const char *shell, const char *shellcmd) fatal("execl failed"); } -const char* +const char * find_home(void) { struct passwd *pw; @@ -215,7 +215,7 @@ find_home(void) home = NULL; } - return home; + return (home); } int @@ -51,8 +51,8 @@ extern char **environ; */ #define PANE_MINIMUM 2 -/* Automatic name refresh interval, in milliseconds. */ -#define NAME_INTERVAL 500 +/* Automatic name refresh interval, in microseconds. Must be < 1 second. */ +#define NAME_INTERVAL 500000 /* * UTF-8 data size. This must be big enough to hold combined characters as well @@ -873,9 +873,13 @@ RB_HEAD(window_pane_tree, window_pane); /* Window structure. */ struct window { u_int id; + char *name; - struct event name_timer; - struct timeval silence_timer; + struct event name_event; + struct timeval name_time; + + struct event alerts_timer; + struct timeval activity_time; struct window_pane *active; @@ -957,19 +961,6 @@ struct layout_cell { TAILQ_ENTRY(layout_cell) entry; }; -/* Paste buffer. */ -struct paste_buffer { - char *data; - size_t size; - - char *name; - int automatic; - u_int order; - - RB_ENTRY(paste_buffer) name_entry; - RB_ENTRY(paste_buffer) time_entry; -}; - /* Environment variable. */ struct environ_entry { char *name; @@ -1270,13 +1261,8 @@ struct client { TAILQ_HEAD(clients, client); /* Parsed arguments structures. */ -struct args_entry { - u_char flag; - char *value; - RB_ENTRY(args_entry) entry; -}; +struct args_entry; RB_HEAD(args_tree, args_entry); - struct args { struct args_tree tree; int argc; @@ -1452,6 +1438,20 @@ void cfg_add_cause(const char *, ...); void cfg_print_causes(struct cmd_q *); void cfg_show_causes(struct session *); +/* paste.c */ +struct paste_buffer; +const char *paste_buffer_name(struct paste_buffer *); +const char *paste_buffer_data(struct paste_buffer *, size_t *); +struct paste_buffer *paste_walk(struct paste_buffer *); +struct paste_buffer *paste_get_top(const char **); +struct paste_buffer *paste_get_name(const char *); +int paste_free_top(void); +int paste_free_name(const char *); +void paste_add(char *, size_t); +int paste_rename(const char *, const char *, char **); +int paste_set(char *, size_t, const char *, char **); +char *paste_make_sample(struct paste_buffer *, int); + /* format.c */ struct format_tree; struct format_tree *format_create(void); @@ -1636,19 +1636,6 @@ void tty_keys_build(struct tty *); void tty_keys_free(struct tty *); int tty_keys_next(struct tty *); -/* paste.c */ -struct paste_buffer *paste_walk(struct paste_buffer *); -struct paste_buffer *paste_get_top(void); -struct paste_buffer *paste_get_name(const char *); -int paste_free_top(void); -int paste_free_name(const char *); -void paste_add(char *, size_t); -int paste_rename(const char *, const char *, char **); -int paste_set(char *, size_t, const char *, char **); -char *paste_make_sample(struct paste_buffer *, int); -void paste_send_pane(struct paste_buffer *, struct window_pane *, - const char *, int); - /* arguments.c */ int args_cmp(struct args_entry *, struct args_entry *); RB_PROTOTYPE(args_tree, args_entry, entry, args_cmp); @@ -1830,6 +1817,10 @@ void key_bindings_dispatch(struct key_binding *, struct client *, int key_string_lookup_string(const char *); const char *key_string_lookup_key(int); +/* alerts.c */ +void alerts_reset_all(void); +void alerts_queue(struct window *, int); + /* server.c */ extern struct clients clients; extern struct clients dead_clients; @@ -1854,12 +1845,8 @@ int server_client_open(struct client *, char **); void server_client_unref(struct client *); void server_client_lost(struct client *); void server_client_callback(int, short, void *); -void server_client_status_timer(void); void server_client_loop(void); -/* server-window.c */ -void server_window_loop(void); - /* server-fn.c */ void server_fill_environ(struct session *, struct environ *); void server_write_ready(struct client *); @@ -1879,7 +1866,6 @@ void server_status_window(struct window *); void server_lock(void); void server_lock_session(struct session *); void server_lock_client(struct client *); -int server_unlock(const char *); void server_kill_window(struct window *); int server_link_window(struct session *, struct winlink *, struct session *, int, int, int, char **); @@ -2029,7 +2015,6 @@ void screen_write_cursormove(struct screen_write_ctx *, u_int, u_int); void screen_write_reverseindex(struct screen_write_ctx *); void screen_write_scrollregion(struct screen_write_ctx *, u_int, u_int); void screen_write_linefeed(struct screen_write_ctx *, int); -void screen_write_linefeedscreen(struct screen_write_ctx *, int); void screen_write_carriagereturn(struct screen_write_ctx *); void screen_write_clearendofscreen(struct screen_write_ctx *); void screen_write_clearstartofscreen(struct screen_write_ctx *); @@ -2085,13 +2070,13 @@ void winlink_stack_push(struct winlink_stack *, struct winlink *); void winlink_stack_remove(struct winlink_stack *, struct winlink *); struct window *window_find_by_id_str(const char *); struct window *window_find_by_id(u_int); +void window_update_activity(struct window *); struct window *window_create1(u_int, u_int); struct window *window_create(const char *, int, char **, const char *, const char *, int, struct environ *, struct termios *, u_int, u_int, u_int, char **); void window_destroy(struct window *); struct window_pane *window_get_active_at(struct window *, u_int, u_int); -void window_set_active_at(struct window *, u_int, u_int); struct window_pane *window_find_string(struct window *, const char *); int window_has_pane(struct window *, struct window_pane *); int window_set_active_pane(struct window *, struct window_pane *); @@ -2172,12 +2157,10 @@ char *layout_dump(struct layout_cell *); int layout_parse(struct window *, const char *); /* layout-set.c */ -const char *layout_set_name(u_int); int layout_set_lookup(const char *); u_int layout_set_select(struct window *, u_int); u_int layout_set_next(struct window *); u_int layout_set_previous(struct window *); -void layout_set_active_changed(struct window *); /* window-clock.c */ extern const struct window_mode window_clock_mode; @@ -2213,7 +2196,7 @@ void window_choose_collapse_all(struct window_pane *); void window_choose_set_current(struct window_pane *, u_int); /* names.c */ -void queue_window_name(struct window *); +void check_window_name(struct window *); char *default_window_name(struct window *); char *format_window_name(struct window *); char *parse_window_name(const char *); diff --git a/window-copy.c b/window-copy.c index 850b437a..460dd10b 100644 --- a/window-copy.c +++ b/window-copy.c @@ -782,7 +782,8 @@ window_copy_key_input(struct window_pane *wp, int key) { struct window_copy_mode_data *data = wp->modedata; struct screen *s = &data->screen; - size_t inputlen, n; + const char *bufdata; + size_t inputlen, n, bufsize; int np; struct paste_buffer *pb; u_char ch; @@ -800,17 +801,18 @@ window_copy_key_input(struct window_pane *wp, int key) *data->inputstr = '\0'; break; case MODEKEYEDIT_PASTE: - if ((pb = paste_get_top()) == NULL) + if ((pb = paste_get_top(NULL)) == NULL) break; - for (n = 0; n < pb->size; n++) { - ch = (u_char) pb->data[n]; + bufdata = paste_buffer_data(pb, &bufsize); + for (n = 0; n < bufsize; n++) { + ch = (u_char)bufdata[n]; if (ch < 32 || ch == 127) break; } inputlen = strlen(data->inputstr); data->inputstr = xrealloc(data->inputstr, inputlen + n + 1); - memcpy(data->inputstr + inputlen, pb->data, n); + memcpy(data->inputstr + inputlen, bufdata, n); data->inputstr[inputlen + n] = '\0'; break; case MODEKEYEDIT_ENTER: @@ -1491,7 +1493,8 @@ window_copy_append_selection(struct window_pane *wp, const char *bufname) { char *buf; struct paste_buffer *pb; - size_t len; + const char *bufdata; + size_t len, bufsize; struct screen_write_ctx ctx; buf = window_copy_get_selection(wp, &len); @@ -1504,17 +1507,16 @@ window_copy_append_selection(struct window_pane *wp, const char *bufname) screen_write_stop(&ctx); } - if (bufname == NULL || *bufname == '\0') { - pb = paste_get_top(); - if (pb != NULL) - bufname = pb->name; - } else + if (bufname == NULL || *bufname == '\0') + pb = paste_get_top(&bufname); + else pb = paste_get_name(bufname); if (pb != NULL) { - buf = xrealloc(buf, len + pb->size); - memmove(buf + pb->size, buf, len); - memcpy(buf, pb->data, pb->size); - len += pb->size; + bufdata = paste_buffer_data(pb, &bufsize); + buf = xrealloc(buf, len + bufsize); + memmove(buf + bufsize, buf, len); + memcpy(buf, bufdata, bufsize); + len += bufsize; } if (paste_set(buf, len, bufname, NULL) != 0) free(buf); @@ -276,6 +276,13 @@ window_find_by_id(u_int id) return (RB_FIND(windows, &windows, &w)); } +void +window_update_activity(struct window *w) +{ + gettimeofday(&w->activity_time, NULL); + alerts_queue(w, WINDOW_ACTIVITY); +} + struct window * window_create1(u_int sx, u_int sy) { @@ -294,18 +301,15 @@ window_create1(u_int sx, u_int sy) w->sx = sx; w->sy = sy; - if (gettimeofday(&w->activity_time, NULL) != 0) - fatal("gettimeofday failed"); - options_init(&w->options, &global_w_options); - if (options_get_number(&w->options, "automatic-rename")) - queue_window_name(w); w->references = 0; w->id = next_window_id++; RB_INSERT(windows, &windows, w); + window_update_activity(w); + return (w); } @@ -348,8 +352,11 @@ window_destroy(struct window *w) layout_free_cell(w->saved_layout_root); free(w->old_layout); - if (event_initialized(&w->name_timer)) - evtimer_del(&w->name_timer); + if (event_initialized(&w->name_event)) + evtimer_del(&w->name_event); + + if (event_initialized(&w->alerts_timer)) + evtimer_del(&w->alerts_timer); options_free(&w->options); @@ -432,16 +439,6 @@ window_get_active_at(struct window *w, u_int x, u_int y) return (NULL); } -void -window_set_active_at(struct window *w, u_int x, u_int y) -{ - struct window_pane *wp; - - wp = window_get_active_at(w, x, y); - if (wp != NULL && wp != w->active) - window_set_active_pane(w, wp); -} - struct window_pane * window_find_string(struct window *w, const char *s) { @@ -703,6 +700,7 @@ struct window_pane * window_pane_create(struct window *w, u_int sx, u_int sy, u_int hlimit) { struct window_pane *wp; + char host[HOST_NAME_MAX + 1]; wp = xcalloc(1, sizeof *wp); wp->window = w; @@ -739,6 +737,9 @@ window_pane_create(struct window *w, u_int sx, u_int sy, u_int hlimit) screen_init(&wp->base, sx, sy, hlimit); wp->screen = &wp->base; + if (gethostname(host, sizeof host) == 0) + screen_set_title(&wp->base, host); + input_init(wp); return (wp); @@ -941,14 +942,6 @@ window_pane_read_callback(unused struct bufferevent *bufev, void *data) input_parse(wp); wp->pipe_off = EVBUFFER_LENGTH(evb); - - /* - * If we get here, we're not outputting anymore, so set the silence - * flag on the window. - */ - wp->window->flags |= WINDOW_SILENCE; - if (gettimeofday(&wp->window->silence_timer, NULL) != 0) - fatal("gettimeofday failed"); return; start_timer: @@ -1078,7 +1071,7 @@ window_pane_set_mode(struct window_pane *wp, const struct window_mode *mode) if ((s = wp->mode->init(wp)) != NULL) wp->screen = s; - wp->flags |= PANE_REDRAW; + wp->flags |= (PANE_REDRAW|PANE_CHANGED); return (0); } @@ -1092,7 +1085,7 @@ window_pane_reset_mode(struct window_pane *wp) wp->mode = NULL; wp->screen = &wp->base; - wp->flags |= PANE_REDRAW; + wp->flags |= (PANE_REDRAW|PANE_CHANGED); } void diff --git a/xterm-keys.c b/xterm-keys.c index 5ca75d89..10d51c78 100644 --- a/xterm-keys.c +++ b/xterm-keys.c @@ -120,6 +120,8 @@ xterm_keys_match(const char *template, const char *buf, size_t len, size_t pos; int retval; + *modifiers = 0; + if (len == 0) return (0); |