From 4179b4242411f41a22d9743b4eff3b19ef69b3e8 Mon Sep 17 00:00:00 2001 From: nicm Date: Thu, 13 Oct 2016 20:27:27 +0000 Subject: [PATCH] Add support for BCE (background colour erase). This makes various escape sequences (notable EL and ED but also IL, DL, ICH, DCH) create blank cells using the current background colour rather than the default colour. On modern systems BCE doesn't really have many benefits, but most other terminals now support it, some (lazy) applications rely on it, and it is not hard to include now that we have pane background colours anyway. Mostly written by Sean Haugh. --- grid-view.c | 61 +++++++++++++++------------- grid.c | 106 +++++++++++++++++++++++++++--------------------- input.c | 28 ++++++++----- screen-redraw.c | 2 +- screen-write.c | 101 ++++++++++++++++++++++++++------------------- screen.c | 7 ++-- tmux.h | 64 ++++++++++++++++------------- tty.c | 95 ++++++++++++++++++++++++++++--------------- window-choose.c | 4 +- window-clock.c | 2 +- window-copy.c | 4 +- window.c | 2 +- 12 files changed, 278 insertions(+), 198 deletions(-) diff --git a/grid-view.c b/grid-view.c index 8160679d..da0433bf 100644 --- a/grid-view.c +++ b/grid-view.c @@ -47,7 +47,7 @@ grid_view_set_cell(struct grid *gd, u_int px, u_int py, /* Clear into history. */ void -grid_view_clear_history(struct grid *gd) +grid_view_clear_history(struct grid *gd, u_int bg) { struct grid_line *gl; u_int yy, last; @@ -56,28 +56,33 @@ grid_view_clear_history(struct grid *gd) last = 0; for (yy = 0; yy < gd->sy; yy++) { gl = &gd->linedata[grid_view_y(gd, yy)]; - if (gl->cellsize != 0) + if (gl->cellused != 0) last = yy + 1; } - if (last == 0) + if (last == 0) { + grid_view_clear(gd, 0, 0, gd->sx, gd->sy, bg); return; + } /* Scroll the lines into the history. */ for (yy = 0; yy < last; yy++) { - grid_collect_history(gd); - grid_scroll_history(gd); + grid_collect_history(gd, bg); + grid_scroll_history(gd, bg); } + if (last < gd->sy) + grid_view_clear(gd, 0, 0, gd->sx, gd->sy - last, bg); gd->hscrolled = 0; } /* Clear area. */ void -grid_view_clear(struct grid *gd, u_int px, u_int py, u_int nx, u_int ny) +grid_view_clear(struct grid *gd, u_int px, u_int py, u_int nx, u_int ny, + u_int bg) { px = grid_view_x(gd, px); py = grid_view_y(gd, py); - grid_clear(gd, px, py, nx, ny); + grid_clear(gd, px, py, nx, ny, bg); } /* Scroll region up. */ @@ -85,9 +90,9 @@ void grid_view_scroll_region_up(struct grid *gd, u_int rupper, u_int rlower) { if (gd->flags & GRID_HISTORY) { - grid_collect_history(gd); + grid_collect_history(gd, 8); if (rupper == 0 && rlower == gd->sy - 1) - grid_scroll_history(gd); + grid_scroll_history(gd, 8); else { rupper = grid_view_y(gd, rupper); rlower = grid_view_y(gd, rlower); @@ -96,7 +101,7 @@ grid_view_scroll_region_up(struct grid *gd, u_int rupper, u_int rlower) } else { rupper = grid_view_y(gd, rupper); rlower = grid_view_y(gd, rlower); - grid_move_lines(gd, rupper, rupper + 1, rlower - rupper); + grid_move_lines(gd, rupper, rupper + 1, rlower - rupper, 8); } } @@ -107,12 +112,12 @@ grid_view_scroll_region_down(struct grid *gd, u_int rupper, u_int rlower) rupper = grid_view_y(gd, rupper); rlower = grid_view_y(gd, rlower); - grid_move_lines(gd, rupper + 1, rupper, rlower - rupper); + grid_move_lines(gd, rupper + 1, rupper, rlower - rupper, 8); } /* Insert lines. */ void -grid_view_insert_lines(struct grid *gd, u_int py, u_int ny) +grid_view_insert_lines(struct grid *gd, u_int py, u_int ny, u_int bg) { u_int sy; @@ -120,13 +125,13 @@ grid_view_insert_lines(struct grid *gd, u_int py, u_int ny) sy = grid_view_y(gd, gd->sy); - grid_move_lines(gd, py + ny, py, sy - py - ny); + grid_move_lines(gd, py + ny, py, sy - py - ny, bg); } /* Insert lines in region. */ void grid_view_insert_lines_region(struct grid *gd, u_int rlower, u_int py, - u_int ny) + u_int ny, u_int bg) { u_int ny2; @@ -135,13 +140,13 @@ grid_view_insert_lines_region(struct grid *gd, u_int rlower, u_int py, py = grid_view_y(gd, py); ny2 = rlower + 1 - py - ny; - grid_move_lines(gd, rlower + 1 - ny2, py, ny2); - grid_clear(gd, 0, py + ny2, gd->sx, ny - ny2); + grid_move_lines(gd, rlower + 1 - ny2, py, ny2, bg); + grid_clear(gd, 0, py + ny2, gd->sx, ny - ny2, bg); } /* Delete lines. */ void -grid_view_delete_lines(struct grid *gd, u_int py, u_int ny) +grid_view_delete_lines(struct grid *gd, u_int py, u_int ny, u_int bg) { u_int sy; @@ -149,14 +154,14 @@ grid_view_delete_lines(struct grid *gd, u_int py, u_int ny) sy = grid_view_y(gd, gd->sy); - grid_move_lines(gd, py, py + ny, sy - py - ny); - grid_clear(gd, 0, sy - ny, gd->sx, py + ny - (sy - ny)); + grid_move_lines(gd, py, py + ny, sy - py - ny, bg); + grid_clear(gd, 0, sy - ny, gd->sx, py + ny - (sy - ny), bg); } /* Delete lines inside scroll region. */ void grid_view_delete_lines_region(struct grid *gd, u_int rlower, u_int py, - u_int ny) + u_int ny, u_int bg) { u_int ny2; @@ -165,13 +170,13 @@ grid_view_delete_lines_region(struct grid *gd, u_int rlower, u_int py, py = grid_view_y(gd, py); ny2 = rlower + 1 - py - ny; - grid_move_lines(gd, py, py + ny, ny2); - grid_clear(gd, 0, py + ny2, gd->sx, ny - ny2); + grid_move_lines(gd, py, py + ny, ny2, bg); + grid_clear(gd, 0, py + ny2, gd->sx, ny - ny2, bg); } /* Insert characters. */ void -grid_view_insert_cells(struct grid *gd, u_int px, u_int py, u_int nx) +grid_view_insert_cells(struct grid *gd, u_int px, u_int py, u_int nx, u_int bg) { u_int sx; @@ -181,14 +186,14 @@ grid_view_insert_cells(struct grid *gd, u_int px, u_int py, u_int nx) sx = grid_view_x(gd, gd->sx); if (px == sx - 1) - grid_clear(gd, px, py, 1, 1); + grid_clear(gd, px, py, 1, 1, bg); else - grid_move_cells(gd, px + nx, px, py, sx - px - nx); + grid_move_cells(gd, px + nx, px, py, sx - px - nx, bg); } /* Delete characters. */ void -grid_view_delete_cells(struct grid *gd, u_int px, u_int py, u_int nx) +grid_view_delete_cells(struct grid *gd, u_int px, u_int py, u_int nx, u_int bg) { u_int sx; @@ -197,8 +202,8 @@ grid_view_delete_cells(struct grid *gd, u_int px, u_int py, u_int nx) sx = grid_view_x(gd, gd->sx); - grid_move_cells(gd, px, px + nx, py, sx - px - nx); - grid_clear(gd, sx - nx, py, px + nx - (sx - nx), 1); + grid_move_cells(gd, px, px + nx, py, sx - px - nx, bg); + grid_clear(gd, sx - nx, py, px + nx - (sx - nx), 1, bg); } /* Convert cells into a string. */ diff --git a/grid.c b/grid.c index 35de2aef..d0a28463 100644 --- a/grid.c +++ b/grid.c @@ -43,7 +43,8 @@ const struct grid_cell_entry grid_default_entry = { 0, { .data = { 0, 8, 8, ' ' } } }; -static void grid_expand_line(struct grid *, u_int, u_int); +static void grid_expand_line(struct grid *, u_int, u_int, u_int); +static void grid_empty_line(struct grid *, u_int, u_int); static void grid_reflow_copy(struct grid_line *, u_int, struct grid_line *, u_int, u_int); @@ -60,9 +61,10 @@ static void grid_string_cells_code(const struct grid_cell *, /* Copy default into a cell. */ static void -grid_clear_cell(struct grid *gd, u_int px, u_int py) +grid_clear_cell(struct grid *gd, u_int px, u_int py, u_int bg) { gd->linedata[py].celldata[px] = grid_default_entry; + gd->linedata[py].celldata[px].data.bg = bg; } /* Check grid y position. */ @@ -162,7 +164,7 @@ grid_compare(struct grid *ga, struct grid *gb) * and shift up. */ void -grid_collect_history(struct grid *gd) +grid_collect_history(struct grid *gd, u_int bg) { u_int yy; @@ -173,7 +175,7 @@ grid_collect_history(struct grid *gd) if (yy < 1) yy = 1; - grid_move_lines(gd, 0, yy, gd->hsize + gd->sy - yy); + grid_move_lines(gd, 0, yy, gd->hsize + gd->sy - yy, bg); gd->hsize -= yy; if (gd->hscrolled > gd->hsize) gd->hscrolled = gd->hsize; @@ -184,14 +186,14 @@ grid_collect_history(struct grid *gd) * allocate a new line at the bottom and move the history size indicator. */ void -grid_scroll_history(struct grid *gd) +grid_scroll_history(struct grid *gd, u_int bg) { u_int yy; yy = gd->hsize + gd->sy; gd->linedata = xreallocarray(gd->linedata, yy + 1, sizeof *gd->linedata); - memset(&gd->linedata[yy], 0, sizeof gd->linedata[yy]); + grid_empty_line(gd, yy, bg); gd->hscrolled++; gd->hsize++; @@ -201,8 +203,8 @@ grid_scroll_history(struct grid *gd) void grid_clear_history(struct grid *gd) { - grid_clear_lines(gd, 0, gd->hsize); - grid_move_lines(gd, 0, gd->hsize, gd->sy); + grid_clear_lines(gd, 0, gd->hsize, 8); + grid_move_lines(gd, 0, gd->hsize, gd->sy, 8); gd->hscrolled = 0; gd->hsize = 0; @@ -247,7 +249,7 @@ grid_scroll_history_region(struct grid *gd, u_int upper, u_int lower) /* Expand line to fit to cell. */ static void -grid_expand_line(struct grid *gd, u_int py, u_int sx) +grid_expand_line(struct grid *gd, u_int py, u_int sx, u_int bg) { struct grid_line *gl; u_int xx; @@ -258,10 +260,19 @@ grid_expand_line(struct grid *gd, u_int py, u_int sx) gl->celldata = xreallocarray(gl->celldata, sx, sizeof *gl->celldata); for (xx = gl->cellsize; xx < sx; xx++) - grid_clear_cell(gd, xx, py); + grid_clear_cell(gd, xx, py, bg); gl->cellsize = sx; } +/* Empty a line and set background colour if needed. */ +static void +grid_empty_line(struct grid *gd, u_int py, u_int bg) +{ + memset(&gd->linedata[py], 0, sizeof gd->linedata[py]); + if (bg != 8) + grid_expand_line(gd, py, gd->sx, bg); +} + /* Peek at grid line. */ const struct grid_line * grid_peek_line(struct grid *gd, u_int py) @@ -317,11 +328,14 @@ grid_set_cell(struct grid *gd, u_int px, u_int py, const struct grid_cell *gc) if (grid_check_y(gd, py) != 0) return; - grid_expand_line(gd, py, px + 1); + grid_expand_line(gd, py, px + 1, 8); gl = &gd->linedata[py]; gce = &gl->celldata[px]; + if (px + 1 > gl->cellused) + gl->cellused = px + 1; + extended = (gce->flags & GRID_FLAG_EXTENDED); if (!extended && (gc->data.size != 1 || gc->data.width != 1)) extended = 1; @@ -358,7 +372,7 @@ grid_set_cell(struct grid *gd, u_int px, u_int py, const struct grid_cell *gc) /* Clear area. */ void -grid_clear(struct grid *gd, u_int px, u_int py, u_int nx, u_int ny) +grid_clear(struct grid *gd, u_int px, u_int py, u_int nx, u_int ny, u_int bg) { u_int xx, yy; @@ -366,7 +380,7 @@ grid_clear(struct grid *gd, u_int px, u_int py, u_int nx, u_int ny) return; if (px == 0 && nx == gd->sx) { - grid_clear_lines(gd, py, ny); + grid_clear_lines(gd, py, ny, bg); return; } @@ -376,23 +390,23 @@ grid_clear(struct grid *gd, u_int px, u_int py, u_int nx, u_int ny) return; for (yy = py; yy < py + ny; yy++) { - if (px >= gd->linedata[yy].cellsize) + if (px + nx >= gd->sx && px < gd->linedata[yy].cellused) + gd->linedata[yy].cellused = px; + if (px > gd->linedata[yy].cellsize && bg == 8) continue; - if (px + nx >= gd->linedata[yy].cellsize) { + if (px + nx >= gd->linedata[yy].cellsize && bg == 8) { gd->linedata[yy].cellsize = px; continue; } - for (xx = px; xx < px + nx; xx++) { - if (xx >= gd->linedata[yy].cellsize) - break; - grid_clear_cell(gd, xx, yy); - } + grid_expand_line(gd, yy, px + nx, bg); + for (xx = px; xx < px + nx; xx++) + grid_clear_cell(gd, xx, yy, bg); } } /* Clear lines. This just frees and truncates the lines. */ void -grid_clear_lines(struct grid *gd, u_int py, u_int ny) +grid_clear_lines(struct grid *gd, u_int py, u_int ny, u_int bg) { struct grid_line *gl; u_int yy; @@ -409,13 +423,13 @@ grid_clear_lines(struct grid *gd, u_int py, u_int ny) gl = &gd->linedata[yy]; free(gl->celldata); free(gl->extddata); - memset(gl, 0, sizeof *gl); + grid_empty_line(gd, yy, bg); } } /* Move a group of lines. */ void -grid_move_lines(struct grid *gd, u_int dy, u_int py, u_int ny) +grid_move_lines(struct grid *gd, u_int dy, u_int py, u_int ny, u_int bg) { u_int yy; @@ -435,7 +449,7 @@ grid_move_lines(struct grid *gd, u_int dy, u_int py, u_int ny) for (yy = dy; yy < dy + ny; yy++) { if (yy >= py && yy < py + ny) continue; - grid_clear_lines(gd, yy, 1); + grid_clear_lines(gd, yy, 1, bg); } memmove(&gd->linedata[dy], &gd->linedata[py], @@ -443,15 +457,15 @@ grid_move_lines(struct grid *gd, u_int dy, u_int py, u_int ny) /* Wipe any lines that have been moved (without freeing them). */ for (yy = py; yy < py + ny; yy++) { - if (yy >= dy && yy < dy + ny) - continue; - memset(&gd->linedata[yy], 0, sizeof gd->linedata[yy]); + if (yy < dy || yy >= dy + ny) + grid_empty_line(gd, yy, bg); } } /* Move a group of cells. */ void -grid_move_cells(struct grid *gd, u_int dx, u_int px, u_int py, u_int nx) +grid_move_cells(struct grid *gd, u_int dx, u_int px, u_int py, u_int nx, + u_int bg) { struct grid_line *gl; u_int xx; @@ -463,8 +477,8 @@ grid_move_cells(struct grid *gd, u_int dx, u_int px, u_int py, u_int nx) return; gl = &gd->linedata[py]; - grid_expand_line(gd, py, px + nx); - grid_expand_line(gd, py, dx + nx); + grid_expand_line(gd, py, px + nx, 8); + grid_expand_line(gd, py, dx + nx, 8); memmove(&gl->celldata[dx], &gl->celldata[px], nx * sizeof *gl->celldata); @@ -472,7 +486,7 @@ grid_move_cells(struct grid *gd, u_int dx, u_int px, u_int py, u_int nx) for (xx = px; xx < px + nx; xx++) { if (xx >= dx && xx < dx + nx) continue; - grid_clear_cell(gd, xx, py); + grid_clear_cell(gd, xx, py, bg); } } @@ -748,7 +762,7 @@ grid_duplicate_lines(struct grid *dst, u_int dy, struct grid *src, u_int sy, ny = dst->hsize + dst->sy - dy; if (sy + ny > src->hsize + src->sy) ny = src->hsize + src->sy - sy; - grid_clear_lines(dst, dy, ny); + grid_clear_lines(dst, dy, ny, 8); for (yy = 0; yy < ny; yy++) { srcl = &src->linedata[sy]; @@ -810,28 +824,28 @@ grid_reflow_join(struct grid *dst, u_int *py, struct grid_line *src_gl, u_int left, to_copy, ox, nx; /* How much is left on the old line? */ - left = new_x - dst_gl->cellsize; + left = new_x - dst_gl->cellused; /* Work out how much to append. */ - to_copy = src_gl->cellsize; + to_copy = src_gl->cellused; if (to_copy > left) to_copy = left; - ox = dst_gl->cellsize; + ox = dst_gl->cellused; nx = ox + to_copy; /* Resize the destination line. */ dst_gl->celldata = xreallocarray(dst_gl->celldata, nx, sizeof *dst_gl->celldata); - dst_gl->cellsize = nx; + dst_gl->cellsize = dst_gl->cellused = nx; /* Append as much as possible. */ grid_reflow_copy(dst_gl, ox, src_gl, 0, to_copy); /* If there is any left in the source, split it. */ - if (src_gl->cellsize > to_copy) { + if (src_gl->cellused > to_copy) { dst_gl->flags |= GRID_LINE_WRAPPED; - src_gl->cellsize -= to_copy; + src_gl->cellused -= to_copy; grid_reflow_split(dst, py, src_gl, new_x, to_copy); } } @@ -845,22 +859,22 @@ grid_reflow_split(struct grid *dst, u_int *py, struct grid_line *src_gl, u_int to_copy; /* Loop and copy sections of the source line. */ - while (src_gl->cellsize > 0) { + while (src_gl->cellused > 0) { /* Create new line. */ if (*py >= dst->hsize + dst->sy) - grid_scroll_history(dst); + grid_scroll_history(dst, 8); dst_gl = &dst->linedata[*py]; (*py)++; /* How much should we copy? */ to_copy = new_x; - if (to_copy > src_gl->cellsize) - to_copy = src_gl->cellsize; + if (to_copy > src_gl->cellused) + to_copy = src_gl->cellused; /* Expand destination line. */ dst_gl->celldata = xreallocarray(NULL, to_copy, sizeof *dst_gl->celldata); - dst_gl->cellsize = to_copy; + dst_gl->cellsize = dst_gl->cellused = to_copy; dst_gl->flags |= GRID_LINE_WRAPPED; /* Copy the data. */ @@ -868,7 +882,7 @@ grid_reflow_split(struct grid *dst, u_int *py, struct grid_line *src_gl, /* Move offset and reduce old line size. */ offset += to_copy; - src_gl->cellsize -= to_copy; + src_gl->cellused -= to_copy; } /* Last line is not wrapped. */ @@ -884,7 +898,7 @@ grid_reflow_move(struct grid *dst, u_int *py, struct grid_line *src_gl) /* Create new line. */ if (*py >= dst->hsize + dst->sy) - grid_scroll_history(dst); + grid_scroll_history(dst, 8); dst_gl = &dst->linedata[*py]; (*py)++; @@ -916,7 +930,7 @@ grid_reflow(struct grid *dst, struct grid *src, u_int new_x) src_gl = src->linedata + line; if (!previous_wrapped) { /* Wasn't wrapped. If smaller, move to destination. */ - if (src_gl->cellsize <= new_x) + if (src_gl->cellused <= new_x) grid_reflow_move(dst, &py, src_gl); else grid_reflow_split(dst, &py, src_gl, new_x, 0); diff --git a/input.c b/input.c index c3bd6510..dd57e7f4 100644 --- a/input.c +++ b/input.c @@ -1283,7 +1283,8 @@ input_csi_dispatch(struct input_ctx *ictx) screen_write_clearcharacter(sctx, input_get(ictx, 0, 1, 1)); break; case INPUT_CSI_DCH: - screen_write_deletecharacter(sctx, input_get(ictx, 0, 1, 1)); + screen_write_deletecharacter(sctx, input_get(ictx, 0, 1, 1), + ictx->cell.cell.bg); break; case INPUT_CSI_DECSTBM: n = input_get(ictx, 0, 1, 1); @@ -1291,7 +1292,8 @@ input_csi_dispatch(struct input_ctx *ictx) screen_write_scrollregion(sctx, n - 1, m - 1); break; case INPUT_CSI_DL: - screen_write_deleteline(sctx, input_get(ictx, 0, 1, 1)); + screen_write_deleteline(sctx, input_get(ictx, 0, 1, 1), + ictx->cell.cell.bg); break; case INPUT_CSI_DSR: switch (input_get(ictx, 0, 0, 0)) { @@ -1309,13 +1311,13 @@ input_csi_dispatch(struct input_ctx *ictx) case INPUT_CSI_ED: switch (input_get(ictx, 0, 0, 0)) { case 0: - screen_write_clearendofscreen(sctx); + screen_write_clearendofscreen(sctx, ictx->cell.cell.bg); break; case 1: screen_write_clearstartofscreen(sctx); break; case 2: - screen_write_clearscreen(sctx); + screen_write_clearscreen(sctx, ictx->cell.cell.bg); break; case 3: switch (input_get(ictx, 1, 0, 0)) { @@ -1336,13 +1338,13 @@ input_csi_dispatch(struct input_ctx *ictx) case INPUT_CSI_EL: switch (input_get(ictx, 0, 0, 0)) { case 0: - screen_write_clearendofline(sctx); + screen_write_clearendofline(sctx, ictx->cell.cell.bg); break; case 1: - screen_write_clearstartofline(sctx); + screen_write_clearstartofline(sctx, ictx->cell.cell.bg); break; case 2: - screen_write_clearline(sctx); + screen_write_clearline(sctx, ictx->cell.cell.bg); break; default: log_debug("%s: unknown '%c'", __func__, ictx->ch); @@ -1354,10 +1356,12 @@ input_csi_dispatch(struct input_ctx *ictx) screen_write_cursormove(sctx, n - 1, s->cy); break; case INPUT_CSI_ICH: - screen_write_insertcharacter(sctx, input_get(ictx, 0, 1, 1)); + screen_write_insertcharacter(sctx, input_get(ictx, 0, 1, 1), + ictx->cell.cell.bg); break; case INPUT_CSI_IL: - screen_write_insertline(sctx, input_get(ictx, 0, 1, 1)); + screen_write_insertline(sctx, input_get(ictx, 0, 1, 1), + ictx->cell.cell.bg); break; case INPUT_CSI_RCP: memcpy(&ictx->cell, &ictx->old_cell, sizeof ictx->cell); @@ -1445,7 +1449,8 @@ input_csi_dispatch_rm_private(struct input_ctx *ictx) break; case 3: /* DECCOLM */ screen_write_cursormove(&ictx->ctx, 0, 0); - screen_write_clearscreen(&ictx->ctx); + screen_write_clearscreen(&ictx->ctx, + ictx->cell.cell.bg); break; case 7: /* DECAWM */ screen_write_mode_clear(&ictx->ctx, MODE_WRAP); @@ -1522,7 +1527,8 @@ input_csi_dispatch_sm_private(struct input_ctx *ictx) break; case 3: /* DECCOLM */ screen_write_cursormove(&ictx->ctx, 0, 0); - screen_write_clearscreen(&ictx->ctx); + screen_write_clearscreen(&ictx->ctx, + ictx->cell.cell.bg); break; case 7: /* DECAWM */ screen_write_mode_set(&ictx->ctx, MODE_WRAP); diff --git a/screen-redraw.c b/screen-redraw.c index 05d094d5..84a951dc 100644 --- a/screen-redraw.c +++ b/screen-redraw.c @@ -295,7 +295,7 @@ screen_redraw_make_pane_status(struct client *c, struct window *w, screen_write_start(&ctx, NULL, &wp->status_screen); screen_write_cursormove(&ctx, 0, 0); - screen_write_clearline(&ctx); + screen_write_clearline(&ctx, 8); screen_write_cnputs(&ctx, outlen, &gc, "%s", out); screen_write_stop(&ctx); diff --git a/screen-write.c b/screen-write.c index 8156a1d0..95caabce 100644 --- a/screen-write.c +++ b/screen-write.c @@ -147,7 +147,7 @@ screen_write_reset(struct screen_write_ctx *ctx) s->mode &= ~(MODE_INSERT|MODE_KCURSOR|MODE_KKEYPAD|MODE_FOCUSON); s->mode &= ~(ALL_MOUSE_MODES|MODE_MOUSE_UTF8|MODE_MOUSE_SGR); - screen_write_clearscreen(ctx); + screen_write_clearscreen(ctx, 8); screen_write_cursormove(ctx, 0, 0); } @@ -601,7 +601,7 @@ screen_write_alignmenttest(struct screen_write_ctx *ctx) /* Insert nx characters. */ void -screen_write_insertcharacter(struct screen_write_ctx *ctx, u_int nx) +screen_write_insertcharacter(struct screen_write_ctx *ctx, u_int nx, u_int bg) { struct screen *s = ctx->s; struct tty_ctx ttyctx; @@ -618,15 +618,16 @@ screen_write_insertcharacter(struct screen_write_ctx *ctx, u_int nx) screen_write_initctx(ctx, &ttyctx); if (s->cx <= screen_size_x(s) - 1) - grid_view_insert_cells(s->grid, s->cx, s->cy, nx); + grid_view_insert_cells(s->grid, s->cx, s->cy, nx, bg); ttyctx.num = nx; + ttyctx.bg = bg; tty_write(tty_cmd_insertcharacter, &ttyctx); } /* Delete nx characters. */ void -screen_write_deletecharacter(struct screen_write_ctx *ctx, u_int nx) +screen_write_deletecharacter(struct screen_write_ctx *ctx, u_int nx, u_int bg) { struct screen *s = ctx->s; struct tty_ctx ttyctx; @@ -643,9 +644,10 @@ screen_write_deletecharacter(struct screen_write_ctx *ctx, u_int nx) screen_write_initctx(ctx, &ttyctx); if (s->cx <= screen_size_x(s) - 1) - grid_view_delete_cells(s->grid, s->cx, s->cy, nx); + grid_view_delete_cells(s->grid, s->cx, s->cy, nx, bg); ttyctx.num = nx; + ttyctx.bg = bg; tty_write(tty_cmd_deletecharacter, &ttyctx); } @@ -668,7 +670,7 @@ screen_write_clearcharacter(struct screen_write_ctx *ctx, u_int nx) if (s->cx <= screen_size_x(s) - 1) { screen_dirty_clear(s, s->cx, s->cy, s->cx + nx - 1, s->cy); - grid_view_clear(s->grid, s->cx, s->cy, nx, 1); + grid_view_clear(s->grid, s->cx, s->cy, nx, 1, 8); } else return; @@ -678,7 +680,7 @@ screen_write_clearcharacter(struct screen_write_ctx *ctx, u_int nx) /* Insert ny lines. */ void -screen_write_insertline(struct screen_write_ctx *ctx, u_int ny) +screen_write_insertline(struct screen_write_ctx *ctx, u_int ny, u_int bg) { struct screen *s = ctx->s; struct tty_ctx ttyctx; @@ -695,9 +697,10 @@ screen_write_insertline(struct screen_write_ctx *ctx, u_int ny) screen_write_flush(ctx); screen_write_initctx(ctx, &ttyctx); - grid_view_insert_lines(s->grid, s->cy, ny); + grid_view_insert_lines(s->grid, s->cy, ny, bg); ttyctx.num = ny; + ttyctx.bg = bg; tty_write(tty_cmd_insertline, &ttyctx); return; } @@ -711,17 +714,20 @@ screen_write_insertline(struct screen_write_ctx *ctx, u_int ny) screen_write_initctx(ctx, &ttyctx); if (s->cy < s->rupper || s->cy > s->rlower) - grid_view_insert_lines(s->grid, s->cy, ny); - else - grid_view_insert_lines_region(s->grid, s->rlower, s->cy, ny); + grid_view_insert_lines(s->grid, s->cy, ny, bg); + else { + grid_view_insert_lines_region(s->grid, s->rlower, s->cy, ny, + bg); + } ttyctx.num = ny; + ttyctx.bg = bg; tty_write(tty_cmd_insertline, &ttyctx); } /* Delete ny lines. */ void -screen_write_deleteline(struct screen_write_ctx *ctx, u_int ny) +screen_write_deleteline(struct screen_write_ctx *ctx, u_int ny, u_int bg) { struct screen *s = ctx->s; struct tty_ctx ttyctx; @@ -738,9 +744,10 @@ screen_write_deleteline(struct screen_write_ctx *ctx, u_int ny) screen_write_flush(ctx); screen_write_initctx(ctx, &ttyctx); - grid_view_delete_lines(s->grid, s->cy, ny); + grid_view_delete_lines(s->grid, s->cy, ny, bg); ttyctx.num = ny; + ttyctx.bg = bg; tty_write(tty_cmd_deleteline, &ttyctx); return; } @@ -754,17 +761,20 @@ screen_write_deleteline(struct screen_write_ctx *ctx, u_int ny) screen_write_initctx(ctx, &ttyctx); if (s->cy < s->rupper || s->cy > s->rlower) - grid_view_delete_lines(s->grid, s->cy, ny); - else - grid_view_delete_lines_region(s->grid, s->rlower, s->cy, ny); + grid_view_delete_lines(s->grid, s->cy, ny, bg); + else { + grid_view_delete_lines_region(s->grid, s->rlower, s->cy, ny, + bg); + } ttyctx.num = ny; + ttyctx.bg = bg; tty_write(tty_cmd_deleteline, &ttyctx); } /* Clear line at cursor. */ void -screen_write_clearline(struct screen_write_ctx *ctx) +screen_write_clearline(struct screen_write_ctx *ctx, u_int bg) { struct screen *s = ctx->s; struct grid_line *gl; @@ -772,20 +782,21 @@ screen_write_clearline(struct screen_write_ctx *ctx) u_int sx = screen_size_x(s); screen_write_initctx(ctx, &ttyctx); + ttyctx.bg = bg; gl = &s->grid->linedata[s->grid->hsize + s->cy]; - if (gl->cellsize != 0) { - screen_dirty_clear(s, 0, s->cy, sx - 1, s->cy); - grid_view_clear(s->grid, 0, s->cy, sx, 1); - } else + if (gl->cellsize == 0 && bg == 8) return; + screen_dirty_clear(s, 0, s->cy, sx - 1, s->cy); + grid_view_clear(s->grid, 0, s->cy, sx, 1, bg); + tty_write(tty_cmd_clearline, &ttyctx); } /* Clear to end of line from cursor. */ void -screen_write_clearendofline(struct screen_write_ctx *ctx) +screen_write_clearendofline(struct screen_write_ctx *ctx, u_int bg) { struct screen *s = ctx->s; struct grid_line *gl; @@ -793,33 +804,35 @@ screen_write_clearendofline(struct screen_write_ctx *ctx) u_int sx = screen_size_x(s); screen_write_initctx(ctx, &ttyctx); + ttyctx.bg = bg; gl = &s->grid->linedata[s->grid->hsize + s->cy]; - if (s->cx <= sx - 1 && s->cx < gl->cellsize) { - screen_dirty_clear(s, s->cx, s->cy, sx - 1, s->cy); - grid_view_clear(s->grid, s->cx, s->cy, sx - s->cx, 1); - } else + if (s->cx > sx - 1 || (s->cx >= gl->cellsize && bg == 8)) return; + screen_dirty_clear(s, s->cx, s->cy, sx - 1, s->cy); + grid_view_clear(s->grid, s->cx, s->cy, sx - s->cx, 1, bg); + tty_write(tty_cmd_clearendofline, &ttyctx); } /* Clear to start of line from cursor. */ void -screen_write_clearstartofline(struct screen_write_ctx *ctx) +screen_write_clearstartofline(struct screen_write_ctx *ctx, u_int bg) { struct screen *s = ctx->s; struct tty_ctx ttyctx; u_int sx = screen_size_x(s); screen_write_initctx(ctx, &ttyctx); + ttyctx.bg = bg; if (s->cx > sx - 1) { screen_dirty_clear(s, 0, s->cy, sx - 1, s->cy); - grid_view_clear(s->grid, 0, s->cy, sx, 1); + grid_view_clear(s->grid, 0, s->cy, sx, 1, bg); } else { screen_dirty_clear(s, 0, s->cy, s->cx, s->cy); - grid_view_clear(s->grid, 0, s->cy, s->cx + 1, 1); + grid_view_clear(s->grid, 0, s->cy, s->cx + 1, 1, bg); } tty_write(tty_cmd_clearstartofline, &ttyctx); @@ -919,25 +932,28 @@ screen_write_carriagereturn(struct screen_write_ctx *ctx) /* Clear to end of screen from cursor. */ void -screen_write_clearendofscreen(struct screen_write_ctx *ctx) +screen_write_clearendofscreen(struct screen_write_ctx *ctx, u_int bg) { struct screen *s = ctx->s; struct tty_ctx ttyctx; u_int sx = screen_size_x(s), sy = screen_size_y(s); screen_write_initctx(ctx, &ttyctx); + ttyctx.bg = bg; /* Scroll into history if it is enabled and clearing entire screen. */ - if (s->cy == 0 && s->grid->flags & GRID_HISTORY) { + if (s->cx == 0 && s->cy == 0 && s->grid->flags & GRID_HISTORY) { screen_dirty_clear(s, 0, 0, sx - 1, sy - 1); - grid_view_clear_history(s->grid); + grid_view_clear_history(s->grid, bg); } else { if (s->cx <= sx - 1) { screen_dirty_clear(s, s->cx, s->cy, sx - 1, s->cy); - grid_view_clear(s->grid, s->cx, s->cy, sx - s->cx, 1); + grid_view_clear(s->grid, s->cx, s->cy, sx - s->cx, 1, + bg); } screen_dirty_clear(s, 0, s->cy + 1, sx - 1, sy - 1); - grid_view_clear(s->grid, 0, s->cy + 1, sx, sy - (s->cy + 1)); + grid_view_clear(s->grid, 0, s->cy + 1, sx, sy - (s->cy + 1), + bg); } tty_write(tty_cmd_clearendofscreen, &ttyctx); @@ -955,14 +971,14 @@ screen_write_clearstartofscreen(struct screen_write_ctx *ctx) if (s->cy > 0) { screen_dirty_clear(s, 0, 0, sx - 1, s->cy); - grid_view_clear(s->grid, 0, 0, sx, s->cy); + grid_view_clear(s->grid, 0, 0, sx, s->cy, 8); } if (s->cx > sx - 1) { screen_dirty_clear(s, 0, s->cy, sx - 1, s->cy); - grid_view_clear(s->grid, 0, s->cy, sx, 1); + grid_view_clear(s->grid, 0, s->cy, sx, 1, 8); } else { screen_dirty_clear(s, 0, s->cy, s->cx, s->cy); - grid_view_clear(s->grid, 0, s->cy, s->cx + 1, 1); + grid_view_clear(s->grid, 0, s->cy, s->cx + 1, 1, 8); } tty_write(tty_cmd_clearstartofscreen, &ttyctx); @@ -970,21 +986,22 @@ screen_write_clearstartofscreen(struct screen_write_ctx *ctx) /* Clear entire screen. */ void -screen_write_clearscreen(struct screen_write_ctx *ctx) +screen_write_clearscreen(struct screen_write_ctx *ctx, u_int bg) { struct screen *s = ctx->s; struct tty_ctx ttyctx; u_int sx = screen_size_x(s), sy = screen_size_y(s); screen_write_initctx(ctx, &ttyctx); + ttyctx.bg = bg; screen_dirty_clear(s, 0, 0, sx - 1, sy - 1); /* Scroll into history if it is enabled. */ if (s->grid->flags & GRID_HISTORY) - grid_view_clear_history(s->grid); + grid_view_clear_history(s->grid, bg); else - grid_view_clear(s->grid, 0, 0, sx, sy); + grid_view_clear(s->grid, 0, 0, sx, sy, bg); tty_write(tty_cmd_clearscreen, &ttyctx); } @@ -996,7 +1013,7 @@ screen_write_clearhistory(struct screen_write_ctx *ctx) struct screen *s = ctx->s; struct grid *gd = s->grid; - grid_move_lines(gd, 0, gd->hsize, gd->sy); + grid_move_lines(gd, 0, gd->hsize, gd->sy, 8); gd->hscrolled = gd->hsize = 0; } @@ -1049,7 +1066,7 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc) if (s->cx <= sx - width) { screen_write_flush(ctx); xx = sx - s->cx - width; - grid_view_insert_cells(s->grid, s->cx, s->cy, xx); + grid_view_insert_cells(s->grid, s->cx, s->cy, xx, 8); } insert = 1; } else diff --git a/screen.c b/screen.c index 3d6b8cdc..bf342c45 100644 --- a/screen.c +++ b/screen.c @@ -60,7 +60,7 @@ screen_reinit(struct screen *s) screen_reset_tabs(s); - grid_clear_lines(s->grid, s->grid->hsize, s->grid->sy); + grid_clear_lines(s->grid, s->grid->hsize, s->grid->sy, 8); screen_clear_selection(s); } @@ -193,7 +193,8 @@ screen_resize_y(struct screen *s, u_int sy) if (available > 0) { if (available > needed) available = needed; - grid_view_delete_lines(gd, oldy - available, available); + grid_view_delete_lines(gd, oldy - available, available, + 8); } needed -= available; @@ -209,7 +210,7 @@ screen_resize_y(struct screen *s, u_int sy) } else if (needed > 0 && available > 0) { if (available > needed) available = needed; - grid_view_delete_lines(gd, 0, available); + grid_view_delete_lines(gd, 0, available, 8); } s->cy -= needed; } diff --git a/tmux.h b/tmux.h index a33eec29..2a271ec5 100644 --- a/tmux.h +++ b/tmux.h @@ -602,6 +602,7 @@ struct grid_cell_entry { /* Grid line. */ struct grid_line { + u_int cellused; u_int cellsize; struct grid_cell_entry *celldata; @@ -710,7 +711,7 @@ struct screen { char *ccolour; /* cursor colour string */ u_int rupper; /* scroll region top */ - u_int rlower; /* scroll region bottom */ + u_int rlower; /* scroll region bottom */ int mode; @@ -1144,6 +1145,9 @@ struct tty_ctx { u_int xoff; u_int yoff; + /* The background colour used for clearing (erasing). */ + u_int bg; + /* Saved last cell on line. */ struct grid_cell last_cell; }; @@ -1187,7 +1191,7 @@ struct client { struct event repeat_timer; struct event click_timer; - u_int click_button; + u_int click_button; struct event status_timer; struct screen status; @@ -1271,10 +1275,10 @@ struct cmd_find_state { int flags; struct cmd_find_state *current; - struct session *s; - struct winlink *wl; + struct session *s; + struct winlink *wl; struct window *w; - struct window_pane *wp; + struct window_pane *wp; int idx; }; @@ -1544,7 +1548,7 @@ void format_defaults_paste_buffer(struct format_tree *, /* hooks.c */ struct hook; -struct hooks *hooks_get(struct session *); +struct hooks *hooks_get(struct session *); struct hooks *hooks_create(struct hooks *); void hooks_free(struct hooks *); struct hook *hooks_first(struct hooks *); @@ -1925,17 +1929,17 @@ int grid_cells_equal(const struct grid_cell *, const struct grid_cell *); struct grid *grid_create(u_int, u_int, u_int); void grid_destroy(struct grid *); int grid_compare(struct grid *, struct grid *); -void grid_collect_history(struct grid *); -void grid_scroll_history(struct grid *); +void grid_collect_history(struct grid *, u_int); +void grid_scroll_history(struct grid *, u_int); void grid_scroll_history_region(struct grid *, u_int, u_int); void grid_clear_history(struct grid *); const struct grid_line *grid_peek_line(struct grid *, u_int); void grid_get_cell(struct grid *, u_int, u_int, struct grid_cell *); void grid_set_cell(struct grid *, u_int, u_int, const struct grid_cell *); -void grid_clear(struct grid *, u_int, u_int, u_int, u_int); -void grid_clear_lines(struct grid *, u_int, u_int); -void grid_move_lines(struct grid *, u_int, u_int, u_int); -void grid_move_cells(struct grid *, u_int, u_int, u_int, u_int); +void grid_clear(struct grid *, u_int, u_int, u_int, u_int, u_int); +void grid_clear_lines(struct grid *, u_int, u_int, u_int); +void grid_move_lines(struct grid *, u_int, u_int, u_int, u_int); +void grid_move_cells(struct grid *, u_int, u_int, u_int, u_int, u_int); char *grid_string_cells(struct grid *, u_int, u_int, u_int, struct grid_cell **, int, int, int); void grid_duplicate_lines(struct grid *, u_int, struct grid *, u_int, @@ -1946,16 +1950,18 @@ u_int grid_reflow(struct grid *, struct grid *, u_int); void grid_view_get_cell(struct grid *, u_int, u_int, struct grid_cell *); void grid_view_set_cell(struct grid *, u_int, u_int, const struct grid_cell *); -void grid_view_clear_history(struct grid *); -void grid_view_clear(struct grid *, u_int, u_int, u_int, u_int); +void grid_view_clear_history(struct grid *, u_int); +void grid_view_clear(struct grid *, u_int, u_int, u_int, u_int, u_int); void grid_view_scroll_region_up(struct grid *, u_int, u_int); void grid_view_scroll_region_down(struct grid *, u_int, u_int); -void grid_view_insert_lines(struct grid *, u_int, u_int); -void grid_view_insert_lines_region(struct grid *, u_int, u_int, u_int); -void grid_view_delete_lines(struct grid *, u_int, u_int); -void grid_view_delete_lines_region(struct grid *, u_int, u_int, u_int); -void grid_view_insert_cells(struct grid *, u_int, u_int, u_int); -void grid_view_delete_cells(struct grid *, u_int, u_int, u_int); +void grid_view_insert_lines(struct grid *, u_int, u_int, u_int); +void grid_view_insert_lines_region(struct grid *, u_int, u_int, u_int, + u_int); +void grid_view_delete_lines(struct grid *, u_int, u_int, u_int); +void grid_view_delete_lines_region(struct grid *, u_int, u_int, u_int, + u_int); +void grid_view_insert_cells(struct grid *, u_int, u_int, u_int, u_int); +void grid_view_delete_cells(struct grid *, u_int, u_int, u_int, u_int); char *grid_view_string_cells(struct grid *, u_int, u_int, u_int); /* screen-write.c */ @@ -1985,22 +1991,22 @@ void screen_write_cursordown(struct screen_write_ctx *, u_int); void screen_write_cursorright(struct screen_write_ctx *, u_int); void screen_write_cursorleft(struct screen_write_ctx *, u_int); void screen_write_alignmenttest(struct screen_write_ctx *); -void screen_write_insertcharacter(struct screen_write_ctx *, u_int); -void screen_write_deletecharacter(struct screen_write_ctx *, u_int); +void screen_write_insertcharacter(struct screen_write_ctx *, u_int, u_int); +void screen_write_deletecharacter(struct screen_write_ctx *, u_int, u_int); void screen_write_clearcharacter(struct screen_write_ctx *, u_int); -void screen_write_insertline(struct screen_write_ctx *, u_int); -void screen_write_deleteline(struct screen_write_ctx *, u_int); -void screen_write_clearline(struct screen_write_ctx *); -void screen_write_clearendofline(struct screen_write_ctx *); -void screen_write_clearstartofline(struct screen_write_ctx *); +void screen_write_insertline(struct screen_write_ctx *, u_int, u_int); +void screen_write_deleteline(struct screen_write_ctx *, u_int, u_int); +void screen_write_clearline(struct screen_write_ctx *, u_int); +void screen_write_clearendofline(struct screen_write_ctx *, u_int); +void screen_write_clearstartofline(struct screen_write_ctx *, u_int); void screen_write_cursormove(struct screen_write_ctx *, u_int, u_int); void screen_write_reverseindex(struct screen_write_ctx *); void screen_write_scrollregion(struct screen_write_ctx *, u_int, u_int); void screen_write_linefeed(struct screen_write_ctx *, int); void screen_write_carriagereturn(struct screen_write_ctx *); -void screen_write_clearendofscreen(struct screen_write_ctx *); +void screen_write_clearendofscreen(struct screen_write_ctx *, u_int); void screen_write_clearstartofscreen(struct screen_write_ctx *); -void screen_write_clearscreen(struct screen_write_ctx *); +void screen_write_clearscreen(struct screen_write_ctx *, u_int); void screen_write_clearhistory(struct screen_write_ctx *); void screen_write_cell(struct screen_write_ctx *, const struct grid_cell *); void screen_write_setselection(struct screen_write_ctx *, u_char *, u_int); diff --git a/tty.c b/tty.c index c4adfe82..198b8451 100644 --- a/tty.c +++ b/tty.c @@ -55,7 +55,8 @@ static void tty_colours_bg(struct tty *, const struct grid_cell *); static void tty_region_pane(struct tty *, const struct tty_ctx *, u_int, u_int); static int tty_large_region(struct tty *, const struct tty_ctx *); -static int tty_fake_bce(const struct tty *, const struct window_pane *); +static int tty_fake_bce(const struct tty *, const struct window_pane *, + u_int); 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); @@ -64,6 +65,8 @@ static void tty_cell(struct tty *, const struct grid_cell *, const struct window_pane *); static void tty_default_colours(struct grid_cell *, const struct window_pane *); +static void tty_default_attributes(struct tty *, const struct window_pane *, + u_int); #define tty_use_acs(tty) \ (tty_term_has((tty)->term, TTYC_ACSC) && !((tty)->flags & TTY_UTF8)) @@ -604,17 +607,20 @@ tty_large_region(__unused struct tty *tty, const struct tty_ctx *ctx) * emulated. */ static int -tty_fake_bce(const struct tty *tty, const struct window_pane *wp) +tty_fake_bce(const struct tty *tty, const struct window_pane *wp, u_int bg) { struct grid_cell gc; + if (tty_term_flag(tty->term, TTYC_BCE)) + return (0); + memcpy(&gc, &grid_default_cell, sizeof gc); if (wp != NULL) tty_default_colours(&gc, wp); - if (gc.bg == 8) - return (0); - return (!tty_term_flag(tty->term, TTYC_BCE)); + if (bg != 8 || gc.bg != 8) + return (1); + return (0); } /* @@ -695,13 +701,13 @@ tty_draw_line(struct tty *tty, const struct window_pane *wp, } if (sx < tty->sx) { - tty_attributes(tty, &grid_default_cell, wp); + tty_default_attributes(tty, wp, 8); tty_cursor(tty, ox + sx, oy + py); if (sx != screen_size_x(s) && ox + screen_size_x(s) >= tty->sx && tty_term_has(tty->term, TTYC_EL) && - !tty_fake_bce(tty, wp)) + !tty_fake_bce(tty, wp, 8)) tty_putcode(tty, TTYC_EL); else tty_repeat_space(tty, screen_size_x(s) - sx); @@ -759,14 +765,15 @@ tty_cmd_insertcharacter(struct tty *tty, const struct tty_ctx *ctx) { struct window_pane *wp = ctx->wp; - if (!tty_pane_full_width(tty, ctx) || tty_fake_bce(tty, wp) || - (!tty_term_has(tty->term, TTYC_DCH) && - !tty_term_has(tty->term, TTYC_DCH1))) { + if (!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); return; } - tty_attributes(tty, &grid_default_cell, wp); + tty_default_attributes(tty, wp, ctx->bg); tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); @@ -778,14 +785,15 @@ tty_cmd_deletecharacter(struct tty *tty, const struct tty_ctx *ctx) { struct window_pane *wp = ctx->wp; - if (!tty_pane_full_width(tty, ctx) || tty_fake_bce(tty, wp) || + if (!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); return; } - tty_attributes(tty, &grid_default_cell, wp); + tty_default_attributes(tty, wp, ctx->bg); tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); @@ -801,7 +809,8 @@ tty_cmd_clearcharacter(struct tty *tty, const struct tty_ctx *ctx) tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); - if (tty_term_has(tty->term, TTYC_ECH) && !tty_fake_bce(tty, ctx->wp)) + if (tty_term_has(tty->term, TTYC_ECH) && + !tty_fake_bce(tty, ctx->wp, ctx->bg)) tty_putcode1(tty, TTYC_ECH, ctx->num); else { for (i = 0; i < ctx->num; i++) @@ -812,14 +821,15 @@ 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) || tty_fake_bce(tty, ctx->wp) || + if (!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)) { tty_redraw_region(tty, ctx); return; } - tty_attributes(tty, &grid_default_cell, ctx->wp); + tty_default_attributes(tty, ctx->wp, ctx->bg); tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower); tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); @@ -830,14 +840,15 @@ 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) || tty_fake_bce(tty, ctx->wp) || + if (!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)) { tty_redraw_region(tty, ctx); return; } - tty_attributes(tty, &grid_default_cell, ctx->wp); + tty_default_attributes(tty, ctx->wp, ctx->bg); tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower); tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); @@ -851,11 +862,12 @@ tty_cmd_clearline(struct tty *tty, const struct tty_ctx *ctx) struct window_pane *wp = ctx->wp; struct screen *s = wp->screen; - tty_attributes(tty, &grid_default_cell, wp); + tty_default_attributes(tty, wp, ctx->bg); tty_cursor_pane(tty, ctx, 0, ctx->ocy); - if (tty_pane_full_width(tty, ctx) && !tty_fake_bce(tty, wp) && + if (tty_pane_full_width(tty, ctx) && + !tty_fake_bce(tty, wp, ctx->bg) && tty_term_has(tty->term, TTYC_EL)) tty_putcode(tty, TTYC_EL); else @@ -868,12 +880,13 @@ tty_cmd_clearendofline(struct tty *tty, const struct tty_ctx *ctx) struct window_pane *wp = ctx->wp; struct screen *s = wp->screen; - tty_attributes(tty, &grid_default_cell, wp); + tty_default_attributes(tty, wp, ctx->bg); tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); if (tty_pane_full_width(tty, ctx) && - tty_term_has(tty->term, TTYC_EL) && !tty_fake_bce(tty, wp)) + tty_term_has(tty->term, TTYC_EL) && + !tty_fake_bce(tty, wp, ctx->bg)) tty_putcode(tty, TTYC_EL); else tty_repeat_space(tty, screen_size_x(s) - ctx->ocx); @@ -882,10 +895,13 @@ tty_cmd_clearendofline(struct tty *tty, const struct tty_ctx *ctx) void tty_cmd_clearstartofline(struct tty *tty, const struct tty_ctx *ctx) { - tty_attributes(tty, &grid_default_cell, ctx->wp); + struct window_pane *wp = ctx->wp; - if (ctx->xoff == 0 && tty_term_has(tty->term, TTYC_EL1) && - !tty_fake_bce(tty, ctx->wp)) { + tty_default_attributes(tty, wp, ctx->bg); + + if (ctx->xoff == 0 && + tty_term_has(tty->term, TTYC_EL1) && + !tty_fake_bce(tty, ctx->wp, ctx->bg)) { tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); tty_putcode(tty, TTYC_EL1); } else { @@ -900,7 +916,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) || tty_fake_bce(tty, ctx->wp) || + if (!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_RI)) { tty_redraw_region(tty, ctx); @@ -923,7 +940,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_fake_bce(tty, wp) || + if (!tty_pane_full_width(tty, ctx) || + tty_fake_bce(tty, wp, ctx->bg) || !tty_term_has(tty->term, TTYC_CSR)) { if (tty_large_region(tty, ctx)) wp->flags |= PANE_REDRAW; @@ -955,13 +973,14 @@ tty_cmd_clearendofscreen(struct tty *tty, const struct tty_ctx *ctx) struct screen *s = wp->screen; u_int i, j; - tty_attributes(tty, &grid_default_cell, wp); + tty_default_attributes(tty, wp, ctx->bg); tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1); tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); if (tty_pane_full_width(tty, ctx) && - tty_term_has(tty->term, TTYC_EL) && !tty_fake_bce(tty, wp)) { + tty_term_has(tty->term, TTYC_EL) && + !tty_fake_bce(tty, wp, ctx->bg)) { tty_putcode(tty, TTYC_EL); if (ctx->ocy != screen_size_y(s) - 1) { tty_cursor_pane(tty, ctx, 0, ctx->ocy + 1); @@ -995,7 +1014,8 @@ tty_cmd_clearstartofscreen(struct tty *tty, const struct tty_ctx *ctx) tty_cursor_pane(tty, ctx, 0, 0); if (tty_pane_full_width(tty, ctx) && - tty_term_has(tty->term, TTYC_EL) && !tty_fake_bce(tty, wp)) { + tty_term_has(tty->term, TTYC_EL) && + !tty_fake_bce(tty, wp, ctx->bg)) { for (i = 0; i < ctx->ocy; i++) { tty_putcode(tty, TTYC_EL); tty_emulate_repeat(tty, TTYC_CUD, TTYC_CUD1, 1); @@ -1017,13 +1037,14 @@ tty_cmd_clearscreen(struct tty *tty, const struct tty_ctx *ctx) struct screen *s = wp->screen; u_int i, j; - tty_attributes(tty, &grid_default_cell, wp); + tty_default_attributes(tty, wp, ctx->bg); tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1); tty_cursor_pane(tty, ctx, 0, 0); if (tty_pane_full_width(tty, ctx) && - tty_term_has(tty->term, TTYC_EL) && !tty_fake_bce(tty, wp)) { + tty_term_has(tty->term, TTYC_EL) && + !tty_fake_bce(tty, wp, ctx->bg)) { for (i = 0; i < screen_size_y(s); i++) { tty_putcode(tty, TTYC_EL); if (i != screen_size_y(s) - 1) { @@ -1721,3 +1742,13 @@ tty_default_colours(struct grid_cell *gc, const struct window_pane *wp) gc->bg = wgc->bg; } } + +static void +tty_default_attributes(struct tty *tty, const struct window_pane *wp, u_int bg) +{ + static struct grid_cell gc; + + memcpy(&gc, &grid_default_cell, sizeof gc); + gc.bg = bg; + tty_attributes(tty, &gc, wp); +} diff --git a/window-choose.c b/window-choose.c index 02c10257..25dc77d1 100644 --- a/window-choose.c +++ b/window-choose.c @@ -900,7 +900,7 @@ window_choose_scroll_up(struct window_pane *wp) screen_write_start(&ctx, wp, NULL); screen_write_cursormove(&ctx, 0, 0); - screen_write_insertline(&ctx, 1); + screen_write_insertline(&ctx, 1, 8); window_choose_write_line(wp, &ctx, 0); if (screen_size_y(&data->screen) > 1) window_choose_write_line(wp, &ctx, 1); @@ -920,7 +920,7 @@ window_choose_scroll_down(struct window_pane *wp) screen_write_start(&ctx, wp, NULL); screen_write_cursormove(&ctx, 0, 0); - screen_write_deleteline(&ctx, 1); + screen_write_deleteline(&ctx, 1, 8); window_choose_write_line(wp, &ctx, screen_size_y(s) - 1); if (screen_size_y(&data->screen) > 1) window_choose_write_line(wp, &ctx, screen_size_y(s) - 2); diff --git a/window-clock.c b/window-clock.c index c80e9af7..97121108 100644 --- a/window-clock.c +++ b/window-clock.c @@ -221,7 +221,7 @@ window_clock_draw_screen(struct window_pane *wp) } else strftime(tim, sizeof tim, "%H:%M", tm); - screen_write_clearscreen(&ctx); + screen_write_clearscreen(&ctx, 8); if (screen_size_x(s) < 6 * strlen(tim) || screen_size_y(s) < 6) { if (screen_size_x(s) >= strlen(tim) && screen_size_y(s) != 0) { diff --git a/window-copy.c b/window-copy.c index 86c90134..507461d6 100644 --- a/window-copy.c +++ b/window-copy.c @@ -2052,7 +2052,7 @@ window_copy_scroll_up(struct window_pane *wp, u_int ny) screen_write_start(&ctx, wp, NULL); screen_write_cursormove(&ctx, 0, 0); - screen_write_deleteline(&ctx, ny); + screen_write_deleteline(&ctx, ny, 8); window_copy_write_lines(wp, &ctx, screen_size_y(s) - ny, ny); window_copy_write_line(wp, &ctx, 0); if (screen_size_y(s) > 1) @@ -2085,7 +2085,7 @@ window_copy_scroll_down(struct window_pane *wp, u_int ny) screen_write_start(&ctx, wp, NULL); screen_write_cursormove(&ctx, 0, 0); - screen_write_insertline(&ctx, ny); + screen_write_insertline(&ctx, ny, 8); window_copy_write_lines(wp, &ctx, 0, ny); if (s->sel.flag && screen_size_y(s) > ny) window_copy_write_line(wp, &ctx, ny); diff --git a/window.c b/window.c index a2a53c06..a65109bc 100644 --- a/window.c +++ b/window.c @@ -1023,7 +1023,7 @@ window_pane_alternate_on(struct window_pane *wp, struct grid_cell *gc, } memcpy(&wp->saved_cell, gc, sizeof wp->saved_cell); - grid_view_clear(s->grid, 0, 0, sx, sy); + grid_view_clear(s->grid, 0, 0, sx, sy, 8); wp->base.grid->flags &= ~GRID_HISTORY;