newdisp[i]->chars[i].attr = ATTR_INVALID;
newdisp[i]->chars[j].attr = ATTR_INVALID;
void term_size(Terminal *term, int newrows, int newcols, int newsavelines){    tree234 *newalt;    termline **newdisp, *line;    int i, j, oldrows = term->rows;    int sblen;    int save_alt_which = term->alt_which;    if (newrows == term->rows && newcols == term->cols &&	newsavelines == term->savelines)	return;			       /* nothing to do */    deselect(term);    swap_screen(term, 0, FALSE, FALSE);    term->alt_t = term->marg_t = 0;    term->alt_b = term->marg_b = newrows - 1;    if (term->rows == -1) {	term->scrollback = newtree234(NULL);	term->screen = newtree234(NULL);	term->tempsblines = 0;	term->rows = 0;    }    /*     * Resize the screen and scrollback. We only need to shift     * lines around within our data structures, because lineptr()     * will take care of resizing each individual line if     * necessary. So:     *      *  - If the new screen is longer, we shunt lines in from temporary     *    scrollback if possible, otherwise we add new blank lines at     *    the bottom.     *     *  - If the new screen is shorter, we remove any blank lines at     *    the bottom if possible, otherwise shunt lines above the cursor     *    to scrollback if possible, otherwise delete lines below the     *    cursor.     *      *  - Then, if the new scrollback length is less than the     *    amount of scrollback we actually have, we must throw some     *    away.     */    sblen = count234(term->scrollback);    /* Do this loop to expand the screen if newrows > rows */    assert(term->rows == count234(term->screen));    while (term->rows < newrows) {	if (term->tempsblines > 0) {	    unsigned char *cline;	    /* Insert a line from the scrollback at the top of the screen. */	    assert(sblen >= term->tempsblines);	    cline = delpos234(term->scrollback, --sblen);	    line = decompressline(cline, NULL);	    sfree(cline);	    line->temporary = FALSE;   /* reconstituted line is now real */	    term->tempsblines -= 1;	    addpos234(term->screen, line, 0);	    term->curs.y += 1;	    term->savecurs.y += 1;	} else {	    /* Add a new blank line at the bottom of the screen. */	    line = newline(term, newcols, FALSE);	    addpos234(term->screen, line, count234(term->screen));	}	term->rows += 1;    }    /* Do this loop to shrink the screen if newrows < rows */    while (term->rows > newrows) {	if (term->curs.y < term->rows - 1) {	    /* delete bottom row, unless it contains the cursor */	    sfree(delpos234(term->screen, term->rows - 1));	} else {	    /* push top row to scrollback */	    line = delpos234(term->screen, 0);	    addpos234(term->scrollback, compressline(line), sblen++);	    freeline(line);	    term->tempsblines += 1;	    term->curs.y -= 1;	    term->savecurs.y -= 1;	}	term->rows -= 1;    }    assert(term->rows == newrows);    assert(count234(term->screen) == newrows);    /* Delete any excess lines from the scrollback. */    while (sblen > newsavelines) {	line = delpos234(term->scrollback, 0);	sfree(line);	sblen--;    }    if (sblen < term->tempsblines)	term->tempsblines = sblen;    assert(count234(term->scrollback) <= newsavelines);    assert(count234(term->scrollback) >= term->tempsblines);    term->disptop = 0;    /* Make a new displayed text buffer. */    newdisp = snewn(newrows, termline *);    for (i = 0; i < newrows; i++) {	newdisp[i] = newline(term, newcols, FALSE);	for (j = 0; j < newcols; j++)	    newdisp[i]->chars[i].attr = ATTR_INVALID;    }    if (term->disptext) {	for (i = 0; i < oldrows; i++)	    freeline(term->disptext[i]);    }    sfree(term->disptext);    term->disptext = newdisp;    term->dispcursx = term->dispcursy = -1;    /* Make a new alternate screen. */    newalt = newtree234(NULL);    for (i = 0; i < newrows; i++) {	line = newline(term, newcols, TRUE);	addpos234(newalt, line, i);    }    if (term->alt_screen) {	while (NULL != (line = delpos234(term->alt_screen, 0)))	    freeline(line);	freetree234(term->alt_screen);    }    term->alt_screen = newalt;    term->alt_sblines = 0;    term->tabs = sresize(term->tabs, newcols, unsigned char);    {	int i;	for (i = (term->cols > 0 ? term->cols : 0); i < newcols; i++)	    term->tabs[i] = (i % 8 == 0 ? TRUE : FALSE);    }    /* Check that the cursor positions are still valid. */    if (term->savecurs.y < 0)	term->savecurs.y = 0;    if (term->savecurs.y >= newrows)	term->savecurs.y = newrows - 1;    if (term->curs.y < 0)	term->curs.y = 0;    if (term->curs.y >= newrows)	term->curs.y = newrows - 1;    if (term->curs.x >= newcols)	term->curs.x = newcols - 1;    term->alt_x = term->alt_y = 0;    term->wrapnext = term->alt_wnext = FALSE;    term->rows = newrows;    term->cols = newcols;    term->savelines = newsavelines;    swap_screen(term, save_alt_which, FALSE, FALSE);    update_sbar(term);    term_update(term);    if (term->resize_fn)	term->resize_fn(term->resize_ctx, term->cols, term->rows);}