term->selstart.y = botline;
term->selstart.y = botline + 1;
static void scroll(Terminal *term, int topline, int botline, int lines, int sb){    unsigned long *line, *line2;    int i, seltop, olddisptop, shift;    if (topline != 0 || term->alt_which != 0)	sb = FALSE;    olddisptop = term->disptop;    shift = lines;    if (lines < 0) {	while (lines < 0) {	    line = delpos234(term->screen, botline);            line = resizeline(line, term->cols);	    for (i = 0; i < term->cols; i++)		line[i + 1] = term->erase_char;	    line[term->cols + 1] = 0;	    addpos234(term->screen, line, topline);	    if (term->selstart.y >= topline && term->selstart.y <= botline) {		term->selstart.y++;		if (term->selstart.y > botline) {		    term->selstart.y = botline;		    term->selstart.x = 0;		}	    }	    if (term->selend.y >= topline && term->selend.y <= botline) {		term->selend.y++;		if (term->selend.y > botline) {		    term->selend.y = botline;		    term->selend.x = 0;		}	    }	    lines++;	}    } else {	while (lines > 0) {	    line = delpos234(term->screen, topline);	    if (sb && term->savelines > 0) {		int sblen = count234(term->scrollback);		/*		 * We must add this line to the scrollback. We'll		 * remove a line from the top of the scrollback to		 * replace it, or allocate a new one if the		 * scrollback isn't full.		 */		if (sblen == term->savelines) {		    sblen--, line2 = delpos234(term->scrollback, 0);		} else {		    line2 = smalloc(TSIZE * (term->cols + 2));		    line2[0] = term->cols;		    term->tempsblines += 1;		}		addpos234(term->scrollback, line, sblen);		line = line2;		/*		 * If the user is currently looking at part of the		 * scrollback, and they haven't enabled any options		 * that are going to reset the scrollback as a		 * result of this movement, then the chances are		 * they'd like to keep looking at the same line. So		 * we move their viewpoint at the same rate as the		 * scroll, at least until their viewpoint hits the		 * top end of the scrollback buffer, at which point		 * we don't have the choice any more.		 * 		 * Thanks to Jan Holmen Holsten for the idea and		 * initial implementation.		 */		if (term->disptop > -term->savelines && term->disptop < 0)		    term->disptop--;	    }            line = resizeline(line, term->cols);	    for (i = 0; i < term->cols; i++)		line[i + 1] = term->erase_char;	    line[term->cols + 1] = LATTR_NORM;	    addpos234(term->screen, line, botline);	    /*	     * If the selection endpoints move into the scrollback,	     * we keep them moving until they hit the top. However,	     * of course, if the line _hasn't_ moved into the	     * scrollback then we don't do this, and cut them off	     * at the top of the scroll region.	     * 	     * This applies to selstart and selend (for an existing	     * selection), and also selanchor (for one being	     * selected as we speak).	     */	    seltop = sb ? -term->savelines : topline;	    if (term->selstart.y >= seltop &&		term->selstart.y <= botline) {		term->selstart.y--;		if (term->selstart.y < seltop) {		    term->selstart.y = seltop;		    term->selstart.x = 0;		}	    }	    if (term->selend.y >= seltop && term->selend.y <= botline) {		term->selend.y--;		if (term->selend.y < seltop) {		    term->selend.y = seltop;		    term->selend.x = 0;		}	    }	    if (term->selanchor.y >= seltop && term->selanchor.y <= botline) {		term->selanchor.y--;		if (term->selanchor.y < seltop) {		    term->selanchor.y = seltop;		    term->selanchor.x = 0;		}	    }	    lines--;	}    }#ifdef OPTIMISE_SCROLL    shift += term->disptop - olddisptop;    if (shift < term->rows && shift > -term->rows && shift != 0)	scroll_display(term, topline, botline, shift);#endif /* OPTIMISE_SCROLL */}