/* Clear area. */ void grid_clear(struct grid *gd, u_int px, u_int py, u_int nx, u_int ny) { u_int xx, yy; GRID_DEBUG(gd, "px=%u, py=%u, nx=%u, ny=%u", px, py, nx, ny); if (nx == 0 || ny == 0) return; if (px == 0 && nx == gd->sx) { grid_clear_lines(gd, py, ny); return; } if (grid_check_y(gd, py) != 0) return; if (grid_check_y(gd, py + ny - 1) != 0) return; for (yy = py; yy < py + ny; yy++) { if (px >= gd->linedata[yy].cellsize) continue; if (px + nx >= gd->linedata[yy].cellsize) { gd->linedata[yy].cellsize = px; continue; } for (xx = px; xx < px + nx; xx++) { if (xx >= gd->linedata[yy].cellsize) break; grid_put_cell(gd, xx, yy, &grid_default_cell); } } }
/* Move a group of lines. */ void grid_move_lines(struct grid *gd, u_int dy, u_int py, u_int ny) { u_int yy; if (ny == 0 || py == dy) return; if (grid_check_y(gd, py) != 0) return; if (grid_check_y(gd, py + ny - 1) != 0) return; if (grid_check_y(gd, dy) != 0) return; if (grid_check_y(gd, dy + ny - 1) != 0) return; /* Free any lines which are being replaced. */ for (yy = dy; yy < dy + ny; yy++) { if (yy >= py && yy < py + ny) continue; grid_clear_lines(gd, yy, 1); } memmove(&gd->linedata[dy], &gd->linedata[py], ny * (sizeof *gd->linedata)); /* 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]); } }
/* Clear area. */ void grid_clear(struct grid *gd, u_int px, u_int py, u_int nx, u_int ny, u_int bg) { struct grid_line *gl; u_int xx, yy; if (nx == 0 || ny == 0) return; if (px == 0 && nx == gd->sx) { grid_clear_lines(gd, py, ny, bg); return; } if (grid_check_y(gd, __func__, py) != 0) return; if (grid_check_y(gd, __func__, py + ny - 1) != 0) return; for (yy = py; yy < py + ny; yy++) { gl = &gd->linedata[yy]; if (px + nx >= gd->sx && px < gl->cellused) gl->cellused = px; if (px > gl->cellsize && COLOUR_DEFAULT(bg)) continue; if (px + nx >= gl->cellsize && COLOUR_DEFAULT(bg)) { gl->cellsize = px; continue; } grid_expand_line(gd, yy, px + nx, 8); /* default bg first */ for (xx = px; xx < px + nx; xx++) grid_clear_cell(gd, xx, yy, bg); } }
/* * Duplicate a set of lines between two grids. If there aren't enough lines in * either source or destination, the number of lines is limited to the number * available. */ void grid_duplicate_lines(struct grid *dst, u_int dy, struct grid *src, u_int sy, u_int ny) { struct grid_line *dstl, *srcl; u_int yy; if (dy + ny > dst->hsize + dst->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); for (yy = 0; yy < ny; yy++) { srcl = &src->linedata[sy]; dstl = &dst->linedata[dy]; memcpy(dstl, srcl, sizeof *dstl); if (srcl->cellsize != 0) { dstl->celldata = xcalloc( srcl->cellsize, sizeof *dstl->celldata); memcpy(dstl->celldata, srcl->celldata, srcl->cellsize * sizeof *dstl->celldata); } sy++; dy++; } }
/* Clear area. */ void grid_clear(struct grid *gd, u_int px, u_int py, u_int nx, u_int ny, u_int bg) { u_int xx, yy; if (nx == 0 || ny == 0) return; if (px == 0 && nx == gd->sx) { grid_clear_lines(gd, py, ny, bg); return; } if (grid_check_y(gd, py) != 0) return; if (grid_check_y(gd, py + ny - 1) != 0) return; for (yy = py; yy < py + ny; yy++) { 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 && bg == 8) { gd->linedata[yy].cellsize = px; continue; } grid_expand_line(gd, yy, px + nx, bg); for (xx = px; xx < px + nx; xx++) grid_clear_cell(gd, xx, yy, bg); } }
/* Clear the history. */ void grid_clear_history(struct grid *gd) { grid_clear_lines(gd, 0, gd->hsize); grid_move_lines(gd, 0, gd->hsize, gd->sy); gd->hsize = 0; gd->linedata = xreallocarray(gd->linedata, gd->sy, sizeof *gd->linedata); }
/* Reinitialise screen. */ void screen_reinit(struct screen *s) { s->cx = 0; s->cy = 0; s->rupper = 0; s->rlower = screen_size_y(s) - 1; s->mode = MODE_CURSOR | MODE_WRAP; screen_reset_tabs(s); grid_clear_lines(s->grid, s->grid->hsize, s->grid->sy); screen_clear_selection(s); }