/* Delete ny lines. */ void screen_write_deleteline(struct screen_write_ctx *ctx, u_int ny, u_int bg) { struct screen *s = ctx->s; struct tty_ctx ttyctx; if (ny == 0) ny = 1; if (s->cy < s->rupper || s->cy > s->rlower) { if (ny > screen_size_y(s) - s->cy) ny = screen_size_y(s) - s->cy; if (ny == 0) return; screen_write_flush(ctx); screen_write_initctx(ctx, &ttyctx); grid_view_delete_lines(s->grid, s->cy, ny, bg); ttyctx.num = ny; ttyctx.bg = bg; tty_write(tty_cmd_deleteline, &ttyctx); return; } if (ny > s->rlower + 1 - s->cy) ny = s->rlower + 1 - s->cy; if (ny == 0) return; screen_write_flush(ctx); screen_write_initctx(ctx, &ttyctx); if (s->cy < s->rupper || s->cy > s->rlower) 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); }
void screen_resize_y(struct screen *s, u_int sy) { struct grid *gd = s->grid; u_int needed, available, oldy, i; if (sy == 0) fatalx("zero size"); oldy = screen_size_y(s); /* * When resizing: * * If the height is decreasing, delete lines from the bottom until * hitting the cursor, then push lines from the top into the history. * * When increasing, pull as many lines as possible from the history to * the top, then fill the remaining with blanks at the bottom. */ /* Size decreasing. */ if (sy < oldy) { needed = oldy - sy; /* Delete as many lines as possible from the bottom. */ available = oldy - 1 - s->cy; if (available > 0) { if (available > needed) available = needed; grid_view_delete_lines(gd, oldy - available, available); } needed -= available; /* * Now just increase the history size, if possible, to take * over the lines which are left. If history is off, delete * lines from the top. */ available = s->cy; if (gd->flags & GRID_HISTORY) gd->hsize += needed; else if (needed > 0 && available > 0) { if (available > needed) available = needed; grid_view_delete_lines(gd, 0, available); } s->cy -= needed; } /* Resize line arrays. */ gd->linedata = xreallocarray(gd->linedata, gd->hsize + sy, sizeof *gd->linedata); /* Size increasing. */ if (sy > oldy) { needed = sy - oldy; /* * Try to pull as much as possible out of the history, if is * is enabled. */ available = gd->hsize; if (gd->flags & GRID_HISTORY && available > 0) { if (available > needed) available = needed; gd->hsize -= available; s->cy += available; } else available = 0; needed -= available; /* Then fill the rest in with blanks. */ for (i = gd->hsize + sy - needed; i < gd->hsize + sy; i++) memset(&gd->linedata[i], 0, sizeof gd->linedata[i]); } /* Set the new size, and reset the scroll region. */ gd->sy = sy; s->rupper = 0; s->rlower = screen_size_y(s) - 1; }