diff options
Diffstat (limited to 'tty.c')
-rw-r--r-- | tty.c | 495 |
1 files changed, 415 insertions, 80 deletions
@@ -64,6 +64,7 @@ static void tty_redraw_region(struct tty *, const struct tty_ctx *); static void tty_emulate_repeat(struct tty *, enum tty_code_code, enum tty_code_code, 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 *, const struct window_pane *); static void tty_default_colours(struct grid_cell *, @@ -698,19 +699,127 @@ tty_repeat_space(struct tty *tty, u_int n) tty_putn(tty, s, n, n); } -/* How many lines are taken up by the status line on this client? */ -u_int -tty_status_lines(struct client *c) +/* Is this window bigger than the terminal? */ +int +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) - 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); + return (tty->sx < w->sx || tty->sy - status_line_size(c) < w->sy); +} + +/* 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); } /* @@ -770,18 +879,82 @@ tty_redraw_region(struct tty *tty, const struct tty_ctx *ctx) if (ctx->ocy < ctx->orupper || ctx->ocy > ctx->orlower) { 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 { 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 tty_clear_line(struct tty *tty, const struct window_pane *wp, u_int py, 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. */ if (nx == 0) @@ -816,14 +989,93 @@ tty_clear_line(struct tty *tty, const struct window_pane *wp, u_int py, tty_repeat_space(tty, nx); } +/* Clear a line, adjusting to visible part of pane. */ +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, u_int ny, u_int px, u_int nx, u_int bg) { - u_int yy; - char tmp[64]; + struct client *c = tty->client; + 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. */ if (nx == 0 || ny == 0) @@ -886,11 +1138,32 @@ tty_clear_area(struct tty *tty, const struct window_pane *wp, u_int py, tty_clear_line(tty, wp, yy, px, nx, bg); } -void -tty_draw_pane(struct tty *tty, const struct window_pane *wp, u_int py, u_int ox, - u_int oy) +/* Clear an area in a pane. */ +static void +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 * @@ -919,17 +1192,27 @@ tty_check_codeset(struct tty *tty, const struct grid_cell *gc) void 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_cell gc, last; 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; char buf[512]; size_t len, old_len; 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); tty->flags |= TTY_NOCURSOR; tty_update_mode(tty, tty->mode, s); @@ -942,41 +1225,48 @@ tty_draw_line(struct tty *tty, const struct window_pane *wp, * there may be empty background cells after it (from BCE). */ sx = screen_size_x(s); - + if (nx > sx) + nx = sx; cellsize = grid_get_line(gd, gd->hsize + py)->cellsize; if (sx > cellsize) sx = cellsize; if (sx > tty->sx) sx = tty->sx; + if (sx > nx) + sx = nx; ux = 0; + if (py == 0) + gl = NULL; + else + gl = grid_get_line(gd, gd->hsize + py - 1); if (wp == NULL || - py == 0 || - (~grid_get_line(gd, gd->hsize + py - 1)->flags & GRID_LINE_WRAPPED) || - ox != 0 || + gl == NULL || + (~gl->flags & GRID_LINE_WRAPPED) || + atx != 0 || tty->cx < tty->sx || - screen_size_x(s) < tty->sx) { - if (screen_size_x(s) < tty->sx && - ox == 0 && - sx != screen_size_x(s) && + nx < tty->sx) { + if (nx < tty->sx && + atx == 0 && + px + sx != nx && tty_term_has(tty->term, TTYC_EL1) && !tty_fake_bce(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); cleared = 1; } - if (sx != 0) - tty_cursor(tty, ox, oy + py); + if (px + sx != 0) + tty_cursor(tty, atx, aty); } 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); len = 0; width = 0; 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); if (len != 0 && ((gcp->attr & GRID_ATTR_CHARSET) || @@ -984,7 +1274,7 @@ tty_draw_line(struct tty *tty, const struct window_pane *wp, gcp->attr != last.attr || gcp->fg != last.fg || 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)) { tty_attributes(tty, &last, wp); tty_putn(tty, buf, len, width); @@ -998,10 +1288,10 @@ tty_draw_line(struct tty *tty, const struct window_pane *wp, screen_select_cell(s, &last, gcp); else 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); for (j = 0; j < gcp->data.width; j++) { - if (ux + j > screen_size_x(s)) + if (ux + j > nx) break; tty_putc(tty, ' '); ux++; @@ -1034,10 +1324,9 @@ tty_draw_line(struct tty *tty, const struct window_pane *wp, } } - if (!cleared && ux < screen_size_x(s)) { - nx = screen_size_x(s) - ux; + if (!cleared && ux < nx) { 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; @@ -1055,6 +1344,8 @@ tty_client_ready(struct client *c, struct window_pane *wp) return (0); if (c->session->curw->window != wp->window) return (0); + if (wp->layout_cell == NULL) + return (0); return (1); } @@ -1065,21 +1356,23 @@ tty_write(void (*cmdfn)(struct tty *, const struct tty_ctx *), struct window_pane *wp = ctx->wp; struct client *c; - /* wp can be NULL if updating the screen but not the terminal. */ if (wp == NULL) return; - - if ((wp->flags & (PANE_REDRAW|PANE_DROP)) || !window_pane_visible(wp)) + if (wp->flags & (PANE_REDRAW|PANE_DROP)) return; TAILQ_FOREACH(c, &clients, entry) { if (!tty_client_ready(c, wp)) continue; + ctx->bigger = tty_window_offset(&c->tty, &ctx->ox, &ctx->oy, + &ctx->sx, &ctx->sy); + ctx->xoff = wp->xoff; ctx->yoff = wp->yoff; + if (status_at_line(c) == 0) - ctx->yoff += status_line_size(c->session); + ctx->yoff += status_line_size(c); cmdfn(&c->tty, ctx); } @@ -1090,11 +1383,12 @@ tty_cmd_insertcharacter(struct tty *tty, const struct tty_ctx *ctx) { 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_term_has(tty->term, TTYC_ICH) && !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; } @@ -1110,11 +1404,12 @@ tty_cmd_deletecharacter(struct tty *tty, const struct tty_ctx *ctx) { 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_term_has(tty->term, TTYC_DCH) && !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; } @@ -1128,6 +1423,11 @@ tty_cmd_deletecharacter(struct tty *tty, const struct tty_ctx *ctx) void 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_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); @@ -1142,7 +1442,8 @@ tty_cmd_clearcharacter(struct tty *tty, const struct tty_ctx *ctx) void 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_term_has(tty->term, TTYC_CSR) || !tty_term_has(tty->term, TTYC_IL1) || @@ -1165,7 +1466,8 @@ tty_cmd_insertline(struct tty *tty, const struct tty_ctx *ctx) void 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_term_has(tty->term, TTYC_CSR) || !tty_term_has(tty->term, TTYC_DL1) || @@ -1189,35 +1491,34 @@ void tty_cmd_clearline(struct tty *tty, const struct tty_ctx *ctx) { struct window_pane *wp = ctx->wp; - u_int nx, py = ctx->yoff + ctx->ocy; + u_int nx; tty_default_attributes(tty, wp, ctx->bg); 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 tty_cmd_clearendofline(struct tty *tty, const struct tty_ctx *ctx) { struct window_pane *wp = ctx->wp; - u_int nx, py = ctx->yoff + ctx->ocy; + u_int nx; tty_default_attributes(tty, wp, ctx->bg); 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 tty_cmd_clearstartofline(struct tty *tty, const struct tty_ctx *ctx) { struct window_pane *wp = ctx->wp; - u_int py = ctx->yoff + ctx->ocy; 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 @@ -1228,7 +1529,8 @@ tty_cmd_reverseindex(struct tty *tty, const struct tty_ctx *ctx) if (ctx->ocy != ctx->orupper) return; - if (!tty_pane_full_width(tty, ctx) || + if (ctx->bigger || + !tty_pane_full_width(tty, ctx) || tty_fake_bce(tty, wp, 8) || !tty_term_has(tty->term, TTYC_CSR) || !tty_term_has(tty->term, TTYC_RI) || @@ -1255,7 +1557,8 @@ tty_cmd_linefeed(struct tty *tty, const struct tty_ctx *ctx) if (ctx->ocy != ctx->orlower) 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_term_has(tty->term, TTYC_CSR) || wp->sx == 1 || @@ -1293,7 +1596,8 @@ tty_cmd_scrollup(struct tty *tty, const struct tty_ctx *ctx) struct window_pane *wp = ctx->wp; 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_term_has(tty->term, TTYC_CSR) || wp->sx == 1 || @@ -1331,18 +1635,18 @@ tty_cmd_clearendofscreen(struct tty *tty, const struct tty_ctx *ctx) tty_region_pane(tty, ctx, 0, screen_size_y(wp->screen) - 1); tty_margin_off(tty); - px = ctx->xoff; + px = 0; 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; - 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; - 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 @@ -1356,18 +1660,18 @@ tty_cmd_clearstartofscreen(struct tty *tty, const struct tty_ctx *ctx) tty_region_pane(tty, ctx, 0, screen_size_y(wp->screen) - 1); tty_margin_off(tty); - px = ctx->xoff; + px = 0; nx = screen_size_x(wp->screen); - py = ctx->yoff; + py = 0; 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; - 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 @@ -1381,12 +1685,12 @@ tty_cmd_clearscreen(struct tty *tty, const struct tty_ctx *ctx) tty_region_pane(tty, ctx, 0, screen_size_y(wp->screen) - 1); tty_margin_off(tty); - px = ctx->xoff; + px = 0; nx = screen_size_x(wp->screen); - py = ctx->yoff; + py = 0; 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 @@ -1396,6 +1700,11 @@ tty_cmd_alignmenttest(struct tty *tty, const struct tty_ctx *ctx) struct screen *s = wp->screen; u_int i, j; + if (ctx->bigger) { + wp->flags |= PANE_REDRAW; + return; + } + tty_attributes(tty, &grid_default_cell, wp); tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1); @@ -1411,7 +1720,10 @@ tty_cmd_alignmenttest(struct tty *tty, const struct tty_ctx *ctx) void 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 && tty_pane_full_width(tty, ctx)) tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower); @@ -1425,6 +1737,27 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx) void 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_cursor_pane_unless_wrap(tty, ctx, ctx->ocx, ctx->ocy); @@ -1543,7 +1876,8 @@ static void tty_region_pane(struct tty *tty, const struct tty_ctx *ctx, u_int rupper, 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. */ @@ -1582,7 +1916,8 @@ tty_margin_off(struct tty *tty) static void 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. */ @@ -1633,7 +1968,7 @@ tty_cursor_pane_unless_wrap(struct tty *tty, const struct tty_ctx *ctx, static void 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. */ |