version 1.54, 2018/08/19 20:13:07 |
version 1.55, 2018/10/18 08:38:01 |
|
|
|
|
u_int sx; |
u_int sx; |
u_int sy; |
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 *, |
|
struct window_pane *); |
static void screen_redraw_draw_number(struct screen_redraw_ctx *, |
static void screen_redraw_draw_number(struct screen_redraw_ctx *, |
struct window_pane *); |
struct window_pane *); |
|
|
|
|
{ |
{ |
struct client *c = ctx->c; |
struct client *c = ctx->c; |
struct window *w = c->session->curw->window; |
struct window *w = c->session->curw->window; |
struct options *oo = c->session->options; |
|
struct tty *tty = &c->tty; |
struct tty *tty = &c->tty; |
struct window_pane *wp; |
struct window_pane *wp; |
int spos; |
struct screen *s; |
u_int yoff; |
u_int i, x, width, xoff, yoff, size; |
|
|
spos = options_get_number(oo, "status-position"); |
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; |
continue; |
|
s = &wp->status_screen; |
|
|
|
size = wp->status_size; |
if (ctx->pane_status == CELL_STATUS_TOP) |
if (ctx->pane_status == CELL_STATUS_TOP) |
yoff = wp->yoff - 1; |
yoff = wp->yoff - 1; |
else |
else |
yoff = wp->yoff + wp->sy; |
yoff = wp->yoff + wp->sy; |
if (spos == 0) |
xoff = wp->xoff + 2; |
yoff += 1; |
|
|
|
tty_draw_line(tty, NULL, &wp->status_screen, 0, wp->xoff + 2, |
if (xoff + size <= ctx->ox || |
yoff); |
xoff >= ctx->ox + ctx->sx || |
|
yoff < ctx->oy || |
|
yoff >= ctx->oy + ctx->sy) |
|
continue; |
|
|
|
if (xoff >= ctx->ox && xoff + size <= ctx->ox + ctx->sx) { |
|
/* All visible. */ |
|
i = 0; |
|
x = xoff - ctx->ox; |
|
width = size; |
|
} else if (xoff < ctx->ox && xoff + size > ctx->ox + ctx->sx) { |
|
/* Both left and right not visible. */ |
|
i = ctx->ox; |
|
x = 0; |
|
width = ctx->sx; |
|
} else if (xoff < ctx->ox) { |
|
/* Left not visible. */ |
|
i = ctx->ox - xoff; |
|
x = 0; |
|
width = size - i; |
|
} else { |
|
/* Right not visible. */ |
|
i = 0; |
|
x = xoff - ctx->ox; |
|
width = size - x; |
|
} |
|
|
|
if (ctx->top) |
|
yoff += ctx->lines; |
|
tty_draw_line(tty, NULL, s, i, 0, width, x, yoff - ctx->oy); |
} |
} |
tty_cursor(tty, 0, 0); |
tty_cursor(tty, 0, 0); |
} |
} |
|
|
memset(ctx, 0, sizeof *ctx); |
memset(ctx, 0, sizeof *ctx); |
ctx->c = c; |
ctx->c = c; |
|
|
ctx->lines = tty_status_lines(c); |
ctx->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) |
if (ctx->lines != 0 && options_get_number(oo, "status-position") == 0) |
ctx->top = 1; |
ctx->top = 1; |
ctx->pane_status = options_get_number(wo, "pane-border-status"); |
ctx->pane_status = options_get_number(wo, "pane-border-status"); |
|
|
ctx->sx = c->tty.sx; |
tty_window_offset(&c->tty, &ctx->ox, &ctx->oy, &ctx->sx, &ctx->sy); |
ctx->sy = c->tty.sy - ctx->lines; |
|
|
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); |
} |
} |
|
|
/* Redraw entire screen. */ |
/* Redraw entire screen. */ |
|
|
tty_reset(&c->tty); |
tty_reset(&c->tty); |
} |
} |
|
|
/* Draw a single pane. */ |
/* Redraw a single pane. */ |
void |
void |
screen_redraw_pane(struct client *c, struct window_pane *wp) |
screen_redraw_pane(struct client *c, struct window_pane *wp) |
{ |
{ |
u_int i, yoff; |
struct screen_redraw_ctx ctx; |
|
|
if (!window_pane_visible(wp)) |
if (!window_pane_visible(wp)) |
return; |
return; |
|
|
yoff = wp->yoff; |
screen_redraw_set_context(c, &ctx); |
if (status_at_line(c) == 0) |
|
yoff += status_line_size(c->session); |
|
|
|
log_debug("%s: redraw pane %%%u (at %u,%u)", c->name, wp->id, |
screen_redraw_draw_pane(&ctx, wp); |
wp->xoff, yoff); |
|
|
|
for (i = 0; i < wp->sy; i++) |
|
tty_draw_pane(&c->tty, wp, i, wp->xoff, yoff); |
|
tty_reset(&c->tty); |
tty_reset(&c->tty); |
} |
} |
|
|
/* Draw a border cell. */ |
/* Draw a border cell. */ |
static void |
static void |
screen_redraw_draw_borders_cell(struct screen_redraw_ctx *ctx, u_int x, u_int y, |
screen_redraw_draw_borders_cell(struct screen_redraw_ctx *ctx, u_int i, u_int j, |
int small, u_int msgx, u_int msgy, struct grid_cell *m_active_gc, |
struct grid_cell *m_active_gc, struct grid_cell *active_gc, |
struct grid_cell *active_gc, struct grid_cell *m_other_gc, |
struct grid_cell *m_other_gc, struct grid_cell *other_gc) |
struct grid_cell *other_gc) |
|
{ |
{ |
struct client *c = ctx->c; |
struct client *c = ctx->c; |
struct session *s = c->session; |
struct session *s = c->session; |
|
|
struct window_pane *wp; |
struct window_pane *wp; |
struct window_pane *active = w->active; |
struct window_pane *active = w->active; |
struct window_pane *marked = marked_pane.wp; |
struct window_pane *marked = marked_pane.wp; |
u_int type; |
u_int type, x = ctx->ox + i, y = ctx->oy + j; |
int flag, pane_status = ctx->pane_status; |
int flag, pane_status = ctx->pane_status; |
|
|
type = screen_redraw_check_cell(c, x, y, pane_status, &wp); |
type = screen_redraw_check_cell(c, x, y, pane_status, &wp); |
if (type == CELL_INSIDE) |
if (type == CELL_INSIDE) |
return; |
return; |
if (type == CELL_OUTSIDE && small && x > msgx && y == msgy) |
|
return; |
|
flag = screen_redraw_check_is(x, y, type, pane_status, w, active, wp); |
flag = screen_redraw_check_is(x, y, type, pane_status, w, active, wp); |
|
|
if (server_is_marked(s, s->curw, marked_pane.wp) && |
if (server_is_marked(s, s->curw, marked_pane.wp) && |
|
|
else |
else |
tty_attributes(tty, other_gc, NULL); |
tty_attributes(tty, other_gc, NULL); |
if (ctx->top) |
if (ctx->top) |
tty_cursor(tty, x, ctx->lines + y); |
tty_cursor(tty, i, ctx->lines + j); |
else |
else |
tty_cursor(tty, x, y); |
tty_cursor(tty, i, j); |
tty_putc(tty, CELL_BORDERS[type]); |
tty_putc(tty, CELL_BORDERS[type]); |
} |
} |
|
|
|
|
struct client *c = ctx->c; |
struct client *c = ctx->c; |
struct session *s = c->session; |
struct session *s = c->session; |
struct window *w = s->curw->window; |
struct window *w = s->curw->window; |
struct options *oo = w->options; |
|
struct tty *tty = &c->tty; |
struct tty *tty = &c->tty; |
|
struct options *oo = w->options; |
struct grid_cell m_active_gc, active_gc, m_other_gc, other_gc; |
struct grid_cell m_active_gc, active_gc, m_other_gc, other_gc; |
struct grid_cell msg_gc; |
u_int i, j; |
u_int i, j, msgx = 0, msgy = 0; |
|
int small, flags; |
|
char msg[256]; |
|
const char *tmp; |
|
size_t msglen = 0; |
|
|
|
small = (ctx->sy + ctx->top > w->sy) || (ctx->sx > w->sx); |
log_debug("%s: %s @%u", __func__, c->name, w->id); |
if (small) { |
|
flags = w->flags & (WINDOW_FORCEWIDTH|WINDOW_FORCEHEIGHT); |
|
if (flags == (WINDOW_FORCEWIDTH|WINDOW_FORCEHEIGHT)) |
|
tmp = "force-width, force-height"; |
|
else if (flags == WINDOW_FORCEWIDTH) |
|
tmp = "force-width"; |
|
else if (flags == WINDOW_FORCEHEIGHT) |
|
tmp = "force-height"; |
|
else if (c->flags & CLIENT_STATUSOFF) |
|
tmp = "status line"; |
|
else |
|
tmp = "a smaller client"; |
|
xsnprintf(msg, sizeof msg, "(size %ux%u from %s)", |
|
w->sx, w->sy, tmp); |
|
msglen = strlen(msg); |
|
|
|
if (ctx->sy - 1 + ctx->top > w->sy && ctx->sx >= msglen) { |
|
msgx = ctx->sx - msglen; |
|
msgy = ctx->sy - 1 + ctx->top; |
|
} else if (ctx->sx - w->sx > msglen) { |
|
msgx = ctx->sx - msglen; |
|
msgy = ctx->sy - 1 + ctx->top; |
|
} else |
|
small = 0; |
|
} |
|
|
|
style_apply(&other_gc, oo, "pane-border-style"); |
style_apply(&other_gc, oo, "pane-border-style"); |
style_apply(&active_gc, oo, "pane-active-border-style"); |
style_apply(&active_gc, oo, "pane-active-border-style"); |
active_gc.attr = other_gc.attr = GRID_ATTR_CHARSET; |
active_gc.attr = other_gc.attr = GRID_ATTR_CHARSET; |
|
|
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 < ctx->sy; j++) { |
for (j = 0; j < tty->sy - ctx->lines; j++) { |
for (i = 0; i < ctx->sx; i++) { |
for (i = 0; i < tty->sx; i++) { |
screen_redraw_draw_borders_cell(ctx, i, j, small, |
screen_redraw_draw_borders_cell(ctx, i, j, |
msgx, msgy, &m_active_gc, &active_gc, &m_other_gc, |
&m_active_gc, &active_gc, &m_other_gc, &other_gc); |
&other_gc); |
|
} |
} |
} |
} |
|
|
if (small) { |
|
memcpy(&msg_gc, &grid_default_cell, sizeof msg_gc); |
|
tty_attributes(tty, &msg_gc, NULL); |
|
tty_cursor(tty, msgx, msgy); |
|
tty_puts(tty, msg); |
|
} |
|
} |
} |
|
|
/* Draw the panes. */ |
/* Draw the panes. */ |
|
|
{ |
{ |
struct client *c = ctx->c; |
struct client *c = ctx->c; |
struct window *w = c->session->curw->window; |
struct window *w = c->session->curw->window; |
struct tty *tty = &c->tty; |
|
struct window_pane *wp; |
struct window_pane *wp; |
u_int i, y; |
|
|
|
if (ctx->top) |
log_debug("%s: %s @%u", __func__, c->name, w->id); |
y = ctx->lines; |
|
else |
|
y = 0; |
|
TAILQ_FOREACH(wp, &w->panes, entry) { |
TAILQ_FOREACH(wp, &w->panes, entry) { |
if (!window_pane_visible(wp)) |
if (!window_pane_visible(wp)) |
continue; |
continue; |
for (i = 0; i < wp->sy; i++) |
screen_redraw_draw_pane(ctx, wp); |
tty_draw_pane(tty, wp, i, wp->xoff, y + wp->yoff); |
|
if (c->flags & CLIENT_IDENTIFY) |
if (c->flags & CLIENT_IDENTIFY) |
screen_redraw_draw_number(ctx, wp); |
screen_redraw_draw_number(ctx, wp); |
} |
} |
|
|
screen_redraw_draw_status(struct screen_redraw_ctx *ctx) |
screen_redraw_draw_status(struct screen_redraw_ctx *ctx) |
{ |
{ |
struct client *c = ctx->c; |
struct client *c = ctx->c; |
|
struct window *w = c->session->curw->window; |
struct tty *tty = &c->tty; |
struct tty *tty = &c->tty; |
|
struct screen *s = &c->status.status; |
u_int i, y; |
u_int i, y; |
|
|
|
log_debug("%s: %s @%u", __func__, c->name, w->id); |
|
|
if (ctx->top) |
if (ctx->top) |
y = 0; |
y = 0; |
else |
else |
y = ctx->sy; |
y = c->tty.sy - ctx->lines; |
for (i = 0; i < ctx->lines; i++) |
for (i = 0; i < ctx->lines; i++) |
tty_draw_line(tty, NULL, &c->status.status, i, 0, y); |
tty_draw_line(tty, NULL, s, 0, i, UINT_MAX, 0, y + i); |
} |
} |
|
|
|
/* Draw one pane. */ |
|
static void |
|
screen_redraw_draw_pane(struct screen_redraw_ctx *ctx, struct window_pane *wp) |
|
{ |
|
struct client *c = ctx->c; |
|
struct window *w = c->session->curw->window; |
|
struct tty *tty = &c->tty; |
|
struct screen *s; |
|
u_int i, j, top, x, y, width; |
|
|
|
log_debug("%s: %s @%u %%%u", __func__, c->name, w->id, wp->id); |
|
|
|
if (wp->xoff + wp->sx <= ctx->ox || wp->xoff >= ctx->ox + ctx->sx) |
|
return; |
|
if (ctx->top) |
|
top = ctx->lines; |
|
else |
|
top = 0; |
|
|
|
s = wp->screen; |
|
for (j = 0; j < wp->sy; j++) { |
|
if (wp->yoff + j < ctx->oy || wp->yoff + j >= ctx->oy + ctx->sy) |
|
continue; |
|
y = top + wp->yoff + j - ctx->oy; |
|
|
|
if (wp->xoff >= ctx->ox && |
|
wp->xoff + wp->sx <= ctx->ox + ctx->sx) { |
|
/* All visible. */ |
|
i = 0; |
|
x = wp->xoff - ctx->ox; |
|
width = wp->sx; |
|
} else if (wp->xoff < ctx->ox && |
|
wp->xoff + wp->sx > ctx->ox + ctx->sx) { |
|
/* Both left and right not visible. */ |
|
i = ctx->ox; |
|
x = 0; |
|
width = ctx->sx; |
|
} else if (wp->xoff < ctx->ox) { |
|
/* Left not visible. */ |
|
i = ctx->ox - wp->xoff; |
|
x = 0; |
|
width = wp->sx - i; |
|
} else { |
|
/* Right not visible. */ |
|
i = 0; |
|
x = wp->xoff - ctx->ox; |
|
width = ctx->sx - x; |
|
} |
|
log_debug("%s: %s %%%u line %u,%u at %u,%u, width %u", |
|
__func__, c->name, wp->id, i, j, x, y, width); |
|
|
|
tty_draw_line(tty, wp, s, i, j, width, x, y); |
|
} |
|
} |
|
|
/* Draw number on a pane. */ |
/* Draw number on a pane. */ |
static void |
static void |
screen_redraw_draw_number(struct screen_redraw_ctx *ctx, struct window_pane *wp) |
screen_redraw_draw_number(struct screen_redraw_ctx *ctx, struct window_pane *wp) |
|
|
struct options *oo = s->options; |
struct options *oo = s->options; |
struct window *w = wp->window; |
struct window *w = wp->window; |
struct grid_cell gc; |
struct grid_cell gc; |
u_int idx, px, py, i, j, xoff, yoff; |
u_int idx, px, py, i, j, xoff, yoff, sx, sy; |
int colour, active_colour; |
int colour, active_colour; |
char buf[16], *ptr; |
char buf[16], *ptr; |
size_t len; |
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) |
if (window_pane_index(wp, &idx) != 0) |
fatalx("index not found"); |
fatalx("index not found"); |
len = xsnprintf(buf, sizeof buf, "%u", idx); |
len = xsnprintf(buf, sizeof buf, "%u", idx); |
|
|
if (wp->sx < len) |
if (sx < len) |
return; |
return; |
colour = options_get_number(oo, "display-panes-colour"); |
colour = options_get_number(oo, "display-panes-colour"); |
active_colour = options_get_number(oo, "display-panes-active-colour"); |
active_colour = options_get_number(oo, "display-panes-active-colour"); |
|
|
px = wp->sx / 2; py = wp->sy / 2; |
if (sx < len * 6 || sy < 5) { |
xoff = wp->xoff; yoff = wp->yoff; |
|
|
|
if (ctx->top) |
|
yoff += ctx->lines; |
|
|
|
if (wp->sx < len * 6 || wp->sy < 5) { |
|
tty_cursor(tty, xoff + px - len / 2, yoff + py); |
tty_cursor(tty, xoff + px - len / 2, yoff + py); |
goto draw_text; |
goto draw_text; |
} |
} |
|
|
} |
} |
|
|
len = xsnprintf(buf, sizeof buf, "%ux%u", wp->sx, wp->sy); |
len = xsnprintf(buf, sizeof buf, "%ux%u", wp->sx, wp->sy); |
if (wp->sx < len || wp->sy < 6) |
if (sx < len || sy < 6) |
return; |
return; |
tty_cursor(tty, xoff + wp->sx - len, yoff); |
tty_cursor(tty, xoff + sx - len, yoff); |
|
|
draw_text: |
draw_text: |
memcpy(&gc, &grid_default_cell, sizeof gc); |
memcpy(&gc, &grid_default_cell, sizeof gc); |