=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/tmux/grid.c,v retrieving revision 1.57 retrieving revision 1.58 diff -u -r1.57 -r1.58 --- src/usr.bin/tmux/grid.c 2016/10/11 13:21:59 1.57 +++ src/usr.bin/tmux/grid.c 2016/10/13 20:27:27 1.58 @@ -1,4 +1,4 @@ -/* $OpenBSD: grid.c,v 1.57 2016/10/11 13:21:59 nicm Exp $ */ +/* $OpenBSD: grid.c,v 1.58 2016/10/13 20:27:27 nicm Exp $ */ /* * Copyright (c) 2008 Nicholas Marriott @@ -43,7 +43,8 @@ 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 @@ /* 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 @@ * 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 @@ 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 @@ * 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 @@ 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 @@ /* 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 @@ 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 @@ 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 @@ /* 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ /* 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ /* 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 @@ /* 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 @@ 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);