version 1.3, 2009/06/04 18:48:24 |
version 1.4, 2009/06/24 19:12:44 |
|
|
screen_resize_y(struct screen *s, u_int sy) |
screen_resize_y(struct screen *s, u_int sy) |
{ |
{ |
struct grid *gd = s->grid; |
struct grid *gd = s->grid; |
u_int oy, yy, ny; |
u_int needed, available, oldy, i; |
|
|
if (sy == 0) |
if (sy == 0) |
fatalx("zero size"); |
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. */ |
/* Size decreasing. */ |
if (sy < screen_size_y(s)) { |
if (sy < oldy) { |
oy = screen_size_y(s); |
needed = oldy - sy; |
|
|
if (s->cy != 0) { |
/* Delete as many lines as possible from the bottom. */ |
/* |
available = oldy - 1 - s->cy; |
* The cursor is not at the start. Try to remove as |
if (available > 0) { |
* many lines as possible from the top. (Up to the |
if (available > needed) |
* cursor line.) |
available = needed; |
*/ |
grid_view_delete_lines(gd, oldy - available, available); |
ny = s->cy; |
|
if (ny > oy - sy) |
|
ny = oy - sy; |
|
|
|
grid_view_delete_lines(gd, 0, ny); |
|
|
|
s->cy -= ny; |
|
oy -= ny; |
|
} |
} |
|
needed -= available; |
|
|
if (sy < oy) { |
/* |
/* Remove any remaining lines from the bottom. */ |
* Now just increase the history size to take over the lines |
grid_view_delete_lines(gd, sy, oy - sy); |
* which are left. XXX Should apply history limit? |
if (s->cy >= sy) |
*/ |
s->cy = sy - 1; |
gd->hsize += needed; |
} |
s->cy -= needed; |
} |
} |
|
|
/* Resize line arrays. */ |
/* Resize line arrays. */ |
gd->size = xrealloc(gd->size, gd->hsize + sy, sizeof *gd->size); |
gd->size = xrealloc(gd->size, gd->hsize + sy, sizeof *gd->size); |
|
|
gd->udata = xrealloc(gd->udata, gd->hsize + sy, sizeof *gd->udata); |
gd->udata = xrealloc(gd->udata, gd->hsize + sy, sizeof *gd->udata); |
|
|
/* Size increasing. */ |
/* Size increasing. */ |
if (sy > screen_size_y(s)) { |
if (sy > oldy) { |
oy = screen_size_y(s); |
needed = sy - oldy; |
for (yy = gd->hsize + oy; yy < gd->hsize + sy; yy++) { |
|
gd->size[yy] = 0; |
/* Try to pull as much as possible out of the history. */ |
gd->data[yy] = NULL; |
available = gd->hsize; |
gd->usize[yy] = 0; |
if (available > 0) { |
gd->udata[yy] = NULL; |
if (available > needed) |
|
available = needed; |
|
gd->hsize -= available; |
|
s->cy += available; |
} |
} |
|
needed -= available; |
|
|
|
/* Then fill the rest in with blanks. */ |
|
for (i = gd->hsize + sy - needed; i < gd->hsize + sy; i++) { |
|
gd->size[i] = gd->usize[i] = 0; |
|
gd->data[i] = gd->udata[i] = NULL; |
|
} |
} |
} |
|
|
|
/* Set the new size, and reset the scroll region. */ |
gd->sy = sy; |
gd->sy = sy; |
|
|
s->rupper = 0; |
s->rupper = 0; |
s->rlower = screen_size_y(s) - 1; |
s->rlower = screen_size_y(s) - 1; |
} |
} |