[net.emacs] Changes to screen-reshaping functions

hoey@nrl-aic (03/26/83)

From:  Dan Hoey <hoey@nrl-aic>

Thanks to Spencer W. Thomas for sending me the lines-on-screen and
columns-on-screen hacks.  I repeat my other request:  Does anyone have
an archive of the Unix Emacs mail?

zorat's version of these changes was in the form of updated display.c,
TrmVT100.c, and TrmAmb.c files.  If you avoided that version on the
basis of the many changes that didn't affect screen reshaping, I have a
smaller change list.  Send to hoey@nrl-aic for a copy, which includes
the changes listed below.

The remainder of this message contains fixes to zorat's version, along
with a fix to the window manager, as described below.

1) Check arguments to avoid destroying emacs.  Your display will look
	funny if you give a number larger than your terminal will
	support, but you won't core-dump (I hope).

2) Provide screen-length and screen-width functions to report the
	current number of lines and columns on the screen.

3) Fix an anomaly in the shrink-window/enlarge-window code when the
	Minibuffer occupies a real window.

4) The published version of lines-on-screen deletes all but the current
	window.  The enclosed changes extend or shrink the last window,
	deleting windows that don't fit, except that the minibuffer is
	preserved.  Unfortunately, we still do a full-screen redisplay,
	but fixing that would require more understanding of the dread
	redisplay algorithm (:=).

5) The Ann Arbor Ambassador changes seemed to screw up when the screen
	height was less than 60.  Lines that were in the terminal memory
	but off-screen would scroll onto the screen when a delete-lines
	function was used.  These changes fix that by also changing the
	memory size.  Also, the possibility of 20 lines was omitted, and
	it is included below.  Thanks to Jeff Coleman for this item.

6) The VT100 clear-screen took a lot longer.  Don't set the screen width
	unless it changes.

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:::: Changes to display.c
:::: Replace ScreenLines and ScreenColumns procedures
static GetScreenLength() {
    MLvalue -> exp_type = IsInteger;
    MLvalue -> exp_int = tt.t_length;
    return 0;
}
static GetScreenWidth() {
    MLvalue -> exp_type = IsInteger;
    MLvalue -> exp_int = tt.t_width;
    return 0;
}

/* AZ routine to change number of lines on screen */
visible procedure ScreenLines () {
    int     newlen = getnum (": lines-on-screen ");
    if ((newlen < 4) || (newlen > MScreenLength)) {
	error ("Bad number of lines");
	return 0;
    }
    if (!BumpWindows(newlen - tt.t_length))
        return 0;
    tt.t_length = newlen;
    ScreenGarbaged = 1;
/*    InitWin (); */
    DoDsp (1);
}
/* AZ routine to change number of cols. on screen */
visible procedure ScreenCols () {
    int     newwidth = getnum (": columns-on-screen ");
    if ((newwidth < 3) || (newwidth > MScreenWidth)) {
	error ("Bad number of columns");
	return 0;
    }
    tt.t_width = newwidth;
    ScreenGarbaged = 1;
    DoDsp (1);
}
::::Insert before defproc(ScreenLines...
	defproc (GetScreenLength, "screen-length");
	defproc (GetScreenWidth, "screen-width");
::::Changes to window.c
::::Procedure ChgWHeight
::::Comments at beginning of procedure
/* Change the height of the pointed-to window by delta; returns true iff
   the change succeeds.  Chains forward if dir>0, backward if dir<0 in
   attempting to find a suitable window.  If dir=0, changes pointed-to
   window.  Will not change the last buffer on the screen, that's the
   minibuffer.
*/
::::Change if statement from
 	if (w -> w_height + delta >= (w -> w_buf == minibuf ? 1 : 2)
 		&& (dir == 0 || w -> w_buf != minibuf)) {
::::to
 	if (w -> w_height + delta >= (w -> w_next ? 2 : 1)
 		&& (dir == 0 || w -> w_next)) {
::::Add procedure
/* Change total window height by delta.  We try to change the last windows on
   the screen, deleting them if necessary.
 */
BumpWindows(delta)
register    delta; {
    register struct window *w;
    for (w = windows; w -> w_next;)
	w = w -> w_next;
 /* Drop windows off bottom of screen */
    while (w -> w_prev && w -> w_prev -> w_height + delta < 2)
	DelWin (w -> w_prev);
    if (!w -> w_prev) {
	error ("Emacs bug -- ran out of windows");
	return 0;
    }
 /* Adjust height of bottom window */
    if (!ChgWHeight (w -> w_prev, delta, 0)) {
	error ("Emacs bug -- crunching windows");
	return 0;
    }
    return 1;
}

::::Changes to TrmVT100.c
::::insert after declaration of WindowSize
static
int	Ncols;
::::in procedure reset()
::::Change the printf (ScreenWidth <= 80 ... statement to
    if (Ncols != tt.t_width) {
	printf ("\033[?3%c", (((Ncols = tt.t_width) <= 80) ? 'l' : 'h'));
	pad (1, 128.0);
    }
::::insert at end of TrmVT100 procedure
	Ncols = 0;
::::Changes to TrmAmb.c
::::in procedure reset
::::Change the if (ScreenLength... statements to
    if (ScreenLength <= 18 ) printf ("\033[18;0;0;18p");
    if (ScreenLength > 18 && ScreenLength <= 20) printf ("\033[20;0;0;20p");
    if (ScreenLength > 20 && ScreenLength <= 22) printf ("\033[22;0;0;22p");
    if (ScreenLength > 22 && ScreenLength <= 24) printf ("\033[24;0;0;24p");
    if (ScreenLength > 24 && ScreenLength <= 26) printf ("\033[26;0;0;26p");
    if (ScreenLength > 26 && ScreenLength <= 28) printf ("\033[28;0;0;28p");
    if (ScreenLength > 28 && ScreenLength <= 30) printf ("\033[30;0;0;30p");
    if (ScreenLength > 30 && ScreenLength <= 36) printf ("\033[36;0;0;36p");
    if (ScreenLength > 36 && ScreenLength <= 40) printf ("\033[40;0;0;40p");
    if (ScreenLength > 40 && ScreenLength <= 48) printf ("\033[48;0;0;48p");
    if (ScreenLength > 48 && ScreenLength <= 60) printf ("\033[60;0;0;60p");
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::