version 1.60, 2019/04/17 14:41:08 |
version 1.61, 2019/05/07 20:01:41 |
|
|
|
|
#include "tmux.h" |
#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_borders(struct screen_redraw_ctx *); |
static void screen_redraw_draw_panes(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_status(struct screen_redraw_ctx *); |
static void screen_redraw_draw_pane(struct screen_redraw_ctx *, |
static void screen_redraw_draw_pane(struct screen_redraw_ctx *, |
struct window_pane *); |
struct window_pane *); |
static void screen_redraw_draw_number(struct screen_redraw_ctx *, |
|
struct window_pane *); |
|
|
|
#define CELL_INSIDE 0 |
#define CELL_INSIDE 0 |
#define CELL_LEFTRIGHT 1 |
#define CELL_LEFTRIGHT 1 |
|
|
width = size - x; |
width = size - x; |
} |
} |
|
|
if (ctx->top) |
if (ctx->statustop) |
yoff += ctx->lines; |
yoff += ctx->statuslines; |
tty_draw_line(tty, NULL, s, i, 0, width, x, yoff - ctx->oy); |
tty_draw_line(tty, NULL, s, i, 0, width, x, yoff - ctx->oy); |
} |
} |
tty_cursor(tty, 0, 0); |
tty_cursor(tty, 0, 0); |
|
|
struct options *oo = s->options; |
struct options *oo = s->options; |
struct window *w = s->curw->window; |
struct window *w = s->curw->window; |
struct options *wo = w->options; |
struct options *wo = w->options; |
|
u_int lines; |
|
|
memset(ctx, 0, sizeof *ctx); |
memset(ctx, 0, sizeof *ctx); |
ctx->c = c; |
ctx->c = c; |
|
|
ctx->lines = status_line_size(c); |
lines = status_line_size(c); |
if (c->message_string != NULL || c->prompt_string != NULL) |
if (c->message_string != NULL || c->prompt_string != NULL) |
ctx->lines = (ctx->lines == 0) ? 1 : ctx->lines; |
lines = (lines == 0) ? 1 : lines; |
if (ctx->lines != 0 && options_get_number(oo, "status-position") == 0) |
if (lines != 0 && options_get_number(oo, "status-position") == 0) |
ctx->top = 1; |
ctx->statustop = 1; |
|
ctx->statuslines = lines; |
|
|
ctx->pane_status = options_get_number(wo, "pane-border-status"); |
ctx->pane_status = options_get_number(wo, "pane-border-status"); |
|
|
tty_window_offset(&c->tty, &ctx->ox, &ctx->oy, &ctx->sx, &ctx->sy); |
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, |
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. */ |
/* Redraw entire screen. */ |
|
|
} |
} |
if (flags & CLIENT_REDRAWWINDOW) |
if (flags & CLIENT_REDRAWWINDOW) |
screen_redraw_draw_panes(&ctx); |
screen_redraw_draw_panes(&ctx); |
if (ctx.lines != 0 && |
if (ctx.statuslines != 0 && |
(flags & (CLIENT_REDRAWSTATUS|CLIENT_REDRAWSTATUSALWAYS))) |
(flags & (CLIENT_REDRAWSTATUS|CLIENT_REDRAWSTATUSALWAYS))) |
screen_redraw_draw_status(&ctx); |
screen_redraw_draw_status(&ctx); |
|
if (c->overlay_draw != NULL) |
|
c->overlay_draw(c, &ctx); |
tty_reset(&c->tty); |
tty_reset(&c->tty); |
} |
} |
|
|
|
|
tty_attributes(tty, active_gc, NULL); |
tty_attributes(tty, active_gc, NULL); |
else |
else |
tty_attributes(tty, other_gc, NULL); |
tty_attributes(tty, other_gc, NULL); |
if (ctx->top) |
if (ctx->statustop) |
tty_cursor(tty, i, ctx->lines + j); |
tty_cursor(tty, i, ctx->statuslines + j); |
else |
else |
tty_cursor(tty, i, j); |
tty_cursor(tty, i, j); |
tty_putc(tty, CELL_BORDERS[type]); |
tty_putc(tty, CELL_BORDERS[type]); |
|
|
memcpy(&m_active_gc, &active_gc, sizeof m_active_gc); |
memcpy(&m_active_gc, &active_gc, sizeof m_active_gc); |
m_active_gc.attr ^= GRID_ATTR_REVERSE; |
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++) { |
for (i = 0; i < tty->sx; i++) { |
screen_redraw_draw_borders_cell(ctx, i, j, |
screen_redraw_draw_borders_cell(ctx, i, j, |
&m_active_gc, &active_gc, &m_other_gc, &other_gc); |
&m_active_gc, &active_gc, &m_other_gc, &other_gc); |
|
|
log_debug("%s: %s @%u", __func__, c->name, w->id); |
log_debug("%s: %s @%u", __func__, c->name, w->id); |
|
|
TAILQ_FOREACH(wp, &w->panes, entry) { |
TAILQ_FOREACH(wp, &w->panes, entry) { |
if (!window_pane_visible(wp)) |
if (window_pane_visible(wp)) |
continue; |
screen_redraw_draw_pane(ctx, wp); |
screen_redraw_draw_pane(ctx, wp); |
|
if (c->flags & CLIENT_IDENTIFY) |
|
screen_redraw_draw_number(ctx, wp); |
|
} |
} |
} |
} |
|
|
|
|
|
|
log_debug("%s: %s @%u", __func__, c->name, w->id); |
log_debug("%s: %s @%u", __func__, c->name, w->id); |
|
|
if (ctx->top) |
if (ctx->statustop) |
y = 0; |
y = 0; |
else |
else |
y = c->tty.sy - ctx->lines; |
y = c->tty.sy - ctx->statuslines; |
for (i = 0; i < ctx->lines; i++) |
for (i = 0; i < ctx->statuslines; i++) |
tty_draw_line(tty, NULL, s, 0, i, UINT_MAX, 0, y + i); |
tty_draw_line(tty, NULL, s, 0, i, UINT_MAX, 0, y + i); |
} |
} |
|
|
|
|
|
|
if (wp->xoff + wp->sx <= ctx->ox || wp->xoff >= ctx->ox + ctx->sx) |
if (wp->xoff + wp->sx <= ctx->ox || wp->xoff >= ctx->ox + ctx->sx) |
return; |
return; |
if (ctx->top) |
if (ctx->statustop) |
top = ctx->lines; |
top = ctx->statuslines; |
else |
else |
top = 0; |
top = 0; |
|
|
|
|
|
|
tty_draw_line(tty, wp, s, i, j, width, x, y); |
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); |
|
} |
} |