1  | 
     | 
     | 
    /*	$OpenBSD: window.c,v 1.36 2015/11/18 18:21:06 jasper Exp $	*/  | 
    
    
    2  | 
     | 
     | 
     | 
    
    
    3  | 
     | 
     | 
    /* This file is in the public domain. */  | 
    
    
    4  | 
     | 
     | 
     | 
    
    
    5  | 
     | 
     | 
    /*  | 
    
    
    6  | 
     | 
     | 
     *		Window handling.  | 
    
    
    7  | 
     | 
     | 
     */  | 
    
    
    8  | 
     | 
     | 
     | 
    
    
    9  | 
     | 
     | 
    #include <sys/queue.h>  | 
    
    
    10  | 
     | 
     | 
    #include <signal.h>  | 
    
    
    11  | 
     | 
     | 
    #include <stdio.h>  | 
    
    
    12  | 
     | 
     | 
    #include <stdlib.h>  | 
    
    
    13  | 
     | 
     | 
     | 
    
    
    14  | 
     | 
     | 
    #include "def.h"  | 
    
    
    15  | 
     | 
     | 
     | 
    
    
    16  | 
     | 
     | 
    struct mgwin *  | 
    
    
    17  | 
     | 
     | 
    new_window(struct buffer *bp)  | 
    
    
    18  | 
     | 
     | 
    { | 
    
    
    19  | 
     | 
     | 
    	struct mgwin *wp;  | 
    
    
    20  | 
     | 
     | 
     | 
    
    
    21  | 
     | 
     | 
    	wp = calloc(1, sizeof(struct mgwin));  | 
    
    
    22  | 
     | 
     | 
    	if (wp == NULL)  | 
    
    
    23  | 
     | 
     | 
    		return (NULL);  | 
    
    
    24  | 
     | 
     | 
     | 
    
    
    25  | 
     | 
     | 
    	wp->w_bufp = bp;  | 
    
    
    26  | 
     | 
     | 
    	wp->w_dotp = NULL;  | 
    
    
    27  | 
     | 
     | 
    	wp->w_doto = 0;  | 
    
    
    28  | 
     | 
     | 
    	wp->w_markp = NULL;  | 
    
    
    29  | 
     | 
     | 
    	wp->w_marko = 0;  | 
    
    
    30  | 
     | 
     | 
    	wp->w_rflag = 0;  | 
    
    
    31  | 
     | 
     | 
    	wp->w_frame = 0;  | 
    
    
    32  | 
     | 
     | 
    	wp->w_wrapline = NULL;  | 
    
    
    33  | 
     | 
     | 
    	wp->w_dotline = wp->w_markline = 1;  | 
    
    
    34  | 
     | 
     | 
    	if (bp)  | 
    
    
    35  | 
     | 
     | 
    		bp->b_nwnd++;  | 
    
    
    36  | 
     | 
     | 
    	return (wp);  | 
    
    
    37  | 
     | 
     | 
    }  | 
    
    
    38  | 
     | 
     | 
     | 
    
    
    39  | 
     | 
     | 
    /*  | 
    
    
    40  | 
     | 
     | 
     * Reposition dot in the current window to line "n".  If the argument is  | 
    
    
    41  | 
     | 
     | 
     * positive, it is that line.  If it is negative it is that line from the  | 
    
    
    42  | 
     | 
     | 
     * bottom.  If it is 0 the window is centered (this is what the standard  | 
    
    
    43  | 
     | 
     | 
     * redisplay code does).  | 
    
    
    44  | 
     | 
     | 
     */  | 
    
    
    45  | 
     | 
     | 
    /* ARGSUSED */  | 
    
    
    46  | 
     | 
     | 
    int  | 
    
    
    47  | 
     | 
     | 
    reposition(int f, int n)  | 
    
    
    48  | 
     | 
     | 
    { | 
    
    
    49  | 
     | 
     | 
    	curwp->w_frame = (f & FFARG) ? (n >= 0 ? n + 1 : n) : 0;  | 
    
    
    50  | 
     | 
     | 
    	curwp->w_rflag |= WFFRAME;  | 
    
    
    51  | 
     | 
     | 
    	sgarbf = TRUE;  | 
    
    
    52  | 
     | 
     | 
    	return (TRUE);  | 
    
    
    53  | 
     | 
     | 
    }  | 
    
    
    54  | 
     | 
     | 
     | 
    
    
    55  | 
     | 
     | 
    /*  | 
    
    
    56  | 
     | 
     | 
     * Refresh the display.  A call is made to the "ttresize" entry in the  | 
    
    
    57  | 
     | 
     | 
     * terminal handler, which tries to reset "nrow" and "ncol".  They will,  | 
    
    
    58  | 
     | 
     | 
     * however, never be set outside of the NROW or NCOL range.  If the display  | 
    
    
    59  | 
     | 
     | 
     * changed size, arrange that everything is redone, then call "update" to  | 
    
    
    60  | 
     | 
     | 
     * fix the display.  We do this so the new size can be displayed.  In the  | 
    
    
    61  | 
     | 
     | 
     * normal case the call to "update" in "main.c" refreshes the screen, and  | 
    
    
    62  | 
     | 
     | 
     * all of the windows need not be recomputed. This call includes a  | 
    
    
    63  | 
     | 
     | 
     * 'force' parameter to ensure that the redraw is done, even after a  | 
    
    
    64  | 
     | 
     | 
     * a suspend/continue (where the window size parameters will already  | 
    
    
    65  | 
     | 
     | 
     * be updated). Note that when you get to the "display unusable"  | 
    
    
    66  | 
     | 
     | 
     * message, the screen will be messed up. If you make the window bigger  | 
    
    
    67  | 
     | 
     | 
     * again, and send another command, everything will get fixed!  | 
    
    
    68  | 
     | 
     | 
     */  | 
    
    
    69  | 
     | 
     | 
    int  | 
    
    
    70  | 
     | 
     | 
    redraw(int f, int n)  | 
    
    
    71  | 
     | 
     | 
    { | 
    
    
    72  | 
     | 
     | 
    	return (do_redraw(f, n, FALSE));  | 
    
    
    73  | 
     | 
     | 
    }  | 
    
    
    74  | 
     | 
     | 
     | 
    
    
    75  | 
     | 
     | 
    /* ARGSUSED */  | 
    
    
    76  | 
     | 
     | 
    int  | 
    
    
    77  | 
     | 
     | 
    do_redraw(int f, int n, int force)  | 
    
    
    78  | 
     | 
     | 
    { | 
    
    
    79  | 
     | 
     | 
    	struct mgwin	*wp;  | 
    
    
    80  | 
     | 
     | 
    	int		 oldnrow, oldncol;  | 
    
    
    81  | 
     | 
     | 
     | 
    
    
    82  | 
     | 
     | 
    	oldnrow = nrow;  | 
    
    
    83  | 
     | 
     | 
    	oldncol = ncol;  | 
    
    
    84  | 
     | 
     | 
    	ttresize();  | 
    
    
    85  | 
     | 
     | 
    	if (nrow != oldnrow || ncol != oldncol || force) { | 
    
    
    86  | 
     | 
     | 
     | 
    
    
    87  | 
     | 
     | 
    		/* find last */  | 
    
    
    88  | 
     | 
     | 
    		wp = wheadp;  | 
    
    
    89  | 
     | 
     | 
    		while (wp->w_wndp != NULL)  | 
    
    
    90  | 
     | 
     | 
    			wp = wp->w_wndp;  | 
    
    
    91  | 
     | 
     | 
     | 
    
    
    92  | 
     | 
     | 
    		/* check if too small */  | 
    
    
    93  | 
     | 
     | 
    		if (nrow < wp->w_toprow + 3) { | 
    
    
    94  | 
     | 
     | 
    			dobeep();  | 
    
    
    95  | 
     | 
     | 
    			ewprintf("Display unusable"); | 
    
    
    96  | 
     | 
     | 
    			return (FALSE);  | 
    
    
    97  | 
     | 
     | 
    		}  | 
    
    
    98  | 
     | 
     | 
    		wp->w_ntrows = nrow - wp->w_toprow - 2;  | 
    
    
    99  | 
     | 
     | 
    		sgarbf = TRUE;  | 
    
    
    100  | 
     | 
     | 
    		update(CMODE);  | 
    
    
    101  | 
     | 
     | 
    	} else  | 
    
    
    102  | 
     | 
     | 
    		sgarbf = TRUE;  | 
    
    
    103  | 
     | 
     | 
    	return (TRUE);  | 
    
    
    104  | 
     | 
     | 
    }  | 
    
    
    105  | 
     | 
     | 
     | 
    
    
    106  | 
     | 
     | 
    /*  | 
    
    
    107  | 
     | 
     | 
     * The command to make the next window (next => down the screen) the current  | 
    
    
    108  | 
     | 
     | 
     * window. There are no real errors, although the command does nothing if  | 
    
    
    109  | 
     | 
     | 
     * there is only 1 window on the screen.  | 
    
    
    110  | 
     | 
     | 
     */  | 
    
    
    111  | 
     | 
     | 
    /* ARGSUSED */  | 
    
    
    112  | 
     | 
     | 
    int  | 
    
    
    113  | 
     | 
     | 
    nextwind(int f, int n)  | 
    
    
    114  | 
     | 
     | 
    { | 
    
    
    115  | 
     | 
     | 
    	struct mgwin	*wp;  | 
    
    
    116  | 
     | 
     | 
     | 
    
    
    117  | 
     | 
     | 
    	if ((wp = curwp->w_wndp) == NULL)  | 
    
    
    118  | 
     | 
     | 
    		wp = wheadp;  | 
    
    
    119  | 
     | 
     | 
    	curwp = wp;  | 
    
    
    120  | 
     | 
     | 
    	curbp = wp->w_bufp;  | 
    
    
    121  | 
     | 
     | 
    	return (TRUE);  | 
    
    
    122  | 
     | 
     | 
    }  | 
    
    
    123  | 
     | 
     | 
     | 
    
    
    124  | 
     | 
     | 
    /* not in GNU Emacs */  | 
    
    
    125  | 
     | 
     | 
    /*  | 
    
    
    126  | 
     | 
     | 
     * This command makes the previous window (previous => up the screen) the  | 
    
    
    127  | 
     | 
     | 
     * current window. There are no errors, although the command does not do  | 
    
    
    128  | 
     | 
     | 
     * a lot if there is only 1 window.  | 
    
    
    129  | 
     | 
     | 
     */  | 
    
    
    130  | 
     | 
     | 
    /* ARGSUSED */  | 
    
    
    131  | 
     | 
     | 
    int  | 
    
    
    132  | 
     | 
     | 
    prevwind(int f, int n)  | 
    
    
    133  | 
     | 
     | 
    { | 
    
    
    134  | 
     | 
     | 
    	struct mgwin	*wp1, *wp2;  | 
    
    
    135  | 
     | 
     | 
     | 
    
    
    136  | 
     | 
     | 
    	wp1 = wheadp;  | 
    
    
    137  | 
     | 
     | 
    	wp2 = curwp;  | 
    
    
    138  | 
     | 
     | 
    	if (wp1 == wp2)  | 
    
    
    139  | 
     | 
     | 
    		wp2 = NULL;  | 
    
    
    140  | 
     | 
     | 
    	while (wp1->w_wndp != wp2)  | 
    
    
    141  | 
     | 
     | 
    		wp1 = wp1->w_wndp;  | 
    
    
    142  | 
     | 
     | 
    	curwp = wp1;  | 
    
    
    143  | 
     | 
     | 
    	curbp = wp1->w_bufp;  | 
    
    
    144  | 
     | 
     | 
    	return (TRUE);  | 
    
    
    145  | 
     | 
     | 
    }  | 
    
    
    146  | 
     | 
     | 
     | 
    
    
    147  | 
     | 
     | 
    /*  | 
    
    
    148  | 
     | 
     | 
     * This command makes the current window the only window on the screen.  Try  | 
    
    
    149  | 
     | 
     | 
     * to set the framing so that "." does not have to move on the display.  Some  | 
    
    
    150  | 
     | 
     | 
     * care has to be taken to keep the values of dot and mark in the buffer  | 
    
    
    151  | 
     | 
     | 
     * structures right if the destruction of a window makes a buffer become  | 
    
    
    152  | 
     | 
     | 
     * undisplayed.  | 
    
    
    153  | 
     | 
     | 
     */  | 
    
    
    154  | 
     | 
     | 
    /* ARGSUSED */  | 
    
    
    155  | 
     | 
     | 
    int  | 
    
    
    156  | 
     | 
     | 
    onlywind(int f, int n)  | 
    
    
    157  | 
     | 
     | 
    { | 
    
    
    158  | 
     | 
     | 
    	struct mgwin	*wp;  | 
    
    
    159  | 
     | 
     | 
    	struct line	*lp;  | 
    
    
    160  | 
     | 
     | 
    	int		 i;  | 
    
    
    161  | 
     | 
     | 
     | 
    
    
    162  | 
     | 
     | 
    	while (wheadp != curwp) { | 
    
    
    163  | 
     | 
     | 
    		wp = wheadp;  | 
    
    
    164  | 
     | 
     | 
    		wheadp = wp->w_wndp;  | 
    
    
    165  | 
     | 
     | 
    		if (--wp->w_bufp->b_nwnd == 0) { | 
    
    
    166  | 
     | 
     | 
    			wp->w_bufp->b_dotp = wp->w_dotp;  | 
    
    
    167  | 
     | 
     | 
    			wp->w_bufp->b_doto = wp->w_doto;  | 
    
    
    168  | 
     | 
     | 
    			wp->w_bufp->b_markp = wp->w_markp;  | 
    
    
    169  | 
     | 
     | 
    			wp->w_bufp->b_marko = wp->w_marko;  | 
    
    
    170  | 
     | 
     | 
    			wp->w_bufp->b_dotline = wp->w_dotline;  | 
    
    
    171  | 
     | 
     | 
    			wp->w_bufp->b_markline = wp->w_markline;  | 
    
    
    172  | 
     | 
     | 
    		}  | 
    
    
    173  | 
     | 
     | 
    		free(wp);  | 
    
    
    174  | 
     | 
     | 
    	}  | 
    
    
    175  | 
     | 
     | 
    	while (curwp->w_wndp != NULL) { | 
    
    
    176  | 
     | 
     | 
    		wp = curwp->w_wndp;  | 
    
    
    177  | 
     | 
     | 
    		curwp->w_wndp = wp->w_wndp;  | 
    
    
    178  | 
     | 
     | 
    		if (--wp->w_bufp->b_nwnd == 0) { | 
    
    
    179  | 
     | 
     | 
    			wp->w_bufp->b_dotp = wp->w_dotp;  | 
    
    
    180  | 
     | 
     | 
    			wp->w_bufp->b_doto = wp->w_doto;  | 
    
    
    181  | 
     | 
     | 
    			wp->w_bufp->b_markp = wp->w_markp;  | 
    
    
    182  | 
     | 
     | 
    			wp->w_bufp->b_marko = wp->w_marko;  | 
    
    
    183  | 
     | 
     | 
    			wp->w_bufp->b_dotline = wp->w_dotline;  | 
    
    
    184  | 
     | 
     | 
    			wp->w_bufp->b_markline = wp->w_markline;  | 
    
    
    185  | 
     | 
     | 
    		}  | 
    
    
    186  | 
     | 
     | 
    		free(wp);  | 
    
    
    187  | 
     | 
     | 
    	}  | 
    
    
    188  | 
     | 
     | 
    	lp = curwp->w_linep;  | 
    
    
    189  | 
     | 
     | 
    	i = curwp->w_toprow;  | 
    
    
    190  | 
     | 
     | 
    	while (i != 0 && lback(lp) != curbp->b_headp) { | 
    
    
    191  | 
     | 
     | 
    		--i;  | 
    
    
    192  | 
     | 
     | 
    		lp = lback(lp);  | 
    
    
    193  | 
     | 
     | 
    	}  | 
    
    
    194  | 
     | 
     | 
    	curwp->w_toprow = 0;  | 
    
    
    195  | 
     | 
     | 
     | 
    
    
    196  | 
     | 
     | 
    	/* 2 = mode, echo */  | 
    
    
    197  | 
     | 
     | 
    	curwp->w_ntrows = nrow - 2;  | 
    
    
    198  | 
     | 
     | 
    	curwp->w_linep = lp;  | 
    
    
    199  | 
     | 
     | 
    	curwp->w_rflag |= WFMODE | WFFULL;  | 
    
    
    200  | 
     | 
     | 
    	return (TRUE);  | 
    
    
    201  | 
     | 
     | 
    }  | 
    
    
    202  | 
     | 
     | 
     | 
    
    
    203  | 
     | 
     | 
    /*  | 
    
    
    204  | 
     | 
     | 
     * Split the current window.  A window smaller than 3 lines cannot be split.  | 
    
    
    205  | 
     | 
     | 
     * The only other error that is possible is a "malloc" failure allocating the  | 
    
    
    206  | 
     | 
     | 
     * structure for the new window.  | 
    
    
    207  | 
     | 
     | 
     * If called with a FFOTHARG, flags on the new window are set to 'n'.  | 
    
    
    208  | 
     | 
     | 
     */  | 
    
    
    209  | 
     | 
     | 
    /* ARGSUSED */  | 
    
    
    210  | 
     | 
     | 
    int  | 
    
    
    211  | 
     | 
     | 
    splitwind(int f, int n)  | 
    
    
    212  | 
     | 
     | 
    { | 
    
    
    213  | 
     | 
     | 
    	struct mgwin	*wp, *wp1, *wp2;  | 
    
    
    214  | 
     | 
     | 
    	struct line	*lp;  | 
    
    
    215  | 
     | 
     | 
    	int		 ntru, ntrd, ntrl;  | 
    
    
    216  | 
     | 
     | 
     | 
    
    
    217  | 
     | 
     | 
    	if (curwp->w_ntrows < 3) { | 
    
    
    218  | 
     | 
     | 
    		dobeep();  | 
    
    
    219  | 
     | 
     | 
    		ewprintf("Cannot split a %d line window", curwp->w_ntrows); | 
    
    
    220  | 
     | 
     | 
    		return (FALSE);  | 
    
    
    221  | 
     | 
     | 
    	}  | 
    
    
    222  | 
     | 
     | 
    	wp = new_window(curbp);  | 
    
    
    223  | 
     | 
     | 
    	if (wp == NULL) { | 
    
    
    224  | 
     | 
     | 
    		dobeep();  | 
    
    
    225  | 
     | 
     | 
    		ewprintf("Unable to create a window"); | 
    
    
    226  | 
     | 
     | 
    		return (FALSE);  | 
    
    
    227  | 
     | 
     | 
    	}  | 
    
    
    228  | 
     | 
     | 
     | 
    
    
    229  | 
     | 
     | 
    	/* use the current dot and mark */  | 
    
    
    230  | 
     | 
     | 
    	wp->w_dotp = curwp->w_dotp;  | 
    
    
    231  | 
     | 
     | 
    	wp->w_doto = curwp->w_doto;  | 
    
    
    232  | 
     | 
     | 
    	wp->w_markp = curwp->w_markp;  | 
    
    
    233  | 
     | 
     | 
    	wp->w_marko = curwp->w_marko;  | 
    
    
    234  | 
     | 
     | 
    	wp->w_dotline = curwp->w_dotline;  | 
    
    
    235  | 
     | 
     | 
    	wp->w_markline = curwp->w_markline;  | 
    
    
    236  | 
     | 
     | 
     | 
    
    
    237  | 
     | 
     | 
    	/* figure out which half of the screen we're in */  | 
    
    
    238  | 
     | 
     | 
    	ntru = (curwp->w_ntrows - 1) / 2;	/* Upper size */  | 
    
    
    239  | 
     | 
     | 
    	ntrl = (curwp->w_ntrows - 1) - ntru;	/* Lower size */  | 
    
    
    240  | 
     | 
     | 
     | 
    
    
    241  | 
     | 
     | 
    	for (lp = curwp->w_linep, ntrd = 0; lp != curwp->w_dotp;  | 
    
    
    242  | 
     | 
     | 
    	    lp = lforw(lp))  | 
    
    
    243  | 
     | 
     | 
    		ntrd++;  | 
    
    
    244  | 
     | 
     | 
     | 
    
    
    245  | 
     | 
     | 
    	lp = curwp->w_linep;  | 
    
    
    246  | 
     | 
     | 
     | 
    
    
    247  | 
     | 
     | 
    	/* old is upper window */  | 
    
    
    248  | 
     | 
     | 
    	if (ntrd <= ntru) { | 
    
    
    249  | 
     | 
     | 
    		/* hit mode line */  | 
    
    
    250  | 
     | 
     | 
    		if (ntrd == ntru)  | 
    
    
    251  | 
     | 
     | 
    			lp = lforw(lp);  | 
    
    
    252  | 
     | 
     | 
    		curwp->w_ntrows = ntru;  | 
    
    
    253  | 
     | 
     | 
    		wp->w_wndp = curwp->w_wndp;  | 
    
    
    254  | 
     | 
     | 
    		curwp->w_wndp = wp;  | 
    
    
    255  | 
     | 
     | 
    		wp->w_toprow = curwp->w_toprow + ntru + 1;  | 
    
    
    256  | 
     | 
     | 
    		wp->w_ntrows = ntrl;  | 
    
    
    257  | 
     | 
     | 
    	/* old is lower window */  | 
    
    
    258  | 
     | 
     | 
    	} else { | 
    
    
    259  | 
     | 
     | 
    		wp1 = NULL;  | 
    
    
    260  | 
     | 
     | 
    		wp2 = wheadp;  | 
    
    
    261  | 
     | 
     | 
    		while (wp2 != curwp) { | 
    
    
    262  | 
     | 
     | 
    			wp1 = wp2;  | 
    
    
    263  | 
     | 
     | 
    			wp2 = wp2->w_wndp;  | 
    
    
    264  | 
     | 
     | 
    		}  | 
    
    
    265  | 
     | 
     | 
    		if (wp1 == NULL)  | 
    
    
    266  | 
     | 
     | 
    			wheadp = wp;  | 
    
    
    267  | 
     | 
     | 
    		else  | 
    
    
    268  | 
     | 
     | 
    			wp1->w_wndp = wp;  | 
    
    
    269  | 
     | 
     | 
    		wp->w_wndp = curwp;  | 
    
    
    270  | 
     | 
     | 
    		wp->w_toprow = curwp->w_toprow;  | 
    
    
    271  | 
     | 
     | 
    		wp->w_ntrows = ntru;  | 
    
    
    272  | 
     | 
     | 
     | 
    
    
    273  | 
     | 
     | 
    		/* mode line */  | 
    
    
    274  | 
     | 
     | 
    		++ntru;  | 
    
    
    275  | 
     | 
     | 
    		curwp->w_toprow += ntru;  | 
    
    
    276  | 
     | 
     | 
    		curwp->w_ntrows = ntrl;  | 
    
    
    277  | 
     | 
     | 
    		while (ntru--)  | 
    
    
    278  | 
     | 
     | 
    			lp = lforw(lp);  | 
    
    
    279  | 
     | 
     | 
    	}  | 
    
    
    280  | 
     | 
     | 
     | 
    
    
    281  | 
     | 
     | 
    	/* adjust the top lines if necessary */  | 
    
    
    282  | 
     | 
     | 
    	curwp->w_linep = lp;  | 
    
    
    283  | 
     | 
     | 
    	wp->w_linep = lp;  | 
    
    
    284  | 
     | 
     | 
     | 
    
    
    285  | 
     | 
     | 
    	curwp->w_rflag |= WFMODE | WFFULL;  | 
    
    
    286  | 
     | 
     | 
    	wp->w_rflag |= WFMODE | WFFULL;  | 
    
    
    287  | 
     | 
     | 
    	/* if FFOTHARG, set flags) */  | 
    
    
    288  | 
     | 
     | 
    	if (f & FFOTHARG)  | 
    
    
    289  | 
     | 
     | 
    		wp->w_flag = n;  | 
    
    
    290  | 
     | 
     | 
     | 
    
    
    291  | 
     | 
     | 
    	return (TRUE);  | 
    
    
    292  | 
     | 
     | 
    }  | 
    
    
    293  | 
     | 
     | 
     | 
    
    
    294  | 
     | 
     | 
    /*  | 
    
    
    295  | 
     | 
     | 
     * Enlarge the current window.  Find the window that loses space.  Make sure  | 
    
    
    296  | 
     | 
     | 
     * it is big enough.  If so, hack the window descriptions, and ask redisplay  | 
    
    
    297  | 
     | 
     | 
     * to do all the hard work.  You don't just set "force reframe" because dot  | 
    
    
    298  | 
     | 
     | 
     * would move.  | 
    
    
    299  | 
     | 
     | 
     */  | 
    
    
    300  | 
     | 
     | 
    /* ARGSUSED */  | 
    
    
    301  | 
     | 
     | 
    int  | 
    
    
    302  | 
     | 
     | 
    enlargewind(int f, int n)  | 
    
    
    303  | 
     | 
     | 
    { | 
    
    
    304  | 
     | 
     | 
    	struct mgwin	*adjwp;  | 
    
    
    305  | 
     | 
     | 
    	struct line	*lp;  | 
    
    
    306  | 
     | 
     | 
    	int		 i;  | 
    
    
    307  | 
     | 
     | 
     | 
    
    
    308  | 
     | 
     | 
    	if (n < 0)  | 
    
    
    309  | 
     | 
     | 
    		return (shrinkwind(f, -n));  | 
    
    
    310  | 
     | 
     | 
    	if (wheadp->w_wndp == NULL) { | 
    
    
    311  | 
     | 
     | 
    		dobeep();  | 
    
    
    312  | 
     | 
     | 
    		ewprintf("Only one window"); | 
    
    
    313  | 
     | 
     | 
    		return (FALSE);  | 
    
    
    314  | 
     | 
     | 
    	}  | 
    
    
    315  | 
     | 
     | 
    	if ((adjwp = curwp->w_wndp) == NULL) { | 
    
    
    316  | 
     | 
     | 
    		adjwp = wheadp;  | 
    
    
    317  | 
     | 
     | 
    		while (adjwp->w_wndp != curwp)  | 
    
    
    318  | 
     | 
     | 
    			adjwp = adjwp->w_wndp;  | 
    
    
    319  | 
     | 
     | 
    	}  | 
    
    
    320  | 
     | 
     | 
    	if (adjwp->w_ntrows <= n) { | 
    
    
    321  | 
     | 
     | 
    		dobeep();  | 
    
    
    322  | 
     | 
     | 
    		ewprintf("Impossible change"); | 
    
    
    323  | 
     | 
     | 
    		return (FALSE);  | 
    
    
    324  | 
     | 
     | 
    	}  | 
    
    
    325  | 
     | 
     | 
     | 
    
    
    326  | 
     | 
     | 
    	/* shrink below */  | 
    
    
    327  | 
     | 
     | 
    	if (curwp->w_wndp == adjwp) { | 
    
    
    328  | 
     | 
     | 
    		lp = adjwp->w_linep;  | 
    
    
    329  | 
     | 
     | 
    		for (i = 0; i < n && lp != adjwp->w_bufp->b_headp; ++i)  | 
    
    
    330  | 
     | 
     | 
    			lp = lforw(lp);  | 
    
    
    331  | 
     | 
     | 
    		adjwp->w_linep = lp;  | 
    
    
    332  | 
     | 
     | 
    		adjwp->w_toprow += n;  | 
    
    
    333  | 
     | 
     | 
    	/* shrink above */  | 
    
    
    334  | 
     | 
     | 
    	} else { | 
    
    
    335  | 
     | 
     | 
    		lp = curwp->w_linep;  | 
    
    
    336  | 
     | 
     | 
    		for (i = 0; i < n && lback(lp) != curbp->b_headp; ++i)  | 
    
    
    337  | 
     | 
     | 
    			lp = lback(lp);  | 
    
    
    338  | 
     | 
     | 
    		curwp->w_linep = lp;  | 
    
    
    339  | 
     | 
     | 
    		curwp->w_toprow -= n;  | 
    
    
    340  | 
     | 
     | 
    	}  | 
    
    
    341  | 
     | 
     | 
    	curwp->w_ntrows += n;  | 
    
    
    342  | 
     | 
     | 
    	adjwp->w_ntrows -= n;  | 
    
    
    343  | 
     | 
     | 
    	curwp->w_rflag |= WFMODE | WFFULL;  | 
    
    
    344  | 
     | 
     | 
    	adjwp->w_rflag |= WFMODE | WFFULL;  | 
    
    
    345  | 
     | 
     | 
    	return (TRUE);  | 
    
    
    346  | 
     | 
     | 
    }  | 
    
    
    347  | 
     | 
     | 
     | 
    
    
    348  | 
     | 
     | 
    /*  | 
    
    
    349  | 
     | 
     | 
     * Shrink the current window.  Find the window that gains space.  Hack at the  | 
    
    
    350  | 
     | 
     | 
     * window descriptions. Ask the redisplay to do all the hard work.  | 
    
    
    351  | 
     | 
     | 
     */  | 
    
    
    352  | 
     | 
     | 
    int  | 
    
    
    353  | 
     | 
     | 
    shrinkwind(int f, int n)  | 
    
    
    354  | 
     | 
     | 
    { | 
    
    
    355  | 
     | 
     | 
    	struct mgwin	*adjwp;  | 
    
    
    356  | 
     | 
     | 
    	struct line	*lp;  | 
    
    
    357  | 
     | 
     | 
    	int		 i;  | 
    
    
    358  | 
     | 
     | 
     | 
    
    
    359  | 
     | 
     | 
    	if (n < 0)  | 
    
    
    360  | 
     | 
     | 
    		return (enlargewind(f, -n));  | 
    
    
    361  | 
     | 
     | 
    	if (wheadp->w_wndp == NULL) { | 
    
    
    362  | 
     | 
     | 
    		dobeep();  | 
    
    
    363  | 
     | 
     | 
    		ewprintf("Only one window"); | 
    
    
    364  | 
     | 
     | 
    		return (FALSE);  | 
    
    
    365  | 
     | 
     | 
    	}  | 
    
    
    366  | 
     | 
     | 
    	/*  | 
    
    
    367  | 
     | 
     | 
    	 * Bit of flakiness - FFRAND means it was an internal call, and  | 
    
    
    368  | 
     | 
     | 
    	 * to be trusted implicitly about sizes.  | 
    
    
    369  | 
     | 
     | 
    	 */  | 
    
    
    370  | 
     | 
     | 
    	if (!(f & FFRAND) && curwp->w_ntrows <= n) { | 
    
    
    371  | 
     | 
     | 
    		dobeep();  | 
    
    
    372  | 
     | 
     | 
    		ewprintf("Impossible change"); | 
    
    
    373  | 
     | 
     | 
    		return (FALSE);  | 
    
    
    374  | 
     | 
     | 
    	}  | 
    
    
    375  | 
     | 
     | 
    	if ((adjwp = curwp->w_wndp) == NULL) { | 
    
    
    376  | 
     | 
     | 
    		adjwp = wheadp;  | 
    
    
    377  | 
     | 
     | 
    		while (adjwp->w_wndp != curwp)  | 
    
    
    378  | 
     | 
     | 
    			adjwp = adjwp->w_wndp;  | 
    
    
    379  | 
     | 
     | 
    	}  | 
    
    
    380  | 
     | 
     | 
     | 
    
    
    381  | 
     | 
     | 
    	/* grow below */  | 
    
    
    382  | 
     | 
     | 
    	if (curwp->w_wndp == adjwp) { | 
    
    
    383  | 
     | 
     | 
    		lp = adjwp->w_linep;  | 
    
    
    384  | 
     | 
     | 
    		for (i = 0; i < n && lback(lp) != adjwp->w_bufp->b_headp; ++i)  | 
    
    
    385  | 
     | 
     | 
    			lp = lback(lp);  | 
    
    
    386  | 
     | 
     | 
    		adjwp->w_linep = lp;  | 
    
    
    387  | 
     | 
     | 
    		adjwp->w_toprow -= n;  | 
    
    
    388  | 
     | 
     | 
    	/* grow above */  | 
    
    
    389  | 
     | 
     | 
    	} else { | 
    
    
    390  | 
     | 
     | 
    		lp = curwp->w_linep;  | 
    
    
    391  | 
     | 
     | 
    		for (i = 0; i < n && lp != curbp->b_headp; ++i)  | 
    
    
    392  | 
     | 
     | 
    			lp = lforw(lp);  | 
    
    
    393  | 
     | 
     | 
    		curwp->w_linep = lp;  | 
    
    
    394  | 
     | 
     | 
    		curwp->w_toprow += n;  | 
    
    
    395  | 
     | 
     | 
    	}  | 
    
    
    396  | 
     | 
     | 
    	curwp->w_ntrows -= n;  | 
    
    
    397  | 
     | 
     | 
    	adjwp->w_ntrows += n;  | 
    
    
    398  | 
     | 
     | 
    	curwp->w_rflag |= WFMODE | WFFULL;  | 
    
    
    399  | 
     | 
     | 
    	adjwp->w_rflag |= WFMODE | WFFULL;  | 
    
    
    400  | 
     | 
     | 
    	return (TRUE);  | 
    
    
    401  | 
     | 
     | 
    }  | 
    
    
    402  | 
     | 
     | 
     | 
    
    
    403  | 
     | 
     | 
    /*  | 
    
    
    404  | 
     | 
     | 
     * Delete current window. Call shrink-window to do the screen updating, then  | 
    
    
    405  | 
     | 
     | 
     * throw away the window.  | 
    
    
    406  | 
     | 
     | 
     */  | 
    
    
    407  | 
     | 
     | 
    /* ARGSUSED */  | 
    
    
    408  | 
     | 
     | 
    int  | 
    
    
    409  | 
     | 
     | 
    delwind(int f, int n)  | 
    
    
    410  | 
     | 
     | 
    { | 
    
    
    411  | 
     | 
     | 
    	struct mgwin	*wp, *nwp;  | 
    
    
    412  | 
     | 
     | 
     | 
    
    
    413  | 
     | 
     | 
    	wp = curwp;		/* Cheap...		 */  | 
    
    
    414  | 
     | 
     | 
     | 
    
    
    415  | 
     | 
     | 
    	/* shrinkwind returning false means only one window... */  | 
    
    
    416  | 
     | 
     | 
    	if (shrinkwind(FFRAND, wp->w_ntrows + 1) == FALSE)  | 
    
    
    417  | 
     | 
     | 
    		return (FALSE);  | 
    
    
    418  | 
     | 
     | 
    	if (--wp->w_bufp->b_nwnd == 0) { | 
    
    
    419  | 
     | 
     | 
    		wp->w_bufp->b_dotp = wp->w_dotp;  | 
    
    
    420  | 
     | 
     | 
    		wp->w_bufp->b_doto = wp->w_doto;  | 
    
    
    421  | 
     | 
     | 
    		wp->w_bufp->b_markp = wp->w_markp;  | 
    
    
    422  | 
     | 
     | 
    		wp->w_bufp->b_marko = wp->w_marko;  | 
    
    
    423  | 
     | 
     | 
    		wp->w_bufp->b_dotline = wp->w_dotline;  | 
    
    
    424  | 
     | 
     | 
    		wp->w_bufp->b_markline = wp->w_markline;  | 
    
    
    425  | 
     | 
     | 
    	}  | 
    
    
    426  | 
     | 
     | 
     | 
    
    
    427  | 
     | 
     | 
    	/* since shrinkwind did't crap out, we know we have a second window */  | 
    
    
    428  | 
     | 
     | 
    	if (wp == wheadp)  | 
    
    
    429  | 
     | 
     | 
    		wheadp = curwp = wp->w_wndp;  | 
    
    
    430  | 
     | 
     | 
    	else if ((curwp = wp->w_wndp) == NULL)  | 
    
    
    431  | 
     | 
     | 
    		curwp = wheadp;  | 
    
    
    432  | 
     | 
     | 
    	curbp = curwp->w_bufp;  | 
    
    
    433  | 
     | 
     | 
    	for (nwp = wheadp; nwp != NULL; nwp = nwp->w_wndp)  | 
    
    
    434  | 
     | 
     | 
    		if (nwp->w_wndp == wp) { | 
    
    
    435  | 
     | 
     | 
    			nwp->w_wndp = wp->w_wndp;  | 
    
    
    436  | 
     | 
     | 
    			break;  | 
    
    
    437  | 
     | 
     | 
    		}  | 
    
    
    438  | 
     | 
     | 
    	free(wp);  | 
    
    
    439  | 
     | 
     | 
    	return (TRUE);  | 
    
    
    440  | 
     | 
     | 
    }  |