Merge branch 'obsd-master'

Conflicts:
	Makefile
	format.c
pull/121/head
Thomas Adam 2015-08-30 21:44:01 +01:00
commit cb89f2f2a1
26 changed files with 594 additions and 388 deletions

View File

@ -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 \

View File

@ -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 *);
/* Window functions that need to happen every loop. */
void
server_window_loop(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);
}
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 (s->curw->window == w)
w->flags &= ~WINDOW_SILENCE;
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");
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;

View File

@ -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);

View File

@ -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);

View File

@ -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();

View File

@ -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);

View File

@ -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);
}

View File

@ -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();

View File

@ -56,7 +56,7 @@ cmd_show_environment_escape(struct environ_entry *envent)
}
*out = '\0';
return ret;
return (ret);
}
void

View File

@ -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);

352
format.c
View File

@ -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);

View File

@ -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);

View File

@ -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)
{

9
log.c
View File

@ -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);

63
names.c
View File

@ -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);
}
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);
int
name_time_expired(struct window *w, struct timeval *tv)
{
struct timeval offset;
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;
if (~w->active->flags & PANE_CHANGED) {
log_debug("@%u active pane not changed", w->id);
return;
}
queue_window_name(w);
log_debug("@%u active pane changed", w->id);
if (~w->active->flags & PANE_CHANGED)
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);
}

63
paste.c
View File

@ -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);
}

View File

@ -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("");

View File

@ -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);
}
}

View File

@ -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();
}
}

View File

@ -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);
}

View File

@ -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;
}

4
tmux.c
View File

@ -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

75
tmux.h
View File

@ -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 *);

View File

@ -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);

View File

@ -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

View File

@ -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);