summaryrefslogtreecommitdiffstats
path: root/format.c
diff options
context:
space:
mode:
authorThomas Adam <thomas@xteddy.org>2021-02-22 08:01:22 +0000
committerThomas Adam <thomas@xteddy.org>2021-02-22 08:01:22 +0000
commitcb7e6698f3241cecfac31a045b907988a4c286f1 (patch)
treef1be1377641c3495ae0635e15cd96baa91431ce1 /format.c
parent742e67080586e212f3c6adbdc1c59bf56b0712b1 (diff)
parente858270006a9041b9016ed9e6cc12d622ac8fe31 (diff)
Merge branch 'obsd-master' into master
Diffstat (limited to 'format.c')
-rw-r--r--format.c2503
1 files changed, 2043 insertions, 460 deletions
diff --git a/format.c b/format.c
index 20a22d80..e18e7852 100644
--- a/format.c
+++ b/format.c
@@ -119,13 +119,23 @@ struct format_entry {
RB_ENTRY(format_entry) entry;
};
-/* Format entry tree. */
+/* Format type. */
+enum format_type {
+ FORMAT_TYPE_UNKNOWN,
+ FORMAT_TYPE_SESSION,
+ FORMAT_TYPE_WINDOW,
+ FORMAT_TYPE_PANE
+};
+
struct format_tree {
+ enum format_type type;
+
struct client *c;
struct session *s;
struct winlink *wl;
struct window *w;
struct window_pane *wp;
+ struct paste_buffer *pb;
struct cmdq_item *item;
struct client *client;
@@ -144,6 +154,7 @@ struct format_expand_state {
struct format_tree *ft;
u_int loop;
time_t time;
+ struct tm tm;
int flags;
};
@@ -263,6 +274,7 @@ format_copy_state(struct format_expand_state *to,
to->ft = from->ft;
to->loop = from->loop;
to->time = from->time;
+ memcpy(&to->tm, &from->tm, sizeof to->tm);
to->flags = from->flags|flags;
}
@@ -451,8 +463,21 @@ format_job_timer(__unused int fd, __unused short events, __unused void *arg)
evtimer_add(&format_job_event, &tv);
}
+/* Wrapper for asprintf. */
+static char * printflike(1, 2)
+format_printf(const char *fmt, ...)
+{
+ va_list ap;
+ char *s;
+
+ va_start(ap, fmt);
+ xvasprintf(&s, fmt, ap);
+ va_end(ap);
+ return (s);
+}
+
/* Callback for host. */
-static char *
+static void *
format_cb_host(__unused struct format_tree *ft)
{
char host[HOST_NAME_MAX + 1];
@@ -463,7 +488,7 @@ format_cb_host(__unused struct format_tree *ft)
}
/* Callback for host_short. */
-static char *
+static void *
format_cb_host_short(__unused struct format_tree *ft)
{
char host[HOST_NAME_MAX + 1], *cp;
@@ -476,7 +501,7 @@ format_cb_host_short(__unused struct format_tree *ft)
}
/* Callback for pid. */
-static char *
+static void *
format_cb_pid(__unused struct format_tree *ft)
{
char *value;
@@ -486,7 +511,7 @@ format_cb_pid(__unused struct format_tree *ft)
}
/* Callback for session_attached_list. */
-static char *
+static void *
format_cb_session_attached_list(struct format_tree *ft)
{
struct session *s = ft->s;
@@ -517,7 +542,7 @@ format_cb_session_attached_list(struct format_tree *ft)
}
/* Callback for session_alerts. */
-static char *
+static void *
format_cb_session_alerts(struct format_tree *ft)
{
struct session *s = ft->s;
@@ -547,7 +572,7 @@ format_cb_session_alerts(struct format_tree *ft)
}
/* Callback for session_stack. */
-static char *
+static void *
format_cb_session_stack(struct format_tree *ft)
{
struct session *s = ft->s;
@@ -569,14 +594,18 @@ format_cb_session_stack(struct format_tree *ft)
}
/* Callback for window_stack_index. */
-static char *
+static void *
format_cb_window_stack_index(struct format_tree *ft)
{
- struct session *s = ft->wl->session;
+ struct session *s;
struct winlink *wl;
u_int idx;
char *value = NULL;
+ if (ft->wl == NULL)
+ return (NULL);
+ s = ft->wl->session;
+
idx = 0;
TAILQ_FOREACH(wl, &s->lastw, sentry) {
idx++;
@@ -590,15 +619,19 @@ format_cb_window_stack_index(struct format_tree *ft)
}
/* Callback for window_linked_sessions_list. */
-static char *
+static void *
format_cb_window_linked_sessions_list(struct format_tree *ft)
{
- struct window *w = ft->wl->window;
+ struct window *w;
struct winlink *wl;
struct evbuffer *buffer;
int size;
char *value = NULL;
+ if (ft->wl == NULL)
+ return (NULL);
+ w = ft->wl->window;
+
buffer = evbuffer_new();
if (buffer == NULL)
fatalx("out of memory");
@@ -616,14 +649,18 @@ format_cb_window_linked_sessions_list(struct format_tree *ft)
}
/* Callback for window_active_sessions. */
-static char *
+static void *
format_cb_window_active_sessions(struct format_tree *ft)
{
- struct window *w = ft->wl->window;
+ struct window *w;
struct winlink *wl;
u_int n = 0;
char *value;
+ if (ft->wl == NULL)
+ return (NULL);
+ w = ft->wl->window;
+
TAILQ_FOREACH(wl, &w->winlinks, wentry) {
if (wl->session->curw == wl)
n++;
@@ -634,15 +671,19 @@ format_cb_window_active_sessions(struct format_tree *ft)
}
/* Callback for window_active_sessions_list. */
-static char *
+static void *
format_cb_window_active_sessions_list(struct format_tree *ft)
{
- struct window *w = ft->wl->window;
+ struct window *w;
struct winlink *wl;
struct evbuffer *buffer;
int size;
char *value = NULL;
+ if (ft->wl == NULL)
+ return (NULL);
+ w = ft->wl->window;
+
buffer = evbuffer_new();
if (buffer == NULL)
fatalx("out of memory");
@@ -662,15 +703,19 @@ format_cb_window_active_sessions_list(struct format_tree *ft)
}
/* Callback for window_active_clients. */
-static char *
+static void *
format_cb_window_active_clients(struct format_tree *ft)
{
- struct window *w = ft->wl->window;
+ struct window *w;
struct client *loop;
struct session *client_session;
u_int n = 0;
char *value;
+ if (ft->wl == NULL)
+ return (NULL);
+ w = ft->wl->window;
+
TAILQ_FOREACH(loop, &clients, entry) {
client_session = loop->session;
if (client_session == NULL)
@@ -685,16 +730,20 @@ format_cb_window_active_clients(struct format_tree *ft)
}
/* Callback for window_active_clients_list. */
-static char *
+static void *
format_cb_window_active_clients_list(struct format_tree *ft)
{
- struct window *w = ft->wl->window;
+ struct window *w;
struct client *loop;
struct session *client_session;
struct evbuffer *buffer;
int size;
char *value = NULL;
+ if (ft->wl == NULL)
+ return (NULL);
+ w = ft->wl->window;
+
buffer = evbuffer_new();
if (buffer == NULL)
fatalx("out of memory");
@@ -718,7 +767,7 @@ format_cb_window_active_clients_list(struct format_tree *ft)
}
/* Callback for window_layout. */
-static char *
+static void *
format_cb_window_layout(struct format_tree *ft)
{
struct window *w = ft->w;
@@ -732,7 +781,7 @@ format_cb_window_layout(struct format_tree *ft)
}
/* Callback for window_visible_layout. */
-static char *
+static void *
format_cb_window_visible_layout(struct format_tree *ft)
{
struct window *w = ft->w;
@@ -744,7 +793,7 @@ format_cb_window_visible_layout(struct format_tree *ft)
}
/* Callback for pane_start_command. */
-static char *
+static void *
format_cb_start_command(struct format_tree *ft)
{
struct window_pane *wp = ft->wp;
@@ -756,7 +805,7 @@ format_cb_start_command(struct format_tree *ft)
}
/* Callback for pane_current_command. */
-static char *
+static void *
format_cb_current_command(struct format_tree *ft)
{
struct window_pane *wp = ft->wp;
@@ -780,7 +829,7 @@ format_cb_current_command(struct format_tree *ft)
}
/* Callback for pane_current_path. */
-static char *
+static void *
format_cb_current_path(struct format_tree *ft)
{
struct window_pane *wp = ft->wp;
@@ -796,7 +845,7 @@ format_cb_current_path(struct format_tree *ft)
}
/* Callback for history_bytes. */
-static char *
+static void *
format_cb_history_bytes(struct format_tree *ft)
{
struct window_pane *wp = ft->wp;
@@ -822,7 +871,7 @@ format_cb_history_bytes(struct format_tree *ft)
}
/* Callback for history_all_bytes. */
-static char *
+static void *
format_cb_history_all_bytes(struct format_tree *ft)
{
struct window_pane *wp = ft->wp;
@@ -849,7 +898,7 @@ format_cb_history_all_bytes(struct format_tree *ft)
}
/* Callback for pane_tabs. */
-static char *
+static void *
format_cb_pane_tabs(struct format_tree *ft)
{
struct window_pane *wp = ft->wp;
@@ -879,7 +928,7 @@ format_cb_pane_tabs(struct format_tree *ft)
}
/* Callback for pane_fg. */
-static char *
+static void *
format_cb_pane_fg(struct format_tree *ft)
{
struct window_pane *wp = ft->wp;
@@ -890,7 +939,7 @@ format_cb_pane_fg(struct format_tree *ft)
}
/* Callback for pane_bg. */
-static char *
+static void *
format_cb_pane_bg(struct format_tree *ft)
{
struct window_pane *wp = ft->wp;
@@ -901,7 +950,7 @@ format_cb_pane_bg(struct format_tree *ft)
}
/* Callback for session_group_list. */
-static char *
+static void *
format_cb_session_group_list(struct format_tree *ft)
{
struct session *s = ft->s;
@@ -934,7 +983,7 @@ format_cb_session_group_list(struct format_tree *ft)
}
/* Callback for session_group_attached_list. */
-static char *
+static void *
format_cb_session_group_attached_list(struct format_tree *ft)
{
struct session *s = ft->s, *client_session, *session_loop;
@@ -974,7 +1023,7 @@ format_cb_session_group_attached_list(struct format_tree *ft)
}
/* Callback for pane_in_mode. */
-static char *
+static void *
format_cb_pane_in_mode(struct format_tree *ft)
{
struct window_pane *wp = ft->wp;
@@ -986,13 +1035,13 @@ format_cb_pane_in_mode(struct format_tree *ft)
return (NULL);
TAILQ_FOREACH(wme, &wp->modes, entry)
- n++;
+ n++;
xasprintf(&value, "%u", n);
return (value);
}
/* Callback for pane_at_top. */
-static char *
+static void *
format_cb_pane_at_top(struct format_tree *ft)
{
struct window_pane *wp = ft->wp;
@@ -1014,7 +1063,7 @@ format_cb_pane_at_top(struct format_tree *ft)
}
/* Callback for pane_at_bottom. */
-static char *
+static void *
format_cb_pane_at_bottom(struct format_tree *ft)
{
struct window_pane *wp = ft->wp;
@@ -1036,7 +1085,7 @@ format_cb_pane_at_bottom(struct format_tree *ft)
}
/* Callback for cursor_character. */
-static char *
+static void *
format_cb_cursor_character(struct format_tree *ft)
{
struct window_pane *wp = ft->wp;
@@ -1052,78 +1101,8 @@ format_cb_cursor_character(struct format_tree *ft)
return (value);
}
-/* Return word at given coordinates. Caller frees. */
-char *
-format_grid_word(struct grid *gd, u_int x, u_int y)
-{
- const struct grid_line *gl;
- struct grid_cell gc;
- const char *ws;
- struct utf8_data *ud = NULL;
- u_int end;
- size_t size = 0;
- int found = 0;
- char *s = NULL;
-
- ws = options_get_string(global_s_options, "word-separators");
-
- for (;;) {
- grid_get_cell(gd, x, y, &gc);
- if (gc.flags & GRID_FLAG_PADDING)
- break;
- if (utf8_cstrhas(ws, &gc.data)) {
- found = 1;
- break;
- }
-
- if (x == 0) {
- if (y == 0)
- break;
- gl = grid_peek_line(gd, y - 1);
- if (~gl->flags & GRID_LINE_WRAPPED)
- break;
- y--;
- x = grid_line_length(gd, y);
- if (x == 0)
- break;
- }
- x--;
- }
- for (;;) {
- if (found) {
- end = grid_line_length(gd, y);
- if (end == 0 || x == end - 1) {
- if (y == gd->hsize + gd->sy - 1)
- break;
- gl = grid_peek_line(gd, y);
- if (~gl->flags & GRID_LINE_WRAPPED)
- break;
- y++;
- x = 0;
- } else
- x++;
- }
- found = 1;
-
- grid_get_cell(gd, x, y, &gc);
- if (gc.flags & GRID_FLAG_PADDING)
- break;
- if (utf8_cstrhas(ws, &gc.data))
- break;
-
- ud = xreallocarray(ud, size + 2, sizeof *ud);
- memcpy(&ud[size++], &gc.data, sizeof *ud);
- }
- if (size != 0) {
- ud[size].size = 0;
- s = utf8_tocstr(ud);
- free(ud);
- }
- return (s);
-}
-
/* Callback for mouse_word. */
-static char *
+static void *
format_cb_mouse_word(struct format_tree *ft)
{
struct window_pane *wp;
@@ -1149,34 +1128,8 @@ format_cb_mouse_word(struct format_tree *ft)
return (format_grid_word(gd, x, gd->hsize + y));
}
-/* Return line at given coordinates. Caller frees. */
-char *
-format_grid_line(struct grid *gd, u_int y)
-{
- struct grid_cell gc;
- struct utf8_data *ud = NULL;
- u_int x;
- size_t size = 0;
- char *s = NULL;
-
- for (x = 0; x < grid_line_length(gd, y); x++) {
- grid_get_cell(gd, x, y, &gc);
- if (gc.flags & GRID_FLAG_PADDING)
- break;
-
- ud = xreallocarray(ud, size + 2, sizeof *ud);
- memcpy(&ud[size++], &gc.data, sizeof *ud);
- }
- if (size != 0) {
- ud[size].size = 0;
- s = utf8_tocstr(ud);
- free(ud);
- }
- return (s);
-}
-
/* Callback for mouse_line. */
-static char *
+static void *
format_cb_mouse_line(struct format_tree *ft)
{
struct window_pane *wp;
@@ -1201,6 +1154,1810 @@ format_cb_mouse_line(struct format_tree *ft)
return (format_grid_line(gd, gd->hsize + y));
}
+/* Callback for alternate_on. */
+static void *
+format_cb_alternate_on(struct format_tree *ft)
+{
+ if (ft->wp != NULL) {
+ if (ft->wp->base.saved_grid != NULL)
+ return (xstrdup("1"));
+ return (xstrdup("0"));
+ }
+ return (NULL);
+}
+
+/* Callback for alternate_saved_x. */
+static void *
+format_cb_alternate_saved_x(struct format_tree *ft)
+{
+ if (ft->wp != NULL)
+ return (format_printf("%u", ft->wp->base.saved_cx));
+ return (NULL);
+}
+
+/* Callback for alternate_saved_y. */
+static void *
+format_cb_alternate_saved_y(struct format_tree *ft)
+{
+ if (ft->wp != NULL)
+ return (format_printf("%u", ft->wp->base.saved_cy));
+ return (NULL);
+}
+
+/* Callback for buffer_name. */
+static void *
+format_cb_buffer_name(struct format_tree *ft)
+{
+ if (ft->pb != NULL)
+ return (xstrdup(paste_buffer_name(ft->pb)));
+ return (NULL);
+}
+
+/* Callback for buffer_sample. */
+static void *
+format_cb_buffer_sample(struct format_tree *ft)
+{
+ if (ft->pb != NULL)
+ return (paste_make_sample(ft->pb));
+ return (NULL);
+}
+
+/* Callback for buffer_size. */
+static void *
+format_cb_buffer_size(struct format_tree *ft)
+{
+ size_t size;
+
+ if (ft->pb != NULL) {
+ paste_buffer_data(ft->pb, &size);
+ return (format_printf("%zu", size));
+ }
+ return (NULL);
+}
+
+/* Callback for client_cell_height. */
+static void *
+format_cb_client_cell_height(struct format_tree *ft)
+{
+ if (ft->c != NULL && (ft->c->tty.flags & TTY_STARTED))
+ return (format_printf("%u", ft->c->tty.ypixel));
+ return (NULL);
+}
+
+/* Callback for client_cell_width. */
+static void *
+format_cb_client_cell_width(struct format_tree *ft)
+{
+ if (ft->c != NULL && (ft->c->tty.flags & TTY_STARTED))
+ return (format_printf("%u", ft->c->tty.xpixel));
+ return (NULL);
+}
+
+/* Callback for client_control_mode. */
+static void *
+format_cb_client_control_mode(struct format_tree *ft)
+{
+ if (ft->c != NULL) {
+ if (ft->c->flags & CLIENT_CONTROL)
+ return (xstrdup("1"));
+ return (xstrdup("0"));
+ }
+ return (NULL);
+}
+
+/* Callback for client_discarded. */
+static void *
+format_cb_client_discarded(struct format_tree *ft)
+{
+ if (ft->c != NULL)
+ return (format_printf("%zu", ft->c->discarded));
+ return (NULL);
+}
+
+/* Callback for client_flags. */
+static void *
+format_cb_client_flags(struct format_tree *ft)
+{
+ if (ft->c != NULL)
+ return (xstrdup(server_client_get_flags(ft->c)));
+ return (NULL);
+}
+
+/* Callback for client_height. */
+static void *
+format_cb_client_height(struct format_tree *ft)
+{
+ if (ft->c != NULL && (ft->c->tty.flags & TTY_STARTED))
+ return (format_printf("%u", ft->c->tty.sy));
+ return (NULL);
+}
+
+/* Callback for client_key_table. */
+static void *
+format_cb_client_key_table(struct format_tree *ft)
+{
+ if (ft->c != NULL)
+ return (xstrdup(ft->c->keytable->name));
+ return (NULL);
+}
+
+/* Callback for client_last_session. */
+static void *
+format_cb_client_last_session(struct format_tree *ft)
+{
+ if (ft->c != NULL &&
+ ft->c->last_session != NULL &&
+ session_alive(ft->c->last_session))
+ return (xstrdup(ft->c->last_session->name));
+ return (NULL);
+}
+
+/* Callback for client_name. */
+static void *
+format_cb_client_name(struct format_tree *ft)
+{
+ if (ft->c != NULL)
+ return (xstrdup(ft->c->name));
+ return (NULL);
+}
+
+/* Callback for client_pid. */
+static void *
+format_cb_client_pid(struct format_tree *ft)
+{
+ if (ft->c != NULL)
+ return (format_printf("%ld", (long)ft->c->pid));
+ return (NULL);
+}
+
+/* Callback for client_prefix. */
+static void *
+format_cb_client_prefix(struct format_tree *ft)
+{
+ const char *name;
+
+ if (ft->c != NULL) {
+ name = server_client_get_key_table(ft->c);
+ if (strcmp(ft->c->keytable->name, name) == 0)
+ return (xstrdup("1"));
+ return (xstrdup("0"));
+ }
+ return (NULL);
+}
+
+/* Callback for client_readonly. */
+static void *
+format_cb_client_readonly(struct format_tree *ft)
+{
+ if (ft->c != NULL) {
+ if (ft->c->flags & CLIENT_READONLY)
+ return (xstrdup("1"));
+ return (xstrdup("0"));
+ }
+ return (NULL);
+}
+
+/* Callback for client_session. */
+static void *
+format_cb_client_session(struct format_tree *ft)
+{
+ if (ft->c != NULL && ft->c->session != NULL)
+ return (xstrdup(ft->c->session->name));
+ return (NULL);
+}
+
+/* Callback for client_termfeatures. */
+static void *
+format_cb_client_termfeatures(struct format_tree *ft)
+{
+ if (ft->c != NULL)
+ return (xstrdup(tty_get_features(ft->c->term_features)));
+ return (NULL);
+}
+
+/* Callback for client_termname. */
+static void *
+format_cb_client_termname(struct format_tree *ft)
+{
+ if (ft->c != NULL)
+ return (xstrdup(ft->c->term_name));
+ return (NULL);
+}
+
+/* Callback for client_termtype. */
+static void *
+format_cb_client_termtype(struct format_tree *ft)
+{
+ if (ft->c != NULL)
+ return (xstrdup(ft->c->term_type));
+ return (NULL);
+}
+
+/* Callback for client_tty. */
+static void *
+format_cb_client_tty(struct format_tree *ft)
+{
+ if (ft->c != NULL)
+ return (xstrdup(ft->c->ttyname));
+ return (NULL);
+}
+
+/* Callback for client_utf8. */
+static void *
+format_cb_client_utf8(struct format_tree *ft)
+{
+ if (ft->c != NULL) {
+ if (ft->c->flags & CLIENT_UTF8)
+ return (xstrdup("1"));
+ return (xstrdup("0"));
+ }
+ return (NULL);
+}
+
+/* Callback for client_width. */
+static void *
+format_cb_client_width(struct format_tree *ft)
+{
+ if (ft->c != NULL)
+ return (format_printf("%u", ft->c->tty.sx));
+ return (NULL);
+}
+
+/* Callback for client_written. */
+static void *
+format_cb_client_written(struct format_tree *ft)
+{
+ if (ft->c != NULL)
+ return (format_printf("%zu", ft->c->written));
+ return (NULL);
+}
+
+/* Callback for cursor_flag. */
+static void *
+format_cb_cursor_flag(struct format_tree *ft)
+{
+ if (ft->wp != NULL) {
+ if (ft->wp->base.mode & MODE_CURSOR)
+ return (xstrdup("1"));
+ return (xstrdup("0"));
+ }
+ return (NULL);
+}
+
+/* Callback for cursor_x. */
+static void *
+format_cb_cursor_x(struct format_tree *ft)
+{
+ if (ft->wp != NULL)
+ return (format_printf("%u", ft->wp->base.cx));
+ return (NULL);
+}
+
+/* Callback for cursor_y. */
+static void *
+format_cb_cursor_y(struct format_tree *ft)
+{
+ if (ft->wp != NULL)
+ return (format_printf("%u", ft->wp->base.cy));
+ return (NULL);
+}
+
+/* Callback for history_limit. */
+static void *
+format_cb_history_limit(struct format_tree *ft)
+{
+ if (ft->wp != NULL)
+ return (format_printf("%u", ft->wp->base.grid->hlimit));
+ return (NULL);
+}
+
+/* Callback for history_size. */
+static void *
+format_cb_history_size(struct format_tree *ft)
+{
+ if (ft->wp != NULL)
+ return (format_printf("%u", ft->wp->base.grid->hsize));
+ return (NULL);
+}
+
+/* Callback for insert_flag. */
+static void *
+format_cb_insert_flag(struct format_tree *ft)
+{
+ if (ft->wp != NULL) {
+ if (ft->wp->base.mode & MODE_INSERT)
+ return (xstrdup("1"));
+ return (xstrdup("0"));
+ }
+ return (NULL);
+}
+
+/* Callback for keypad_cursor_flag. */
+static void *
+format_cb_keypad_cursor_flag(struct format_tree *ft)
+{
+ if (ft->wp != NULL) {
+ if (ft->wp->base.mode & MODE_KCURSOR)
+ return (xstrdup("1"));
+ return (xstrdup("0"));
+ }
+ return (NULL);
+}
+
+/* Callback for keypad_flag. */
+static void *
+format_cb_keypad_flag(struct format_tree *ft)
+{
+ if (ft->wp != NULL) {
+ if (ft->wp->base.mode & MODE_KKEYPAD)
+ return (xstrdup("1"));
+ return (xstrdup("0"));
+ }
+ return (NULL);
+}
+
+/* Callback for mouse_all_flag. */
+static void *
+format_cb_mouse_all_flag(struct format_tree *ft)
+{
+ if (ft->wp != NULL) {
+ if (ft->wp->base.mode & MODE_MOUSE_ALL)
+ return (xstrdup("1"));
+ return (xstrdup("0"));
+ }
+ return (NULL);
+}
+
+/* Callback for mouse_any_flag. */
+static void *
+format_cb_mouse_any_flag(struct format_tree *ft)
+{
+ if (ft->wp != NULL) {
+ if (ft->wp->base.mode & ALL_MOUSE_MODES)
+ return (xstrdup("1"));
+ return (xstrdup("0"));
+ }
+ return (NULL);
+}
+
+/* Callback for mouse_button_flag. */
+static void *
+format_cb_mouse_button_flag(struct format_tree *ft)
+{
+ if (ft->wp != NULL) {
+ if (ft->wp->base.mode & MODE_MOUSE_BUTTON)
+ return (xstrdup("1"));
+ return (xstrdup("0"));
+ }
+ return (NULL);
+}
+
+/* Callback for mouse_pane. */
+static void *
+format_cb_mouse_pane(struct format_tree *ft)
+{
+ struct window_pane *wp;
+
+ if (ft->m.valid) {
+ wp = cmd_mouse_pane(&ft->m, NULL, NULL);
+ if (wp != NULL)
+ return (format_printf("%%%u", wp->id));
+ return (NULL);
+ }
+ return (NULL);
+}
+
+/* Callback for mouse_sgr_flag. */
+static void *
+format_cb_mouse_sgr_flag(struct format_tree *ft)
+{
+ if (ft->wp != NULL) {
+ if (ft->wp->base.mode & MODE_MOUSE_SGR)
+ return (xstrdup("1"));
+ return (xstrdup("0"));
+ }
+ return (NULL);
+}
+
+/* Callback for mouse_standard_flag. */
+static void *
+format_cb_mouse_standard_flag(struct format_tree *ft)
+{
+ if (ft->wp != NULL) {
+ if (ft->wp->base.mode & MODE_MOUSE_STANDARD)
+ return (xstrdup("1"));
+ return (xstrdup("0"));
+ }
+ return (NULL);
+}
+
+/* Callback for mouse_utf8_flag. */
+static void *
+format_cb_mouse_utf8_flag(struct format_tree *ft)
+{
+ if (ft->wp != NULL) {
+ if (ft->wp->base.mode & MODE_MOUSE_UTF8)
+ return (xstrdup("1"));
+ return (xstrdup("0"));
+ }
+ return (NULL);
+}
+
+/* Callback for mouse_x. */
+static void *
+format_cb_mouse_x(struct format_tree *ft)
+{
+ struct window_pane *wp;
+ u_int x, y;
+
+ if (ft->m.valid) {
+ wp = cmd_mouse_pane(&ft->m, NULL, NULL);
+ if (wp != NULL && cmd_mouse_at(wp, &ft->m, &x, &y, 0) == 0)
+ return (format_printf("%u", x));
+ return (NULL);
+ }
+ return (NULL);
+}
+
+/* Callback for mouse_y. */
+static void *
+format_cb_mouse_y(struct format_tree *ft)
+{
+ struct window_pane *wp;
+ u_int x, y;
+
+ if (ft->m.valid) {
+ wp = cmd_mouse_pane(&ft->m, NULL, NULL);
+ if (wp != NULL && cmd_mouse_at(wp, &ft->m, &x, &y, 0) == 0)
+ return (format_printf("%u", y));
+ return (NULL);
+ }
+ return (NULL);
+}
+
+/* Callback for origin_flag. */
+static void *
+format_cb_origin_flag(struct format_tree *ft)
+{
+ if (ft->wp != NULL) {
+ if (ft->wp->base.mode & MODE_ORIGIN)
+ return (xstrdup("1"));
+ return (xstrdup("0"));
+ }
+ return (NULL);
+}
+
+/* Callback for pane_active. */
+static void *
+format_cb_pane_active(struct format_tree *ft)
+{
+ if (ft->wp != NULL) {
+ if (ft->wp == ft->wp->window->active)
+ return (xstrdup("1"));
+ return (xstrdup("0"));
+ }
+ return (NULL);
+}
+
+/* Callback for pane_at_left. */
+static void *
+format_cb_pane_at_left(struct format_tree *ft)
+{
+ if (ft->wp != NULL) {
+ if (ft->wp->xoff == 0)
+ return (xstrdup("1"));
+ return (xstrdup("0"));
+ }
+ return (NULL);
+}
+
+/* Callback for pane_at_right. */
+static void *
+format_cb_pane_at_right(struct format_tree *ft)
+{
+ if (ft->wp != NULL) {
+ if (ft->wp->xoff + ft->wp->sx == ft->wp->window->sx)
+ return (xstrdup("1"));
+ return (xstrdup("0"));
+ }
+ return (NULL);
+}
+
+/* Callback for pane_bottom. */
+static void *
+format_cb_pane_bottom(struct format_tree *ft)
+{
+ if (ft->wp != NULL)
+ return (format_printf("%u", ft->wp->yoff + ft->wp->sy - 1));
+ return (NULL);
+}
+
+/* Callback for pane_dead. */
+static void *
+format_cb_pane_dead(struct format_tree *ft)
+{
+ if (ft->wp != NULL) {
+ if (ft->wp->fd == -1)
+ return (xstrdup("1"));
+ return (xstrdup("0"));
+ }
+ return (NULL);
+}
+
+/* Callback for pane_dead_status. */
+static void *
+format_cb_pane_dead_status(struct format_tree *ft)
+{
+ struct window_pane *wp = ft->wp;
+
+ if (wp != NULL) {
+ if ((wp->flags & PANE_STATUSREADY) && WIFEXITED(wp->status))
+ return (format_printf("%d", WEXITSTATUS(wp->status)));
+ return (NULL);
+ }
+ return (NULL);
+}
+
+/* Callback for pane_format. */
+static void *
+format_cb_pane_format(struct format_tree *ft)
+{
+ if (ft->type == FORMAT_TYPE_PANE)
+ return (xstrdup("1"));
+ return (xstrdup("0"));
+}
+
+/* Callback for pane_height. */
+static void *
+format_cb_pane_height(struct format_tree *ft)
+{
+ if (ft->wp != NULL)
+ return (format_printf("%u", ft->wp->sy));
+ return (NULL);
+}
+
+/* Callback for pane_id. */
+static void *
+format_cb_pane_id(struct format_tree *ft)
+{
+ if (ft->wp != NULL)
+ return (format_printf("%%%u", ft->wp->id));
+ return (NULL);
+}
+
+/* Callback for pane_index. */
+static void *
+format_cb_pane_index(struct format_tree *ft)
+{
+ u_int idx;
+
+ if (ft->wp != NULL && window_pane_index(ft->wp, &idx) == 0)
+ return (format_printf("%u", idx));
+ return (NULL);
+}
+
+/* Callback for pane_input_off. */
+static void *
+format_cb_pane_input_off(struct format_tree *ft)
+{
+ if (ft->wp != NULL) {
+ if (ft->wp->flags & PANE_INPUTOFF)
+ return (xstrdup("1"));
+ return (xstrdup("0"));
+ }
+ return (NULL);
+}
+
+/* Callback for pane_last. */
+static void *
+format_cb_pane_last(struct format_tree *ft)
+{
+ if (ft->wp != NULL) {
+ if (ft->wp == ft->wp->window->last)
+ return (xstrdup("1"));
+ return (xstrdup("0"));
+ }
+ return (NULL);
+}
+
+/* Callback for pane_left. */
+static void *
+format_cb_pane_left(struct format_tree *ft)
+{
+ if (ft->wp != NULL)
+ return (format_printf("%u", ft->wp->xoff));
+ return (NULL);
+}
+
+/* Callback for pane_marked. */
+static void *
+format_cb_pane_marked(struct format_tree *ft)
+{
+ if (ft->wp != NULL) {
+ if (server_check_marked() && marked_pane.wp == ft->wp)
+ return (xstrdup("1"));
+ return (xstrdup("0"));
+ }
+ return (NULL);
+}
+
+/* Callback for pane_marked_set. */
+static void *
+format_cb_pane_marked_set(struct format_tree *ft)
+{
+ if (ft->wp != NULL) {
+ if (server_check_marked())
+ return (xstrdup("1"));
+ return (xstrdup("0"));
+ }
+ return (NULL);
+}
+
+/* Callback for pane_mode. */
+static void *
+format_cb_pane_mode(struct format_tree *ft)
+{
+ struct window_mode_entry *wme;
+
+ if (ft->wp != NULL) {
+ wme = TAILQ_FIRST(&ft->wp->modes);
+ if (wme != NULL)
+ return (xstrdup(wme->mode->name));
+ return (NULL);
+ }
+ return (NULL);
+}
+
+/* Callback for pane_path. */
+static void *
+format_cb_pane_path(struct format_tree *ft)
+{
+ if (ft->wp != NULL) {
+ if (ft->wp->base.path == NULL)
+ return (xstrdup(""));
+ return (xstrdup(ft->wp->base.path));
+ }
+ return (NULL);
+}
+
+/* Callback for pane_pid. */
+static void *
+format_cb_pane_pid(struct format_tree *ft)
+{
+ if (ft->wp != NULL)
+ return (format_printf("%ld", (long)ft->wp->pid));
+ return (NULL);
+}
+
+/* Callback for pane_pipe. */
+static void *
+format_cb_pane_pipe(struct format_tree *ft)
+{
+ if (ft->wp != NULL) {
+ if (ft->wp->pipe_fd != -1)
+ return (xstrdup("1"));
+ return (xstrdup("0"));
+ }
+ return (NULL);
+}
+
+/* Callback for pane_right. */
+static void *
+format_cb_pane_right(struct format_tree *ft)
+{
+ if (ft->wp != NULL)
+ return (format_printf("%u", ft->wp->xoff + ft->wp->sx - 1));
+ return (NULL);
+}
+
+/* Callback for pane_search_string. */
+static void *
+format_cb_pane_search_string(struct format_tree *ft)
+{
+ if (ft->wp != NULL) {
+ if (ft->wp->searchstr == NULL)
+ return (xstrdup(""));
+ return (xstrdup(ft->wp->searchstr));
+ }
+ return (NULL);
+}
+
+/* Callback for pane_synchronized. */
+static void *
+format_cb_pane_synchronized(struct format_tree *ft)
+{
+ if (ft->wp != NULL) {
+ if (options_get_number(ft->wp->options, "synchronize-panes"))
+ return (xstrdup("1"));
+ return (xstrdup("0"));
+ }
+ return (NULL);
+}
+
+/* Callback for pane_title. */
+static void *
+format_cb_pane_title(struct format_tree *ft)
+{
+ if (ft->wp != NULL)
+ return (xstrdup(ft->wp->base.title));
+ return (NULL);
+}
+
+/* Callback for pane_top. */
+static void *
+format_cb_pane_top(struct format_tree *ft)
+{
+ if (ft->wp != NULL)
+ return (format_printf("%u", ft->wp->yoff));
+ return (NULL);
+}
+
+/* Callback for pane_tty. */
+static void *
+format_cb_pane_tty(struct format_tree *ft)
+{
+ if (ft->wp != NULL)
+ return (xstrdup(ft->wp->tty));
+ return (NULL);
+}
+
+/* Callback for pane_width. */
+static void *
+format_cb_pane_width(struct format_tree *ft)
+{
+ if (ft->wp != NULL)
+ return (format_printf("%u", ft->wp->sx));
+ return (NULL);
+}
+
+/* Callback for scroll_region_lower. */
+static void *
+format_cb_scroll_region_lower(struct format_tree *ft)
+{
+ if (ft->wp != NULL)
+ return (format_printf("%u", ft->wp->base.rlower));
+ return (NULL);
+}
+
+/* Callback for scroll_region_upper. */
+static void *
+format_cb_scroll_region_upper(struct format_tree *ft)
+{
+ if (ft->wp != NULL)
+ return (format_printf("%u", ft->wp->base.rupper));
+ return (NULL);
+}
+
+/* Callback for session_attached. */
+static void *
+format_cb_session_attached(struct format_tree *ft)
+{
+ if (ft->s != NULL)
+ return (format_printf("%u", ft->s->attached));
+ return (NULL);
+}
+
+/* Callback for session_format. */
+static void *
+format_cb_session_format(struct format_tree *ft)
+{
+ if (ft->type == FORMAT_TYPE_SESSION)
+ return (xstrdup("1"));
+ return (xstrdup("0"));
+}
+
+/* Callback for session_group. */
+static void *
+format_cb_session_group(struct format_