mirror of
https://github.com/tmux/tmux.git
synced 2024-12-12 17:38:48 +00:00
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.
This commit is contained in:
parent
d53d3bce59
commit
89db309e10
@ -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]);
|
||||
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_data = xstrdup("select-pane -t '%%'");
|
||||
if (args_has(args, 'b'))
|
||||
c->identify_callback_item = NULL;
|
||||
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);
|
||||
|
||||
out:
|
||||
if (c->identify_callback_item != NULL) {
|
||||
c->identify_callback_item->flags &= ~CMDQ_WAITING;
|
||||
c->identify_callback_item = NULL;
|
||||
}
|
||||
|
||||
free(c->identify_callback_data);
|
||||
c->identify_callback_data = NULL;
|
||||
|
||||
c->identify_callback = NULL;
|
||||
return (1);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
|
||||
if (args_has(args, 'b'))
|
||||
return (CMD_RETURN_NORMAL);
|
||||
return (CMD_RETURN_WAIT);
|
||||
}
|
||||
|
183
screen-redraw.c
183
screen-redraw.c
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
35
tmux.h
35
tmux.h
@ -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 *);
|
||||
|
Loading…
Reference in New Issue
Block a user