version 1.308, 2018/10/18 07:57:57 |
version 1.309, 2018/10/18 08:38:01 |
|
|
static void tty_emulate_repeat(struct tty *, enum tty_code_code, |
static void tty_emulate_repeat(struct tty *, enum tty_code_code, |
enum tty_code_code, u_int); |
enum tty_code_code, u_int); |
static void tty_repeat_space(struct tty *, u_int); |
static void tty_repeat_space(struct tty *, u_int); |
|
static void tty_draw_pane(struct tty *, const struct tty_ctx *, u_int); |
static void tty_cell(struct tty *, const struct grid_cell *, |
static void tty_cell(struct tty *, const struct grid_cell *, |
const struct window_pane *); |
const struct window_pane *); |
static void tty_default_colours(struct grid_cell *, |
static void tty_default_colours(struct grid_cell *, |
|
|
tty_putn(tty, s, n, n); |
tty_putn(tty, s, n, n); |
} |
} |
|
|
/* How many lines are taken up by the status line on this client? */ |
/* Is this window bigger than the terminal? */ |
u_int |
int |
tty_status_lines(struct client *c) |
tty_window_bigger(struct tty *tty) |
{ |
{ |
u_int lines; |
struct client *c = tty->client; |
|
struct window *w = c->session->curw->window; |
|
|
if (c->flags & CLIENT_STATUSOFF) |
return (tty->sx < w->sx || tty->sy - status_line_size(c) < w->sy); |
lines = 0; |
|
else |
|
lines = status_line_size(c->session); |
|
if (c->message_string != NULL || c->prompt_string != NULL) |
|
lines = (lines == 0) ? 1 : lines; |
|
return (lines); |
|
} |
} |
|
|
|
/* What offset should this window be drawn at? */ |
|
int |
|
tty_window_offset(struct tty *tty, u_int *ox, u_int *oy, u_int *sx, u_int *sy) |
|
{ |
|
*ox = tty->oox; |
|
*oy = tty->ooy; |
|
*sx = tty->osx; |
|
*sy = tty->osy; |
|
|
|
return (tty->oflag); |
|
} |
|
|
|
/* What offset should this window be drawn at? */ |
|
static int |
|
tty_window_offset1(struct tty *tty, u_int *ox, u_int *oy, u_int *sx, u_int *sy) |
|
{ |
|
struct client *c = tty->client; |
|
struct window *w = c->session->curw->window; |
|
struct window_pane *wp = w->active; |
|
u_int cx, cy, lines; |
|
|
|
lines = status_line_size(c); |
|
|
|
if (tty->sx >= w->sx && tty->sy - lines >= w->sy) { |
|
*ox = 0; |
|
*oy = 0; |
|
*sx = w->sx; |
|
*sy = w->sy; |
|
|
|
c->pan_window = NULL; |
|
return (0); |
|
} |
|
|
|
*sx = tty->sx; |
|
*sy = tty->sy - lines; |
|
|
|
if (c->pan_window == w) { |
|
if (*sx >= w->sx) |
|
c->pan_ox = 0; |
|
else if (c->pan_ox + *sx > w->sx) |
|
c->pan_ox = w->sx - *sx; |
|
*ox = c->pan_ox; |
|
if (*sy >= w->sy) |
|
c->pan_oy = 0; |
|
else if (c->pan_oy + *sy > w->sy) |
|
c->pan_oy = w->sy - *sy; |
|
*oy = c->pan_oy; |
|
return (1); |
|
} |
|
|
|
if (~wp->screen->mode & MODE_CURSOR) { |
|
*ox = 0; |
|
*oy = 0; |
|
} else { |
|
cx = wp->xoff + wp->screen->cx; |
|
cy = wp->yoff + wp->screen->cy; |
|
|
|
if (cx < *sx) |
|
*ox = 0; |
|
else if (cx > w->sx - *sx) |
|
*ox = w->sx - *sx; |
|
else |
|
*ox = cx - *sx / 2; |
|
|
|
if (cy < *sy) |
|
*oy = 0; |
|
else if (cy > w->sy - *sy) |
|
*oy = w->sy - *sy; |
|
else |
|
*oy = cy - *sy / 2; |
|
} |
|
|
|
c->pan_window = NULL; |
|
return (1); |
|
} |
|
|
|
/* Update stored offsets for a window and redraw if necessary. */ |
|
void |
|
tty_update_window_offset(struct window *w) |
|
{ |
|
struct client *c; |
|
|
|
TAILQ_FOREACH(c, &clients, entry) { |
|
if (c->session != NULL && c->session->curw->window == w) |
|
tty_update_client_offset(c); |
|
} |
|
} |
|
|
|
/* Update stored offsets for a client and redraw if necessary. */ |
|
void |
|
tty_update_client_offset(struct client *c) |
|
{ |
|
u_int ox, oy, sx, sy; |
|
|
|
c->tty.oflag = tty_window_offset1(&c->tty, &ox, &oy, &sx, &sy); |
|
if (ox == c->tty.oox && |
|
oy == c->tty.ooy && |
|
sx == c->tty.osx && |
|
sy == c->tty.osy) |
|
return; |
|
|
|
log_debug ("%s: %s offset has changed (%u,%u %ux%u -> %u,%u %ux%u)", |
|
__func__, c->name, c->tty.oox, c->tty.ooy, c->tty.osx, c->tty.osy, |
|
ox, oy, sx, sy); |
|
|
|
c->tty.oox = ox; |
|
c->tty.ooy = oy; |
|
c->tty.osx = sx; |
|
c->tty.osy = sy; |
|
|
|
c->flags |= (CLIENT_REDRAWWINDOW|CLIENT_REDRAWSTATUS); |
|
} |
|
|
/* |
/* |
* Is the region large enough to be worth redrawing once later rather than |
* Is the region large enough to be worth redrawing once later rather than |
* probably several times now? Currently yes if it is more than 50% of the |
* probably several times now? Currently yes if it is more than 50% of the |
|
|
|
|
if (ctx->ocy < ctx->orupper || ctx->ocy > ctx->orlower) { |
if (ctx->ocy < ctx->orupper || ctx->ocy > ctx->orlower) { |
for (i = ctx->ocy; i < screen_size_y(s); i++) |
for (i = ctx->ocy; i < screen_size_y(s); i++) |
tty_draw_pane(tty, wp, i, ctx->xoff, ctx->yoff); |
tty_draw_pane(tty, ctx, i); |
} else { |
} else { |
for (i = ctx->orupper; i <= ctx->orlower; i++) |
for (i = ctx->orupper; i <= ctx->orlower; i++) |
tty_draw_pane(tty, wp, i, ctx->xoff, ctx->yoff); |
tty_draw_pane(tty, ctx, i); |
} |
} |
} |
} |
|
|
|
/* Is this position visible in the pane? */ |
|
static int |
|
tty_is_visible(struct tty *tty, const struct tty_ctx *ctx, u_int px, u_int py, |
|
u_int nx, u_int ny) |
|
{ |
|
u_int xoff = ctx->xoff + px, yoff = ctx->yoff + py, lines; |
|
|
|
if (!ctx->bigger) |
|
return (1); |
|
|
|
if (status_at_line(tty->client) == 0) |
|
lines = status_line_size(tty->client); |
|
else |
|
lines = 0; |
|
|
|
if (xoff + nx <= ctx->ox || xoff >= ctx->ox + ctx->sx || |
|
yoff + ny <= ctx->oy || yoff >= lines + ctx->oy + ctx->sy) { |
|
return (0); |
|
} |
|
return (1); |
|
} |
|
|
|
/* Clamp line position to visible part of pane. */ |
|
static int |
|
tty_clamp_line(struct tty *tty, const struct tty_ctx *ctx, u_int px, u_int py, |
|
u_int nx, u_int *i, u_int *x, u_int *rx, u_int *ry) |
|
{ |
|
struct window_pane *wp = ctx->wp; |
|
u_int xoff = wp->xoff + px; |
|
|
|
if (!tty_is_visible(tty, ctx, px, py, nx, 1)) |
|
return (0); |
|
*ry = ctx->yoff + py - ctx->oy; |
|
|
|
if (xoff >= ctx->ox && xoff + nx <= ctx->ox + ctx->sx) { |
|
/* All visible. */ |
|
*i = 0; |
|
*x = ctx->xoff + px - ctx->ox; |
|
*rx = nx; |
|
} else if (xoff < ctx->ox && xoff + nx > ctx->ox + ctx->sx) { |
|
/* Both left and right not visible. */ |
|
*i = ctx->ox; |
|
*x = 0; |
|
*rx = ctx->sx; |
|
} else if (xoff < ctx->ox) { |
|
/* Left not visible. */ |
|
*i = ctx->ox - (ctx->xoff + px); |
|
*x = 0; |
|
*rx = nx - *i; |
|
} else { |
|
/* Right not visible. */ |
|
*i = 0; |
|
*x = (ctx->xoff + px) - ctx->ox; |
|
*rx = ctx->sx - *x; |
|
} |
|
if (*rx > nx) |
|
fatalx("%s: x too big, %u > %u", __func__, *rx, nx); |
|
|
|
return (1); |
|
} |
|
|
|
/* Clear a line. */ |
static void |
static void |
tty_clear_line(struct tty *tty, const struct window_pane *wp, u_int py, |
tty_clear_line(struct tty *tty, const struct window_pane *wp, u_int py, |
u_int px, u_int nx, u_int bg) |
u_int px, u_int nx, u_int bg) |
{ |
{ |
log_debug("%s: %u at %u,%u", __func__, nx, px, py); |
struct client *c = tty->client; |
|
|
|
log_debug("%s: %s, %u at %u,%u", __func__, c->name, nx, px, py); |
|
|
/* Nothing to clear. */ |
/* Nothing to clear. */ |
if (nx == 0) |
if (nx == 0) |
return; |
return; |
|
|
tty_repeat_space(tty, nx); |
tty_repeat_space(tty, nx); |
} |
} |
|
|
|
/* Clear a line, adjusting to visible part of pane. */ |
static void |
static void |
|
tty_clear_pane_line(struct tty *tty, const struct tty_ctx *ctx, u_int py, |
|
u_int px, u_int nx, u_int bg) |
|
{ |
|
struct client *c = tty->client; |
|
u_int i, x, rx, ry; |
|
|
|
log_debug("%s: %s, %u at %u,%u", __func__, c->name, nx, px, py); |
|
|
|
if (tty_clamp_line(tty, ctx, px, py, nx, &i, &x, &rx, &ry)) |
|
tty_clear_line(tty, ctx->wp, ry, x, rx, bg); |
|
} |
|
|
|
/* Clamp area position to visible part of pane. */ |
|
static int |
|
tty_clamp_area(struct tty *tty, const struct tty_ctx *ctx, u_int px, u_int py, |
|
u_int nx, u_int ny, u_int *i, u_int *j, u_int *x, u_int *y, u_int *rx, |
|
u_int *ry) |
|
{ |
|
struct window_pane *wp = ctx->wp; |
|
u_int xoff = wp->xoff + px, yoff = wp->yoff + py; |
|
|
|
if (!tty_is_visible(tty, ctx, px, py, nx, ny)) |
|
return (0); |
|
|
|
if (xoff >= ctx->ox && xoff + nx <= ctx->ox + ctx->sx) { |
|
/* All visible. */ |
|
*i = 0; |
|
*x = ctx->xoff + px - ctx->ox; |
|
*rx = nx; |
|
} else if (xoff < ctx->ox && xoff + nx > ctx->ox + ctx->sx) { |
|
/* Both left and right not visible. */ |
|
*i = ctx->ox; |
|
*x = 0; |
|
*rx = ctx->sx; |
|
} else if (xoff < ctx->ox) { |
|
/* Left not visible. */ |
|
*i = ctx->ox - (ctx->xoff + px); |
|
*x = 0; |
|
*rx = nx - *i; |
|
} else { |
|
/* Right not visible. */ |
|
*i = 0; |
|
*x = (ctx->xoff + px) - ctx->ox; |
|
*rx = ctx->sx - *x; |
|
} |
|
if (*rx > nx) |
|
fatalx("%s: x too big, %u > %u", __func__, *rx, nx); |
|
|
|
if (yoff >= ctx->oy && yoff + ny <= ctx->oy + ctx->sy) { |
|
/* All visible. */ |
|
*j = 0; |
|
*y = ctx->yoff + py - ctx->oy; |
|
*ry = ny; |
|
} else if (yoff < ctx->oy && yoff + ny > ctx->oy + ctx->sy) { |
|
/* Both left and right not visible. */ |
|
*j = ctx->oy; |
|
*y = 0; |
|
*ry = ctx->sy; |
|
} else if (yoff < ctx->oy) { |
|
/* Left not visible. */ |
|
*j = ctx->oy - (ctx->yoff + py); |
|
*y = 0; |
|
*ry = ny - *j; |
|
} else { |
|
/* Right not visible. */ |
|
*j = 0; |
|
*y = (ctx->yoff + py) - ctx->oy; |
|
*ry = ctx->sy - *y; |
|
} |
|
if (*ry > ny) |
|
fatalx("%s: y too big, %u > %u", __func__, *ry, ny); |
|
|
|
return (1); |
|
} |
|
|
|
/* Clear an area, adjusting to visible part of pane. */ |
|
static void |
tty_clear_area(struct tty *tty, const struct window_pane *wp, u_int py, |
tty_clear_area(struct tty *tty, const struct window_pane *wp, u_int py, |
u_int ny, u_int px, u_int nx, u_int bg) |
u_int ny, u_int px, u_int nx, u_int bg) |
{ |
{ |
u_int yy; |
struct client *c = tty->client; |
char tmp[64]; |
u_int yy; |
|
char tmp[64]; |
|
|
log_debug("%s: %u,%u at %u,%u", __func__, nx, ny, px, py); |
log_debug("%s: %s, %u,%u at %u,%u", __func__, c->name, nx, ny, px, py); |
|
|
/* Nothing to clear. */ |
/* Nothing to clear. */ |
if (nx == 0 || ny == 0) |
if (nx == 0 || ny == 0) |
|
|
tty_clear_line(tty, wp, yy, px, nx, bg); |
tty_clear_line(tty, wp, yy, px, nx, bg); |
} |
} |
|
|
void |
/* Clear an area in a pane. */ |
tty_draw_pane(struct tty *tty, const struct window_pane *wp, u_int py, u_int ox, |
static void |
u_int oy) |
tty_clear_pane_area(struct tty *tty, const struct tty_ctx *ctx, u_int py, |
|
u_int ny, u_int px, u_int nx, u_int bg) |
{ |
{ |
tty_draw_line(tty, wp, wp->screen, py, ox, oy); |
u_int i, j, x, y, rx, ry; |
|
|
|
if (tty_clamp_area(tty, ctx, px, py, nx, ny, &i, &j, &x, &y, &rx, &ry)) |
|
tty_clear_area(tty, ctx->wp, y, ry, x, rx, bg); |
} |
} |
|
|
|
static void |
|
tty_draw_pane(struct tty *tty, const struct tty_ctx *ctx, u_int py) |
|
{ |
|
struct window_pane *wp = ctx->wp; |
|
struct screen *s = wp->screen; |
|
u_int nx = screen_size_x(s), i, x, rx, ry; |
|
|
|
log_debug("%s: %s %u %d", __func__, tty->client->name, py, ctx->bigger); |
|
|
|
if (!ctx->bigger) { |
|
tty_draw_line(tty, wp, s, 0, py, nx, ctx->xoff, ctx->yoff + py); |
|
return; |
|
} |
|
if (tty_clamp_line(tty, ctx, 0, py, nx, &i, &x, &rx, &ry)) |
|
tty_draw_line(tty, wp, s, i, py, rx, x, ry); |
|
} |
|
|
static const struct grid_cell * |
static const struct grid_cell * |
tty_check_codeset(struct tty *tty, const struct grid_cell *gc) |
tty_check_codeset(struct tty *tty, const struct grid_cell *gc) |
{ |
{ |
|
|
|
|
void |
void |
tty_draw_line(struct tty *tty, const struct window_pane *wp, |
tty_draw_line(struct tty *tty, const struct window_pane *wp, |
struct screen *s, u_int py, u_int ox, u_int oy) |
struct screen *s, u_int px, u_int py, u_int nx, u_int atx, u_int aty) |
{ |
{ |
struct grid *gd = s->grid; |
struct grid *gd = s->grid; |
struct grid_cell gc, last; |
struct grid_cell gc, last; |
const struct grid_cell *gcp; |
const struct grid_cell *gcp; |
u_int i, j, ux, sx, nx, width; |
struct grid_line *gl; |
|
u_int i, j, ux, sx, width; |
int flags, cleared = 0; |
int flags, cleared = 0; |
char buf[512]; |
char buf[512]; |
size_t len, old_len; |
size_t len, old_len; |
u_int cellsize; |
u_int cellsize; |
|
|
|
log_debug("%s: px=%u py=%u nx=%u atx=%u aty=%u", __func__, |
|
px, py, nx, atx, aty); |
|
|
|
/* |
|
* py is the line in the screen to draw. |
|
* px is the start x and nx is the width to draw. |
|
* atx,aty is the line on the terminal to draw it. |
|
*/ |
|
|
flags = (tty->flags & TTY_NOCURSOR); |
flags = (tty->flags & TTY_NOCURSOR); |
tty->flags |= TTY_NOCURSOR; |
tty->flags |= TTY_NOCURSOR; |
tty_update_mode(tty, tty->mode, s); |
tty_update_mode(tty, tty->mode, s); |
|
|
* there may be empty background cells after it (from BCE). |
* there may be empty background cells after it (from BCE). |
*/ |
*/ |
sx = screen_size_x(s); |
sx = screen_size_x(s); |
|
if (nx > sx) |
|
nx = sx; |
cellsize = grid_get_line(gd, gd->hsize + py)->cellsize; |
cellsize = grid_get_line(gd, gd->hsize + py)->cellsize; |
if (sx > cellsize) |
if (sx > cellsize) |
sx = cellsize; |
sx = cellsize; |
if (sx > tty->sx) |
if (sx > tty->sx) |
sx = tty->sx; |
sx = tty->sx; |
|
if (sx > nx) |
|
sx = nx; |
ux = 0; |
ux = 0; |
|
|
|
if (py == 0) |
|
gl = NULL; |
|
else |
|
gl = grid_get_line(gd, gd->hsize + py - 1); |
if (wp == NULL || |
if (wp == NULL || |
py == 0 || |
gl == NULL || |
(~grid_get_line(gd, gd->hsize + py - 1)->flags & GRID_LINE_WRAPPED) || |
(~gl->flags & GRID_LINE_WRAPPED) || |
ox != 0 || |
atx != 0 || |
tty->cx < tty->sx || |
tty->cx < tty->sx || |
screen_size_x(s) < tty->sx) { |
nx < tty->sx) { |
if (screen_size_x(s) < tty->sx && |
if (nx < tty->sx && |
ox == 0 && |
atx == 0 && |
sx != screen_size_x(s) && |
px + sx != nx && |
tty_term_has(tty->term, TTYC_EL1) && |
tty_term_has(tty->term, TTYC_EL1) && |
!tty_fake_bce(tty, wp, 8)) { |
!tty_fake_bce(tty, wp, 8)) { |
tty_default_attributes(tty, wp, 8); |
tty_default_attributes(tty, wp, 8); |
tty_cursor(tty, screen_size_x(s) - 1, oy + py); |
tty_cursor(tty, nx - 1, aty); |
tty_putcode(tty, TTYC_EL1); |
tty_putcode(tty, TTYC_EL1); |
cleared = 1; |
cleared = 1; |
} |
} |
if (sx != 0) |
if (px + sx != 0) |
tty_cursor(tty, ox, oy + py); |
tty_cursor(tty, atx, aty); |
} else |
} else |
log_debug("%s: wrapped line %u", __func__, oy + py); |
log_debug("%s: wrapped line %u", __func__, aty); |
|
|
memcpy(&last, &grid_default_cell, sizeof last); |
memcpy(&last, &grid_default_cell, sizeof last); |
len = 0; |
len = 0; |
width = 0; |
width = 0; |
|
|
for (i = 0; i < sx; i++) { |
for (i = 0; i < sx; i++) { |
grid_view_get_cell(gd, i, py, &gc); |
grid_view_get_cell(gd, px + i, py, &gc); |
gcp = tty_check_codeset(tty, &gc); |
gcp = tty_check_codeset(tty, &gc); |
if (len != 0 && |
if (len != 0 && |
((gcp->attr & GRID_ATTR_CHARSET) || |
((gcp->attr & GRID_ATTR_CHARSET) || |
|
|
gcp->attr != last.attr || |
gcp->attr != last.attr || |
gcp->fg != last.fg || |
gcp->fg != last.fg || |
gcp->bg != last.bg || |
gcp->bg != last.bg || |
ux + width + gcp->data.width >= screen_size_x(s) || |
ux + width + gcp->data.width >= nx || |
(sizeof buf) - len < gcp->data.size)) { |
(sizeof buf) - len < gcp->data.size)) { |
tty_attributes(tty, &last, wp); |
tty_attributes(tty, &last, wp); |
tty_putn(tty, buf, len, width); |
tty_putn(tty, buf, len, width); |
|
|
screen_select_cell(s, &last, gcp); |
screen_select_cell(s, &last, gcp); |
else |
else |
memcpy(&last, gcp, sizeof last); |
memcpy(&last, gcp, sizeof last); |
if (ux + gcp->data.width > screen_size_x(s)) { |
if (ux + gcp->data.width > nx) { |
tty_attributes(tty, &last, wp); |
tty_attributes(tty, &last, wp); |
for (j = 0; j < gcp->data.width; j++) { |
for (j = 0; j < gcp->data.width; j++) { |
if (ux + j > screen_size_x(s)) |
if (ux + j > nx) |
break; |
break; |
tty_putc(tty, ' '); |
tty_putc(tty, ' '); |
ux++; |
ux++; |
|
|
} |
} |
} |
} |
|
|
if (!cleared && ux < screen_size_x(s)) { |
if (!cleared && ux < nx) { |
nx = screen_size_x(s) - ux; |
|
tty_default_attributes(tty, wp, 8); |
tty_default_attributes(tty, wp, 8); |
tty_clear_line(tty, wp, oy + py, ox + ux, nx, 8); |
tty_clear_line(tty, wp, aty, atx + ux, nx - ux, 8); |
} |
} |
|
|
tty->flags = (tty->flags & ~TTY_NOCURSOR) | flags; |
tty->flags = (tty->flags & ~TTY_NOCURSOR) | flags; |
|
|
return (0); |
return (0); |
if (c->session->curw->window != wp->window) |
if (c->session->curw->window != wp->window) |
return (0); |
return (0); |
|
if (wp->layout_cell == NULL) |
|
return (0); |
return (1); |
return (1); |
} |
} |
|
|
|
|
struct window_pane *wp = ctx->wp; |
struct window_pane *wp = ctx->wp; |
struct client *c; |
struct client *c; |
|
|
/* wp can be NULL if updating the screen but not the terminal. */ |
|
if (wp == NULL) |
if (wp == NULL) |
return; |
return; |
|
if (wp->flags & (PANE_REDRAW|PANE_DROP)) |
if ((wp->flags & (PANE_REDRAW|PANE_DROP)) || !window_pane_visible(wp)) |
|
return; |
return; |
|
|
TAILQ_FOREACH(c, &clients, entry) { |
TAILQ_FOREACH(c, &clients, entry) { |
if (!tty_client_ready(c, wp)) |
if (!tty_client_ready(c, wp)) |
continue; |
continue; |
|
|
|
ctx->bigger = tty_window_offset(&c->tty, &ctx->ox, &ctx->oy, |
|
&ctx->sx, &ctx->sy); |
|
|
ctx->xoff = wp->xoff; |
ctx->xoff = wp->xoff; |
ctx->yoff = wp->yoff; |
ctx->yoff = wp->yoff; |
|
|
if (status_at_line(c) == 0) |
if (status_at_line(c) == 0) |
ctx->yoff += status_line_size(c->session); |
ctx->yoff += status_line_size(c); |
|
|
cmdfn(&c->tty, ctx); |
cmdfn(&c->tty, ctx); |
} |
} |
|
|
{ |
{ |
struct window_pane *wp = ctx->wp; |
struct window_pane *wp = ctx->wp; |
|
|
if (!tty_pane_full_width(tty, ctx) || |
if (ctx->bigger || |
|
!tty_pane_full_width(tty, ctx) || |
tty_fake_bce(tty, wp, ctx->bg) || |
tty_fake_bce(tty, wp, ctx->bg) || |
(!tty_term_has(tty->term, TTYC_ICH) && |
(!tty_term_has(tty->term, TTYC_ICH) && |
!tty_term_has(tty->term, TTYC_ICH1))) { |
!tty_term_has(tty->term, TTYC_ICH1))) { |
tty_draw_pane(tty, wp, ctx->ocy, ctx->xoff, ctx->yoff); |
tty_draw_pane(tty, ctx, ctx->ocy); |
return; |
return; |
} |
} |
|
|
|
|
{ |
{ |
struct window_pane *wp = ctx->wp; |
struct window_pane *wp = ctx->wp; |
|
|
if (!tty_pane_full_width(tty, ctx) || |
if (ctx->bigger || |
|
!tty_pane_full_width(tty, ctx) || |
tty_fake_bce(tty, wp, ctx->bg) || |
tty_fake_bce(tty, wp, ctx->bg) || |
(!tty_term_has(tty->term, TTYC_DCH) && |
(!tty_term_has(tty->term, TTYC_DCH) && |
!tty_term_has(tty->term, TTYC_DCH1))) { |
!tty_term_has(tty->term, TTYC_DCH1))) { |
tty_draw_pane(tty, wp, ctx->ocy, ctx->xoff, ctx->yoff); |
tty_draw_pane(tty, ctx, ctx->ocy); |
return; |
return; |
} |
} |
|
|
|
|
void |
void |
tty_cmd_clearcharacter(struct tty *tty, const struct tty_ctx *ctx) |
tty_cmd_clearcharacter(struct tty *tty, const struct tty_ctx *ctx) |
{ |
{ |
|
if (ctx->bigger) { |
|
tty_draw_pane(tty, ctx, ctx->ocy); |
|
return; |
|
} |
|
|
tty_default_attributes(tty, ctx->wp, ctx->bg); |
tty_default_attributes(tty, ctx->wp, ctx->bg); |
|
|
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); |
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); |
|
|
void |
void |
tty_cmd_insertline(struct tty *tty, const struct tty_ctx *ctx) |
tty_cmd_insertline(struct tty *tty, const struct tty_ctx *ctx) |
{ |
{ |
if (!tty_pane_full_width(tty, ctx) || |
if (ctx->bigger || |
|
!tty_pane_full_width(tty, ctx) || |
tty_fake_bce(tty, ctx->wp, ctx->bg) || |
tty_fake_bce(tty, ctx->wp, ctx->bg) || |
!tty_term_has(tty->term, TTYC_CSR) || |
!tty_term_has(tty->term, TTYC_CSR) || |
!tty_term_has(tty->term, TTYC_IL1) || |
!tty_term_has(tty->term, TTYC_IL1) || |
|
|
void |
void |
tty_cmd_deleteline(struct tty *tty, const struct tty_ctx *ctx) |
tty_cmd_deleteline(struct tty *tty, const struct tty_ctx *ctx) |
{ |
{ |
if (!tty_pane_full_width(tty, ctx) || |
if (ctx->bigger || |
|
!tty_pane_full_width(tty, ctx) || |
tty_fake_bce(tty, ctx->wp, ctx->bg) || |
tty_fake_bce(tty, ctx->wp, ctx->bg) || |
!tty_term_has(tty->term, TTYC_CSR) || |
!tty_term_has(tty->term, TTYC_CSR) || |
!tty_term_has(tty->term, TTYC_DL1) || |
!tty_term_has(tty->term, TTYC_DL1) || |
|
|
tty_cmd_clearline(struct tty *tty, const struct tty_ctx *ctx) |
tty_cmd_clearline(struct tty *tty, const struct tty_ctx *ctx) |
{ |
{ |
struct window_pane *wp = ctx->wp; |
struct window_pane *wp = ctx->wp; |
u_int nx, py = ctx->yoff + ctx->ocy; |
u_int nx; |
|
|
tty_default_attributes(tty, wp, ctx->bg); |
tty_default_attributes(tty, wp, ctx->bg); |
|
|
nx = screen_size_x(wp->screen); |
nx = screen_size_x(wp->screen); |
tty_clear_line(tty, wp, py, ctx->xoff, nx, ctx->bg); |
tty_clear_pane_line(tty, ctx, ctx->ocy, 0, nx, ctx->bg); |
} |
} |
|
|
void |
void |
tty_cmd_clearendofline(struct tty *tty, const struct tty_ctx *ctx) |
tty_cmd_clearendofline(struct tty *tty, const struct tty_ctx *ctx) |
{ |
{ |
struct window_pane *wp = ctx->wp; |
struct window_pane *wp = ctx->wp; |
u_int nx, py = ctx->yoff + ctx->ocy; |
u_int nx; |
|
|
tty_default_attributes(tty, wp, ctx->bg); |
tty_default_attributes(tty, wp, ctx->bg); |
|
|
nx = screen_size_x(wp->screen) - ctx->ocx; |
nx = screen_size_x(wp->screen) - ctx->ocx; |
tty_clear_line(tty, wp, py, ctx->xoff + ctx->ocx, nx, ctx->bg); |
tty_clear_pane_line(tty, ctx, ctx->ocy, ctx->ocx, nx, ctx->bg); |
} |
} |
|
|
void |
void |
tty_cmd_clearstartofline(struct tty *tty, const struct tty_ctx *ctx) |
tty_cmd_clearstartofline(struct tty *tty, const struct tty_ctx *ctx) |
{ |
{ |
struct window_pane *wp = ctx->wp; |
struct window_pane *wp = ctx->wp; |
u_int py = ctx->yoff + ctx->ocy; |
|
|
|
tty_default_attributes(tty, wp, ctx->bg); |
tty_default_attributes(tty, wp, ctx->bg); |
|
|
tty_clear_line(tty, wp, py, ctx->xoff, ctx->ocx + 1, ctx->bg); |
tty_clear_pane_line(tty, ctx, ctx->ocy, 0, ctx->ocx + 1, ctx->bg); |
} |
} |
|
|
void |
void |
|
|
if (ctx->ocy != ctx->orupper) |
if (ctx->ocy != ctx->orupper) |
return; |
return; |
|
|
if (!tty_pane_full_width(tty, ctx) || |
if (ctx->bigger || |
|
!tty_pane_full_width(tty, ctx) || |
tty_fake_bce(tty, wp, 8) || |
tty_fake_bce(tty, wp, 8) || |
!tty_term_has(tty->term, TTYC_CSR) || |
!tty_term_has(tty->term, TTYC_CSR) || |
!tty_term_has(tty->term, TTYC_RI) || |
!tty_term_has(tty->term, TTYC_RI) || |
|
|
if (ctx->ocy != ctx->orlower) |
if (ctx->ocy != ctx->orlower) |
return; |
return; |
|
|
if ((!tty_pane_full_width(tty, ctx) && !tty_use_margin(tty)) || |
if (ctx->bigger || |
|
(!tty_pane_full_width(tty, ctx) && !tty_use_margin(tty)) || |
tty_fake_bce(tty, wp, 8) || |
tty_fake_bce(tty, wp, 8) || |
!tty_term_has(tty->term, TTYC_CSR) || |
!tty_term_has(tty->term, TTYC_CSR) || |
wp->sx == 1 || |
wp->sx == 1 || |
|
|
struct window_pane *wp = ctx->wp; |
struct window_pane *wp = ctx->wp; |
u_int i; |
u_int i; |
|
|
if ((!tty_pane_full_width(tty, ctx) && !tty_use_margin(tty)) || |
if (ctx->bigger || |
|
(!tty_pane_full_width(tty, ctx) && !tty_use_margin(tty)) || |
tty_fake_bce(tty, wp, 8) || |
tty_fake_bce(tty, wp, 8) || |
!tty_term_has(tty->term, TTYC_CSR) || |
!tty_term_has(tty->term, TTYC_CSR) || |
wp->sx == 1 || |
wp->sx == 1 || |
|
|
tty_region_pane(tty, ctx, 0, screen_size_y(wp->screen) - 1); |
tty_region_pane(tty, ctx, 0, screen_size_y(wp->screen) - 1); |
tty_margin_off(tty); |
tty_margin_off(tty); |
|
|
px = ctx->xoff; |
px = 0; |
nx = screen_size_x(wp->screen); |
nx = screen_size_x(wp->screen); |
py = ctx->yoff + ctx->ocy + 1; |
py = ctx->ocy + 1; |
ny = screen_size_y(wp->screen) - ctx->ocy - 1; |
ny = screen_size_y(wp->screen) - ctx->ocy - 1; |
|
|
tty_clear_area(tty, wp, py, ny, px, nx, ctx->bg); |
tty_clear_pane_area(tty, ctx, py, ny, px, nx, ctx->bg); |
|
|
px = ctx->xoff + ctx->ocx; |
px = ctx->ocx; |
nx = screen_size_x(wp->screen) - ctx->ocx; |
nx = screen_size_x(wp->screen) - ctx->ocx; |
py = ctx->yoff + ctx->ocy; |
py = ctx->ocy; |
|
|
tty_clear_line(tty, wp, py, px, nx, ctx->bg); |
tty_clear_pane_line(tty, ctx, py, px, nx, ctx->bg); |
} |
} |
|
|
void |
void |
|
|
tty_region_pane(tty, ctx, 0, screen_size_y(wp->screen) - 1); |
tty_region_pane(tty, ctx, 0, screen_size_y(wp->screen) - 1); |
tty_margin_off(tty); |
tty_margin_off(tty); |
|
|
px = ctx->xoff; |
px = 0; |
nx = screen_size_x(wp->screen); |
nx = screen_size_x(wp->screen); |
py = ctx->yoff; |
py = 0; |
ny = ctx->ocy - 1; |
ny = ctx->ocy - 1; |
|
|
tty_clear_area(tty, wp, py, ny, px, nx, ctx->bg); |
tty_clear_pane_area(tty, ctx, py, ny, px, nx, ctx->bg); |
|
|
px = ctx->xoff; |
px = 0; |
nx = ctx->ocx + 1; |
nx = ctx->ocx + 1; |
py = ctx->yoff + ctx->ocy; |
py = ctx->ocy; |
|
|
tty_clear_line(tty, wp, py, px, nx, ctx->bg); |
tty_clear_pane_line(tty, ctx, py, px, nx, ctx->bg); |
} |
} |
|
|
void |
void |
|
|
tty_region_pane(tty, ctx, 0, screen_size_y(wp->screen) - 1); |
tty_region_pane(tty, ctx, 0, screen_size_y(wp->screen) - 1); |
tty_margin_off(tty); |
tty_margin_off(tty); |
|
|
px = ctx->xoff; |
px = 0; |
nx = screen_size_x(wp->screen); |
nx = screen_size_x(wp->screen); |
py = ctx->yoff; |
py = 0; |
ny = screen_size_y(wp->screen); |
ny = screen_size_y(wp->screen); |
|
|
tty_clear_area(tty, wp, py, ny, px, nx, ctx->bg); |
tty_clear_pane_area(tty, ctx, py, ny, px, nx, ctx->bg); |
} |
} |
|
|
void |
void |
|
|
struct screen *s = wp->screen; |
struct screen *s = wp->screen; |
u_int i, j; |
u_int i, j; |
|
|
|
if (ctx->bigger) { |
|
wp->flags |= PANE_REDRAW; |
|
return; |
|
} |
|
|
tty_attributes(tty, &grid_default_cell, wp); |
tty_attributes(tty, &grid_default_cell, wp); |
|
|
tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1); |
tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1); |
|
|
void |
void |
tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx) |
tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx) |
{ |
{ |
if (ctx->xoff + ctx->ocx > tty->sx - 1 && |
if (!tty_is_visible(tty, ctx, ctx->ocx, ctx->ocy, 1, 1)) |
|
return; |
|
|
|
if (ctx->xoff + ctx->ocx - ctx->ox > tty->sx - 1 && |
ctx->ocy == ctx->orlower && |
ctx->ocy == ctx->orlower && |
tty_pane_full_width(tty, ctx)) |
tty_pane_full_width(tty, ctx)) |
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower); |
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower); |
|
|
void |
void |
tty_cmd_cells(struct tty *tty, const struct tty_ctx *ctx) |
tty_cmd_cells(struct tty *tty, const struct tty_ctx *ctx) |
{ |
{ |
|
struct window_pane *wp = ctx->wp; |
|
|
|
if (!tty_is_visible(tty, ctx, ctx->ocx, ctx->ocy, ctx->num, 1)) |
|
return; |
|
|
|
if (ctx->bigger && |
|
(ctx->xoff + ctx->ocx < ctx->ox || |
|
ctx->xoff + ctx->ocx + ctx->num > ctx->ox + ctx->sx)) { |
|
if (!ctx->wrapped || |
|
!tty_pane_full_width(tty, ctx) || |
|
(tty->term->flags & TERM_EARLYWRAP) || |
|
ctx->xoff + ctx->ocx != 0 || |
|
ctx->yoff + ctx->ocy != tty->cy + 1 || |
|
tty->cx < tty->sx || |
|
tty->cy == tty->rlower) |
|
tty_draw_pane(tty, ctx, ctx->ocy); |
|
else |
|
wp->flags |= PANE_REDRAW; |
|
return; |
|
} |
|
|
tty_margin_off(tty); |
tty_margin_off(tty); |
tty_cursor_pane_unless_wrap(tty, ctx, ctx->ocx, ctx->ocy); |
tty_cursor_pane_unless_wrap(tty, ctx, ctx->ocx, ctx->ocy); |
|
|
|
|
tty_region_pane(struct tty *tty, const struct tty_ctx *ctx, u_int rupper, |
tty_region_pane(struct tty *tty, const struct tty_ctx *ctx, u_int rupper, |
u_int rlower) |
u_int rlower) |
{ |
{ |
tty_region(tty, ctx->yoff + rupper, ctx->yoff + rlower); |
tty_region(tty, ctx->yoff + rupper - ctx->oy, |
|
ctx->yoff + rlower - ctx->oy); |
} |
} |
|
|
/* Set region at absolute position. */ |
/* Set region at absolute position. */ |
|
|
static void |
static void |
tty_margin_pane(struct tty *tty, const struct tty_ctx *ctx) |
tty_margin_pane(struct tty *tty, const struct tty_ctx *ctx) |
{ |
{ |
tty_margin(tty, ctx->xoff, ctx->xoff + ctx->wp->sx - 1); |
tty_margin(tty, ctx->xoff - ctx->ox, |
|
ctx->xoff + ctx->wp->sx - 1 - ctx->ox); |
} |
} |
|
|
/* Set margin at absolute position. */ |
/* Set margin at absolute position. */ |
|
|
static void |
static void |
tty_cursor_pane(struct tty *tty, const struct tty_ctx *ctx, u_int cx, u_int cy) |
tty_cursor_pane(struct tty *tty, const struct tty_ctx *ctx, u_int cx, u_int cy) |
{ |
{ |
tty_cursor(tty, ctx->xoff + cx, ctx->yoff + cy); |
tty_cursor(tty, ctx->xoff + cx - ctx->ox, ctx->yoff + cy - ctx->oy); |
} |
} |
|
|
/* Move cursor to absolute position. */ |
/* Move cursor to absolute position. */ |