diff options
author | Nicholas Marriott <nicm@cvs.openbsd.org> | 2019-05-07 20:01:42 +0000 |
---|---|---|
committer | Nicholas Marriott <nicm@cvs.openbsd.org> | 2019-05-07 20:01:42 +0000 |
commit | 7f930ebd2b4ec4ba66134fa7eb4f8e1d807a274d (patch) | |
tree | 991b9877ed91bf8147dcac41430a7d392c857a81 | |
parent | 5c61d45a254862e55b4d16a7c2fcfb475a8602f2 (diff) |
Move around the display-panes identify code to make it a bit more
generic and hide the display-panes specific bits into
cmd-display-panes.c.
-rw-r--r-- | usr.bin/tmux/cmd-display-panes.c | 256 | ||||
-rw-r--r-- | usr.bin/tmux/screen-redraw.c | 185 | ||||
-rw-r--r-- | usr.bin/tmux/server-client.c | 83 | ||||
-rw-r--r-- | usr.bin/tmux/tmux.h | 37 |
4 files changed, 290 insertions, 271 deletions
diff --git a/usr.bin/tmux/cmd-display-panes.c b/usr.bin/tmux/cmd-display-panes.c index 73533202da5..fbc54be6500 100644 --- a/usr.bin/tmux/cmd-display-panes.c +++ b/usr.bin/tmux/cmd-display-panes.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-display-panes.c,v 1.23 2019/02/06 07:36:06 nicm Exp $ */ +/* $OpenBSD: cmd-display-panes.c,v 1.24 2019/05/07 20:01:41 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -20,6 +20,7 @@ #include <ctype.h> #include <stdlib.h> +#include <string.h> #include "tmux.h" @@ -30,9 +31,6 @@ static enum cmd_retval cmd_display_panes_exec(struct cmd *, struct cmdq_item *); -static void cmd_display_panes_callback(struct client *, - struct window_pane *); - const struct cmd_entry cmd_display_panes_entry = { .name = "display-panes", .alias = "displayp", @@ -44,46 +42,145 @@ const struct cmd_entry cmd_display_panes_entry = { .exec = cmd_display_panes_exec }; -static enum cmd_retval -cmd_display_panes_exec(struct cmd *self, struct cmdq_item *item) +struct cmd_display_panes_data { + struct cmdq_item *item; + char *command; +}; + +static void +cmd_display_panes_draw_pane(struct screen_redraw_ctx *ctx, + struct window_pane *wp) { - struct args *args = self->args; - struct client *c; - struct session *s; - u_int delay; - char *cause; + struct client *c = ctx->c; + struct tty *tty = &c->tty; + struct session *s = c->session; + struct options *oo = s->options; + struct window *w = wp->window; + struct grid_cell gc; + u_int idx, px, py, i, j, xoff, yoff, sx, sy; + int colour, active_colour; + char buf[16], *ptr; + size_t len; - if ((c = cmd_find_client(item, args_get(args, 't'), 0)) == NULL) - return (CMD_RETURN_ERROR); - s = c->session; + if (wp->xoff + wp->sx <= ctx->ox || + wp->xoff >= ctx->ox + ctx->sx || + wp->yoff + wp->sy <= ctx->oy || + wp->yoff >= ctx->oy + ctx->sy) + return; - if (c->identify_callback != NULL) - return (CMD_RETURN_NORMAL); + if (wp->xoff >= ctx->ox && wp->xoff + wp->sx <= ctx->ox + ctx->sx) { + /* All visible. */ + xoff = wp->xoff - ctx->ox; + sx = wp->sx; + } else if (wp->xoff < ctx->ox && + wp->xoff + wp->sx > ctx->ox + ctx->sx) { + /* Both left and right not visible. */ + xoff = 0; + sx = ctx->sx; + } else if (wp->xoff < ctx->ox) { + /* Left not visible. */ + xoff = 0; + sx = wp->sx - (ctx->ox - wp->xoff); + } else { + /* Right not visible. */ + xoff = wp->xoff - ctx->ox; + sx = wp->sx - xoff; + } + if (wp->yoff >= ctx->oy && wp->yoff + wp->sy <= ctx->oy + ctx->sy) { + /* All visible. */ + yoff = wp->yoff - ctx->oy; + sy = wp->sy; + } else if (wp->yoff < ctx->oy && + wp->yoff + wp->sy > ctx->oy + ctx->sy) { + /* Both top and bottom not visible. */ + yoff = 0; + sy = ctx->sy; + } else if (wp->yoff < ctx->oy) { + /* Top not visible. */ + yoff = 0; + sy = wp->sy - (ctx->oy - wp->yoff); + } else { + /* Bottom not visible. */ + yoff = wp->yoff - ctx->oy; + sy = wp->sy - yoff; + } - c->identify_callback = cmd_display_panes_callback; - if (args->argc != 0) - c->identify_callback_data = xstrdup(args->argv[0]); - else - c->identify_callback_data = xstrdup("select-pane -t '%%'"); - if (args_has(args, 'b')) - c->identify_callback_item = NULL; + if (ctx->statustop) + yoff += ctx->statuslines; + px = sx / 2; + py = sy / 2; + + if (window_pane_index(wp, &idx) != 0) + fatalx("index not found"); + len = xsnprintf(buf, sizeof buf, "%u", idx); + + if (sx < len) + return; + colour = options_get_number(oo, "display-panes-colour"); + active_colour = options_get_number(oo, "display-panes-active-colour"); + + if (sx < len * 6 || sy < 5) { + tty_cursor(tty, xoff + px - len / 2, yoff + py); + goto draw_text; + } + + px -= len * 3; + py -= 2; + + memcpy(&gc, &grid_default_cell, sizeof gc); + if (w->active == wp) + gc.bg = active_colour; else - c->identify_callback_item = item; + gc.bg = colour; + gc.flags |= GRID_FLAG_NOPALETTE; - if (args_has(args, 'd')) { - delay = args_strtonum(args, 'd', 0, UINT_MAX, &cause); - if (cause != NULL) { - cmdq_error(item, "delay %s", cause); - free(cause); - return (CMD_RETURN_ERROR); + tty_attributes(tty, &gc, wp); + for (ptr = buf; *ptr != '\0'; ptr++) { + if (*ptr < '0' || *ptr > '9') + continue; + idx = *ptr - '0'; + + for (j = 0; j < 5; j++) { + for (i = px; i < px + 5; i++) { + tty_cursor(tty, xoff + i, yoff + py + j); + if (window_clock_table[idx][j][i - px]) + tty_putc(tty, ' '); + } } - } else - delay = options_get_number(s->options, "display-panes-time"); - server_client_set_identify(c, delay); + px += 6; + } - if (args_has(args, 'b')) - return (CMD_RETURN_NORMAL); - return (CMD_RETURN_WAIT); + len = xsnprintf(buf, sizeof buf, "%ux%u", wp->sx, wp->sy); + if (sx < len || sy < 6) + return; + tty_cursor(tty, xoff + sx - len, yoff); + +draw_text: + memcpy(&gc, &grid_default_cell, sizeof gc); + if (w->active == wp) + gc.fg = active_colour; + else + gc.fg = colour; + gc.flags |= GRID_FLAG_NOPALETTE; + + tty_attributes(tty, &gc, wp); + tty_puts(tty, buf); + + tty_cursor(tty, 0, 0); +} + +static void +cmd_display_panes_draw(struct client *c, struct screen_redraw_ctx *ctx) +{ + struct window *w = c->session->curw->window; + struct window_pane *wp; + + log_debug("%s: %s @%u", __func__, c->name, w->id); + + TAILQ_FOREACH(wp, &w->panes, entry) { + if (window_pane_visible(wp)) + cmd_display_panes_draw_pane(ctx, wp); + } } static enum cmd_retval @@ -98,17 +195,36 @@ cmd_display_panes_error(struct cmdq_item *item, void *data) } static void -cmd_display_panes_callback(struct client *c, struct window_pane *wp) +cmd_display_panes_free(struct client *c) { - struct cmd_list *cmdlist; - struct cmdq_item *new_item; - char *cmd, *expanded, *cause; + struct cmd_display_panes_data *cdata = c->overlay_data; + + if (cdata->item != NULL) + cdata->item->flags &= ~CMDQ_WAITING; + free(cdata->command); + free(cdata); +} + +static int +cmd_display_panes_key(struct client *c, struct key_event *event) +{ + struct cmd_display_panes_data *cdata = c->overlay_data; + struct cmd_list *cmdlist; + struct cmdq_item *new_item; + char *cmd, *expanded, *cause; + struct window *w = c->session->curw->window; + struct window_pane *wp; + + if (event->key < '0' || event->key > '9') + return (1); + wp = window_pane_at_index(w, event->key - '0'); if (wp == NULL) - goto out; + return (1); + window_unzoom(w); xasprintf(&expanded, "%%%u", wp->id); - cmd = cmd_template_replace(c->identify_callback_data, expanded, 1); + cmd = cmd_template_replace(cdata->command, expanded, 1); cmdlist = cmd_string_parse(cmd, NULL, 0, &cause); if (cmdlist == NULL && cause != NULL) @@ -119,25 +235,59 @@ cmd_display_panes_callback(struct client *c, struct window_pane *wp) new_item = cmdq_get_command(cmdlist, NULL, NULL, 0); cmd_list_free(cmdlist); } - if (new_item != NULL) { - if (c->identify_callback_item != NULL) - cmdq_insert_after(c->identify_callback_item, new_item); + if (cdata->item != NULL) + cmdq_insert_after(cdata->item, new_item); else cmdq_append(c, new_item); } free(cmd); free(expanded); + return (1); +} -out: - if (c->identify_callback_item != NULL) { - c->identify_callback_item->flags &= ~CMDQ_WAITING; - c->identify_callback_item = NULL; - } +static enum cmd_retval +cmd_display_panes_exec(struct cmd *self, struct cmdq_item *item) +{ + struct args *args = self->args; + struct client *c; + struct session *s; + u_int delay; + char *cause; + struct cmd_display_panes_data *cdata; + + if ((c = cmd_find_client(item, args_get(args, 't'), 0)) == NULL) + return (CMD_RETURN_ERROR); + s = c->session; - free(c->identify_callback_data); - c->identify_callback_data = NULL; + if (c->overlay_draw != NULL) + return (CMD_RETURN_NORMAL); + + if (args_has(args, 'd')) { + delay = args_strtonum(args, 'd', 0, UINT_MAX, &cause); + if (cause != NULL) { + cmdq_error(item, "delay %s", cause); + free(cause); + return (CMD_RETURN_ERROR); + } + } else + delay = options_get_number(s->options, "display-panes-time"); + + cdata = xmalloc(sizeof *cdata); + if (args->argc != 0) + cdata->command = xstrdup(args->argv[0]); + else + cdata->command = xstrdup("select-pane -t '%%'"); + if (args_has(args, 'b')) + cdata->item = NULL; + else + cdata->item = item; + + server_client_set_overlay(c, delay, cmd_display_panes_draw, + cmd_display_panes_key, cmd_display_panes_free, cdata); - c->identify_callback = NULL; + if (args_has(args, 'b')) + return (CMD_RETURN_NORMAL); + return (CMD_RETURN_WAIT); } diff --git a/usr.bin/tmux/screen-redraw.c b/usr.bin/tmux/screen-redraw.c index 80db9362b15..8a8e734cc46 100644 --- a/usr.bin/tmux/screen-redraw.c +++ b/usr.bin/tmux/screen-redraw.c @@ -1,4 +1,4 @@ -/* $OpenBSD: screen-redraw.c,v 1.60 2019/04/17 14:41:08 nicm Exp $ */ +/* $OpenBSD: screen-redraw.c,v 1.61 2019/05/07 20:01:41 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -23,27 +23,11 @@ #include "tmux.h" -struct screen_redraw_ctx { - struct client *c; - - u_int lines; - int top; - - int pane_status; - - u_int sx; - u_int sy; - u_int ox; - u_int oy; -}; - static void screen_redraw_draw_borders(struct screen_redraw_ctx *); static void screen_redraw_draw_panes(struct screen_redraw_ctx *); static void screen_redraw_draw_status(struct screen_redraw_ctx *); static void screen_redraw_draw_pane(struct screen_redraw_ctx *, struct window_pane *); -static void screen_redraw_draw_number(struct screen_redraw_ctx *, - struct window_pane *); #define CELL_INSIDE 0 #define CELL_LEFTRIGHT 1 @@ -374,8 +358,8 @@ screen_redraw_draw_pane_status(struct screen_redraw_ctx *ctx) width = size - x; } - if (ctx->top) - yoff += ctx->lines; + if (ctx->statustop) + yoff += ctx->statuslines; tty_draw_line(tty, NULL, s, i, 0, width, x, yoff - ctx->oy); } tty_cursor(tty, 0, 0); @@ -419,21 +403,25 @@ screen_redraw_set_context(struct client *c, struct screen_redraw_ctx *ctx) struct options *oo = s->options; struct window *w = s->curw->window; struct options *wo = w->options; + u_int lines; memset(ctx, 0, sizeof *ctx); ctx->c = c; - ctx->lines = status_line_size(c); + lines = status_line_size(c); if (c->message_string != NULL || c->prompt_string != NULL) - ctx->lines = (ctx->lines == 0) ? 1 : ctx->lines; - if (ctx->lines != 0 && options_get_number(oo, "status-position") == 0) - ctx->top = 1; + lines = (lines == 0) ? 1 : lines; + if (lines != 0 && options_get_number(oo, "status-position") == 0) + ctx->statustop = 1; + ctx->statuslines = lines; + ctx->pane_status = options_get_number(wo, "pane-border-status"); tty_window_offset(&c->tty, &ctx->ox, &ctx->oy, &ctx->sx, &ctx->sy); log_debug("%s: %s @%u ox=%u oy=%u sx=%u sy=%u %u/%d", __func__, c->name, - w->id, ctx->ox, ctx->oy, ctx->sx, ctx->sy, ctx->lines, ctx->top); + w->id, ctx->ox, ctx->oy, ctx->sx, ctx->sy, ctx->statuslines, + ctx->statustop); } /* Redraw entire screen. */ @@ -456,9 +444,11 @@ screen_redraw_screen(struct client *c) } if (flags & CLIENT_REDRAWWINDOW) screen_redraw_draw_panes(&ctx); - if (ctx.lines != 0 && + if (ctx.statuslines != 0 && (flags & (CLIENT_REDRAWSTATUS|CLIENT_REDRAWSTATUSALWAYS))) screen_redraw_draw_status(&ctx); + if (c->overlay_draw != NULL) + c->overlay_draw(c, &ctx); tty_reset(&c->tty); } @@ -508,8 +498,8 @@ screen_redraw_draw_borders_cell(struct screen_redraw_ctx *ctx, u_int i, u_int j, tty_attributes(tty, active_gc, NULL); else tty_attributes(tty, other_gc, NULL); - if (ctx->top) - tty_cursor(tty, i, ctx->lines + j); + if (ctx->statustop) + tty_cursor(tty, i, ctx->statuslines + j); else tty_cursor(tty, i, j); tty_putc(tty, CELL_BORDERS[type]); @@ -538,7 +528,7 @@ screen_redraw_draw_borders(struct screen_redraw_ctx *ctx) memcpy(&m_active_gc, &active_gc, sizeof m_active_gc); m_active_gc.attr ^= GRID_ATTR_REVERSE; - for (j = 0; j < tty->sy - ctx->lines; j++) { + for (j = 0; j < tty->sy - ctx->statuslines; j++) { for (i = 0; i < tty->sx; i++) { screen_redraw_draw_borders_cell(ctx, i, j, &m_active_gc, &active_gc, &m_other_gc, &other_gc); @@ -557,11 +547,8 @@ screen_redraw_draw_panes(struct screen_redraw_ctx *ctx) log_debug("%s: %s @%u", __func__, c->name, w->id); TAILQ_FOREACH(wp, &w->panes, entry) { - if (!window_pane_visible(wp)) - continue; - screen_redraw_draw_pane(ctx, wp); - if (c->flags & CLIENT_IDENTIFY) - screen_redraw_draw_number(ctx, wp); + if (window_pane_visible(wp)) + screen_redraw_draw_pane(ctx, wp); } } @@ -577,11 +564,11 @@ screen_redraw_draw_status(struct screen_redraw_ctx *ctx) log_debug("%s: %s @%u", __func__, c->name, w->id); - if (ctx->top) + if (ctx->statustop) y = 0; else - y = c->tty.sy - ctx->lines; - for (i = 0; i < ctx->lines; i++) + y = c->tty.sy - ctx->statuslines; + for (i = 0; i < ctx->statuslines; i++) tty_draw_line(tty, NULL, s, 0, i, UINT_MAX, 0, y + i); } @@ -599,8 +586,8 @@ screen_redraw_draw_pane(struct screen_redraw_ctx *ctx, struct window_pane *wp) if (wp->xoff + wp->sx <= ctx->ox || wp->xoff >= ctx->ox + ctx->sx) return; - if (ctx->top) - top = ctx->lines; + if (ctx->statustop) + top = ctx->statuslines; else top = 0; @@ -639,125 +626,3 @@ screen_redraw_draw_pane(struct screen_redraw_ctx *ctx, struct window_pane *wp) tty_draw_line(tty, wp, s, i, j, width, x, y); } } - -/* Draw number on a pane. */ -static void -screen_redraw_draw_number(struct screen_redraw_ctx *ctx, struct window_pane *wp) -{ - struct client *c = ctx->c; - struct tty *tty = &c->tty; - struct session *s = c->session; - struct options *oo = s->options; - struct window *w = wp->window; - struct grid_cell gc; - u_int idx, px, py, i, j, xoff, yoff, sx, sy; - int colour, active_colour; - char buf[16], *ptr; - size_t len; - - if (wp->xoff + wp->sx <= ctx->ox || - wp->xoff >= ctx->ox + ctx->sx || - wp->yoff + wp->sy <= ctx->oy || - wp->yoff >= ctx->oy + ctx->sy) - return; - - if (wp->xoff >= ctx->ox && wp->xoff + wp->sx <= ctx->ox + ctx->sx) { - /* All visible. */ - xoff = wp->xoff - ctx->ox; - sx = wp->sx; - } else if (wp->xoff < ctx->ox && - wp->xoff + wp->sx > ctx->ox + ctx->sx) { - /* Both left and right not visible. */ - xoff = 0; - sx = ctx->sx; - } else if (wp->xoff < ctx->ox) { - /* Left not visible. */ - xoff = 0; - sx = wp->sx - (ctx->ox - wp->xoff); - } else { - /* Right not visible. */ - xoff = wp->xoff - ctx->ox; - sx = wp->sx - xoff; - } - if (wp->yoff >= ctx->oy && wp->yoff + wp->sy <= ctx->oy + ctx->sy) { - /* All visible. */ - yoff = wp->yoff - ctx->oy; - sy = wp->sy; - } else if (wp->yoff < ctx->oy && - wp->yoff + wp->sy > ctx->oy + ctx->sy) { - /* Both top and bottom not visible. */ - yoff = 0; - sy = ctx->sy; - } else if (wp->yoff < ctx->oy) { - /* Top not visible. */ - yoff = 0; - sy = wp->sy - (ctx->oy - wp->yoff); - } else { - /* Bottom not visible. */ - yoff = wp->yoff - ctx->oy; - sy = wp->sy - yoff; - } - - if (ctx->top) - yoff += ctx->lines; - px = sx / 2; - py = sy / 2; - - if (window_pane_index(wp, &idx) != 0) - fatalx("index not found"); - len = xsnprintf(buf, sizeof buf, "%u", idx); - - if (sx < len) - return; - colour = options_get_number(oo, "display-panes-colour"); - active_colour = options_get_number(oo, "display-panes-active-colour"); - - if (sx < len * 6 || sy < 5) { - tty_cursor(tty, xoff + px - len / 2, yoff + py); - goto draw_text; - } - - px -= len * 3; - py -= 2; - - memcpy(&gc, &grid_default_cell, sizeof gc); - if (w->active == wp) - gc.bg = active_colour; - else - gc.bg = colour; - gc.flags |= GRID_FLAG_NOPALETTE; - - tty_attributes(tty, &gc, wp); - for (ptr = buf; *ptr != '\0'; ptr++) { - if (*ptr < '0' || *ptr > '9') - continue; - idx = *ptr - '0'; - - for (j = 0; j < 5; j++) { - for (i = px; i < px + 5; i++) { - tty_cursor(tty, xoff + i, yoff + py + j); - if (window_clock_table[idx][j][i - px]) - tty_putc(tty, ' '); - } - } - px += 6; - } - - len = xsnprintf(buf, sizeof buf, "%ux%u", wp->sx, wp->sy); - if (sx < len || sy < 6) - return; - tty_cursor(tty, xoff + sx - len, yoff); - -draw_text: - memcpy(&gc, &grid_default_cell, sizeof gc); - if (w->active == wp) - gc.fg = active_colour; - else - gc.fg = colour; - gc.flags |= GRID_FLAG_NOPALETTE; - - tty_attributes(tty, &gc, wp); - tty_puts(tty, buf); - - tty_cursor(tty, 0, 0); -} diff --git a/usr.bin/tmux/server-client.c b/usr.bin/tmux/server-client.c index 7b4bab1f55d..caf9044574b 100644 --- a/usr.bin/tmux/server-client.c +++ b/usr.bin/tmux/server-client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: server-client.c,v 1.280 2019/05/07 11:24:03 nicm Exp $ */ +/* $OpenBSD: server-client.c,v 1.281 2019/05/07 20:01:41 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -43,8 +43,7 @@ static void server_client_check_redraw(struct client *); static void server_client_set_title(struct client *); static void server_client_reset_state(struct client *); static int server_client_assume_paste(struct session *); -static void server_client_clear_identify(struct client *, - struct window_pane *); +static void server_client_clear_overlay(struct client *); static void server_client_dispatch(struct imsg *, void *); static void server_client_dispatch_command(struct client *, struct imsg *); @@ -66,44 +65,53 @@ server_client_how_many(void) return (n); } -/* Identify mode callback. */ +/* Overlay timer callback. */ static void -server_client_callback_identify(__unused int fd, __unused short events, - void *data) +server_client_overlay_timer(__unused int fd, __unused short events, void *data) { - server_client_clear_identify(data, NULL); + server_client_clear_overlay(data); } -/* Set identify mode on client. */ +/* Set an overlay on client. */ void -server_client_set_identify(struct client *c, u_int delay) +server_client_set_overlay(struct client *c, u_int delay, overlay_draw_cb drawcb, + overlay_key_cb keycb, overlay_free_cb freecb, void *data) { struct timeval tv; tv.tv_sec = delay / 1000; tv.tv_usec = (delay % 1000) * 1000L; - if (event_initialized(&c->identify_timer)) - evtimer_del(&c->identify_timer); - evtimer_set(&c->identify_timer, server_client_callback_identify, c); + if (event_initialized(&c->overlay_timer)) + evtimer_del(&c->overlay_timer); + evtimer_set(&c->overlay_timer, server_client_overlay_timer, c); if (delay != 0) - evtimer_add(&c->identify_timer, &tv); + evtimer_add(&c->overlay_timer, &tv); + + c->overlay_draw = drawcb; + c->overlay_key = keycb; + c->overlay_free = freecb; + c->overlay_data = data; - c->flags |= CLIENT_IDENTIFY; c->tty.flags |= (TTY_FREEZE|TTY_NOCURSOR); server_redraw_client(c); } -/* Clear identify mode on client. */ +/* Clear overlay mode on client. */ static void -server_client_clear_identify(struct client *c, struct window_pane *wp) +server_client_clear_overlay(struct client *c) { - if (~c->flags & CLIENT_IDENTIFY) + if (c->overlay_draw == NULL) return; - c->flags &= ~CLIENT_IDENTIFY; - if (c->identify_callback != NULL) - c->identify_callback(c, wp); + if (event_initialized(&c->overlay_timer)) + evtimer_del(&c->overlay_timer); + + if (c->overlay_free != NULL) + c->overlay_free(c); + + c->overlay_draw = NULL; + c->overlay_key = NULL; c->tty.flags &= ~(TTY_FREEZE|TTY_NOCURSOR); server_redraw_client(c); @@ -257,7 +265,7 @@ server_client_lost(struct client *c) c->flags |= CLIENT_DEAD; - server_client_clear_identify(c, NULL); + server_client_clear_overlay(c); status_prompt_clear(c); status_message_clear(c); @@ -291,9 +299,6 @@ server_client_lost(struct client *c) key_bindings_unref_table(c->keytable); - if (event_initialized(&c->identify_timer)) - evtimer_del(&c->identify_timer); - free(c->message_string); if (event_initialized(&c->message_timer)) evtimer_del(&c->message_timer); @@ -1016,21 +1021,9 @@ server_client_key_callback(struct cmdq_item *item, void *data) fatal("gettimeofday failed"); session_update_activity(s, &c->activity_time); - /* Number keys jump to pane in identify mode. */ - if (c->flags & CLIENT_IDENTIFY && key >= '0' && key <= '9') { - if (c->flags & CLIENT_READONLY) - goto out; - window_unzoom(w); - wp = window_pane_at_index(w, key - '0'); - server_client_clear_identify(c, wp); - goto out; - } - /* Handle status line. */ - if (!(c->flags & CLIENT_READONLY)) { + if (~c->flags & CLIENT_READONLY) status_message_clear(c); - server_client_clear_identify(c, NULL); - } if (c->prompt_string != NULL) { if (c->flags & CLIENT_READONLY) goto out; @@ -1211,27 +1204,19 @@ int server_client_handle_key(struct client *c, struct key_event *event) { struct session *s = c->session; - struct window *w; - struct window_pane *wp = NULL; struct cmdq_item *item; /* Check the client is good to accept input. */ if (s == NULL || (c->flags & (CLIENT_DEAD|CLIENT_SUSPENDED)) != 0) return (0); - w = s->curw->window; /* - * Key presses in identify mode are a special case. The queue might be + * Key presses in overlay mode are a special case. The queue might be * blocked so they need to be processed immediately rather than queued. */ - if (c->flags & CLIENT_IDENTIFY) { - if (c->flags & CLIENT_READONLY) - return (0); - if (event->key >= '0' && event->key <= '9') { - window_unzoom(w); - wp = window_pane_at_index(w, event->key - '0'); - } - server_client_clear_identify(c, wp); + if ((~c->flags & CLIENT_READONLY) && c->overlay_key != NULL) { + if (c->overlay_key(c, event) != 0) + server_client_clear_overlay(c); return (0); } diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h index 8349fecd3fc..e01874b37bf 100644 --- a/usr.bin/tmux/tmux.h +++ b/usr.bin/tmux/tmux.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tmux.h,v 1.889 2019/05/07 11:24:03 nicm Exp $ */ +/* $OpenBSD: tmux.h,v 1.890 2019/05/07 20:01:41 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -727,6 +727,21 @@ struct screen_write_ctx { u_int skipped; }; +/* Screen redraw context. */ +struct screen_redraw_ctx { + struct client *c; + + u_int statuslines; + int statustop; + + int pane_status; + + u_int sx; + u_int sy; + u_int ox; + u_int oy; +}; + /* Screen size. */ #define screen_size_x(s) ((s)->grid->sx) #define screen_size_y(s) ((s)->grid->sy) @@ -1374,6 +1389,9 @@ struct status_line { /* Client connection. */ typedef int (*prompt_input_cb)(struct client *, void *, const char *, int); typedef void (*prompt_free_cb)(void *); +typedef void (*overlay_draw_cb)(struct client *, struct screen_redraw_ctx *); +typedef int (*overlay_key_cb)(struct client *, struct key_event *); +typedef void (*overlay_free_cb)(struct client *); struct client { const char *name; struct tmuxpeer *peer; @@ -1423,7 +1441,7 @@ struct client { #define CLIENT_REPEAT 0x20 #define CLIENT_SUSPENDED 0x40 #define CLIENT_ATTACHED 0x80 -#define CLIENT_IDENTIFY 0x100 +/* 0x100 unused */ #define CLIENT_DEAD 0x200 #define CLIENT_REDRAWBORDERS 0x400 #define CLIENT_READONLY 0x800 @@ -1452,12 +1470,6 @@ struct client { int flags; struct key_table *keytable; - struct event identify_timer; - void (*identify_callback)(struct client *, - struct window_pane *); - void *identify_callback_data; - struct cmdq_item *identify_callback_item; - char *message_string; struct event message_timer; u_int message_next; @@ -1488,6 +1500,12 @@ struct client { u_int pan_ox; u_int pan_oy; + overlay_draw_cb overlay_draw; + overlay_key_cb overlay_key; + overlay_free_cb overlay_free; + void *overlay_data; + struct event overlay_timer; + TAILQ_ENTRY(client) entry; }; TAILQ_HEAD(clients, client); @@ -2008,7 +2026,8 @@ void server_add_accept(int); /* server-client.c */ u_int server_client_how_many(void); -void server_client_set_identify(struct client *, u_int); +void server_client_set_overlay(struct client *, u_int, overlay_draw_cb, + overlay_key_cb, overlay_free_cb, void *); void server_client_set_key_table(struct client *, const char *); const char *server_client_get_key_table(struct client *); int server_client_check_nested(struct client *); |