version 1.3, 2000/04/13 06:12:18 |
version 1.4, 2000/09/01 14:59:09 |
|
|
/* |
/* |
* Window handling. |
* Window handling. |
*/ |
*/ |
#include "def.h" |
|
|
|
|
#include "def.h" |
|
|
/* |
/* |
* Reposition dot in the current |
* Reposition dot in the current window to line "n". If the argument is |
* window to line "n". If the argument is |
* positive, it is that line. If it is negative it is that line from the |
* positive, it is that line. If it is negative it |
* bottom. If it is 0 the window is centered (this is what the standard |
* is that line from the bottom. If it is 0 the window |
* redisplay code does). If GOSREC is undefined, default is 0, so it acts |
* is centered (this is what the standard redisplay code |
* like GNU. If GOSREC is defined, with no argument it defaults to 1 and |
* does). If GOSREC is undefined, default is 0, so it acts like GNU. |
* works like in Gosling. |
* If GOSREC is defined, with no argument it defaults to 1 |
|
* and works like in Gosling. |
|
*/ |
*/ |
/* ARGSUSED */ |
/* ARGSUSED */ |
|
int |
reposition(f, n) |
reposition(f, n) |
|
int f, n; |
{ |
{ |
#ifndef GOSREC |
#ifndef GOSREC |
curwp->w_force = (f & FFARG) ? (n >= 0 ? n + 1 : n) : 0; |
curwp->w_force = (f & FFARG) ? (n >= 0 ? n + 1 : n) : 0; |
#else |
#else /* !GOSREC */ |
curwp->w_force = n; |
curwp->w_force = n; |
#endif |
#endif /* !GOSREC */ |
curwp->w_flag |= WFFORCE; |
curwp->w_flag |= WFFORCE; |
sgarbf = TRUE; |
sgarbf = TRUE; |
return TRUE; |
return TRUE; |
} |
} |
|
|
/* |
/* |
* Refresh the display. A call is made to the |
* Refresh the display. A call is made to the "ttresize" entry in the |
* "ttresize" entry in the terminal handler, which tries |
* terminal handler, which tries to reset "nrow" and "ncol". They will, |
* to reset "nrow" and "ncol". They will, however, never |
* however, never be set outside of the NROW or NCOL range. If the display |
* be set outside of the NROW or NCOL range. If the display |
* changed size, arrange that everything is redone, then call "update" to |
* changed size, arrange that everything is redone, then |
* fix the display. We do this so the new size can be displayed. In the |
* call "update" to fix the display. We do this so the |
* normal case the call to "update" in "main.c" refreshes the screen, and |
* new size can be displayed. In the normal case the |
* all of the windows need not be recomputed. Note that when you get to the |
* call to "update" in "main.c" refreshes the screen, |
* "display unusable" message, the screen will be messed up. If you make the |
* and all of the windows need not be recomputed. |
* window bigger again, and send another command, everything will get fixed! |
* Note that when you get to the "display unusable" |
|
* message, the screen will be messed up. If you make |
|
* the window bigger again, and send another command, |
|
* everything will get fixed! |
|
*/ |
*/ |
/* ARGSUSED */ |
/* ARGSUSED */ |
|
int |
refresh(f, n) |
refresh(f, n) |
|
int f, n; |
{ |
{ |
register MGWIN *wp; |
MGWIN *wp; |
register int oldnrow; |
int oldnrow; |
register int oldncol; |
int oldncol; |
|
|
oldnrow = nrow; |
oldnrow = nrow; |
oldncol = ncol; |
oldncol = ncol; |
ttresize(); |
ttresize(); |
if (nrow != oldnrow || ncol != oldncol) { |
if (nrow != oldnrow || ncol != oldncol) { |
wp = wheadp; /* Find last. */ |
|
|
/* find last */ |
|
wp = wheadp; |
while (wp->w_wndp != NULL) |
while (wp->w_wndp != NULL) |
wp = wp->w_wndp; |
wp = wp->w_wndp; |
if (nrow < wp->w_toprow + 3) { /* Check if too small. */ |
|
|
/* check if too small */ |
|
if (nrow < wp->w_toprow + 3) { |
ewprintf("Display unusable"); |
ewprintf("Display unusable"); |
return (FALSE); |
return (FALSE); |
} |
} |
|
|
} |
} |
|
|
/* |
/* |
* The command to make the next |
* The command to make the next window (next => down the screen) the current |
* window (next => down the screen) |
* window. There are no real errors, although the command does nothing if |
* the current window. There are no real |
* there is only 1 window on the screen. |
* errors, although the command does |
|
* nothing if there is only 1 window on |
|
* the screen. |
|
*/ |
*/ |
/* ARGSUSED */ |
/* ARGSUSED */ |
|
int |
nextwind(f, n) |
nextwind(f, n) |
|
int f, n; |
{ |
{ |
register MGWIN *wp; |
MGWIN *wp; |
|
|
if ((wp = curwp->w_wndp) == NULL) |
if ((wp = curwp->w_wndp) == NULL) |
wp = wheadp; |
wp = wheadp; |
|
|
} |
} |
|
|
#ifdef GOSMACS |
#ifdef GOSMACS |
|
|
/* not in Gnu Emacs */ |
/* not in Gnu Emacs */ |
/* |
/* |
* This command makes the previous |
* This command makes the previous window (previous => up the screen) the |
* window (previous => up the screen) the |
* current window. There are no errors, although the command does not do |
* current window. There arn't any errors, |
* a lot if there is only 1 window. |
* although the command does not do a lot |
|
* if there is 1 window. |
|
*/ |
*/ |
/* ARGSUSED */ |
/* ARGSUSED */ |
|
int |
prevwind(f, n) |
prevwind(f, n) |
|
int f, n; |
{ |
{ |
register MGWIN *wp1; |
MGWIN *wp1, *wp2; |
register MGWIN *wp2; |
|
|
|
wp1 = wheadp; |
wp1 = wheadp; |
wp2 = curwp; |
wp2 = curwp; |
|
|
curbp = wp1->w_bufp; |
curbp = wp1->w_bufp; |
return TRUE; |
return TRUE; |
} |
} |
#endif |
#endif /* GOSEMACS */ |
|
|
/* |
/* |
* This command makes the current |
* This command makes the current window the only window on the screen. Try |
* window the only window on the screen. |
* to set the framing so that "." does not have to move on the display. Some |
* Try to set the framing |
* care has to be taken to keep the values of dot and mark in the buffer |
* so that "." does not have to move on |
* structures right if the distruction of a window makes a buffer become |
* the display. Some care has to be taken |
* undisplayed. |
* to keep the values of dot and mark |
|
* in the buffer structures right if the |
|
* distruction of a window makes a buffer |
|
* become undisplayed. |
|
*/ |
*/ |
/* ARGSUSED */ |
/* ARGSUSED */ |
|
int |
onlywind(f, n) |
onlywind(f, n) |
|
int f, n; |
{ |
{ |
register MGWIN *wp; |
MGWIN *wp; |
register LINE *lp; |
LINE *lp; |
register int i; |
int i; |
|
|
while (wheadp != curwp) { |
while (wheadp != curwp) { |
wp = wheadp; |
wp = wheadp; |
|
|
wp->w_bufp->b_markp = wp->w_markp; |
wp->w_bufp->b_markp = wp->w_markp; |
wp->w_bufp->b_marko = wp->w_marko; |
wp->w_bufp->b_marko = wp->w_marko; |
} |
} |
free((char *) wp); |
free((char *)wp); |
} |
} |
while (curwp->w_wndp != NULL) { |
while (curwp->w_wndp != NULL) { |
wp = curwp->w_wndp; |
wp = curwp->w_wndp; |
|
|
wp->w_bufp->b_markp = wp->w_markp; |
wp->w_bufp->b_markp = wp->w_markp; |
wp->w_bufp->b_marko = wp->w_marko; |
wp->w_bufp->b_marko = wp->w_marko; |
} |
} |
free((char *) wp); |
free((char *)wp); |
} |
} |
lp = curwp->w_linep; |
lp = curwp->w_linep; |
i = curwp->w_toprow; |
i = curwp->w_toprow; |
|
|
lp = lback(lp); |
lp = lback(lp); |
} |
} |
curwp->w_toprow = 0; |
curwp->w_toprow = 0; |
curwp->w_ntrows = nrow - 2; /* 2 = mode, echo. */ |
|
|
/* 2 = mode, echo */ |
|
curwp->w_ntrows = nrow - 2; |
curwp->w_linep = lp; |
curwp->w_linep = lp; |
curwp->w_flag |= WFMODE | WFHARD; |
curwp->w_flag |= WFMODE | WFHARD; |
return TRUE; |
return TRUE; |
} |
} |
|
|
/* |
/* |
* Split the current window. A window |
* Split the current window. A window smaller than 3 lines cannot be split. |
* smaller than 3 lines cannot be split. |
* The only other error that is possible is a "malloc" failure allocating the |
* The only other error that is possible is |
* structure for the new window. |
* a "malloc" failure allocating the structure |
|
* for the new window. |
|
*/ |
*/ |
/* ARGSUSED */ |
/* ARGSUSED */ |
|
int |
splitwind(f, n) |
splitwind(f, n) |
|
int f, n; |
{ |
{ |
register MGWIN *wp; |
MGWIN *wp, *wp1, *wp2; |
register LINE *lp; |
LINE *lp; |
register int ntru; |
int ntru, ntrd, ntrl; |
register int ntrd; |
|
int ntrl; |
|
MGWIN *wp1, *wp2; |
|
|
|
if (curwp->w_ntrows < 3) { |
if (curwp->w_ntrows < 3) { |
ewprintf("Cannot split a %d line window", curwp->w_ntrows); |
ewprintf("Cannot split a %d line window", curwp->w_ntrows); |
return (FALSE); |
return (FALSE); |
} |
} |
if ((wp = (MGWIN *) malloc(sizeof(MGWIN))) == NULL) { |
if ((wp = (MGWIN *)malloc(sizeof(MGWIN))) == NULL) { |
ewprintf("Can't get %d", sizeof(MGWIN)); |
ewprintf("Can't get %d", sizeof(MGWIN)); |
return (FALSE); |
return (FALSE); |
} |
} |
++curbp->b_nwnd; /* Displayed twice. */ |
|
|
/* displayed twice */ |
|
++curbp->b_nwnd; |
wp->w_bufp = curbp; |
wp->w_bufp = curbp; |
wp->w_dotp = curwp->w_dotp; |
wp->w_dotp = curwp->w_dotp; |
wp->w_doto = curwp->w_doto; |
wp->w_doto = curwp->w_doto; |
|
|
lp = lforw(lp); |
lp = lforw(lp); |
} |
} |
lp = curwp->w_linep; |
lp = curwp->w_linep; |
if (ntrd <= ntru) { /* Old is upper window. */ |
|
if (ntrd == ntru) /* Hit mode line. */ |
/* old is upper window */ |
|
if (ntrd <= ntru) { |
|
/* hit mode line */ |
|
if (ntrd == ntru) |
lp = lforw(lp); |
lp = lforw(lp); |
curwp->w_ntrows = ntru; |
curwp->w_ntrows = ntru; |
wp->w_wndp = curwp->w_wndp; |
wp->w_wndp = curwp->w_wndp; |
curwp->w_wndp = wp; |
curwp->w_wndp = wp; |
wp->w_toprow = curwp->w_toprow + ntru + 1; |
wp->w_toprow = curwp->w_toprow + ntru + 1; |
wp->w_ntrows = ntrl; |
wp->w_ntrows = ntrl; |
} else { /* Old is lower window */ |
/* old is lower window */ |
|
} else { |
wp1 = NULL; |
wp1 = NULL; |
wp2 = wheadp; |
wp2 = wheadp; |
while (wp2 != curwp) { |
while (wp2 != curwp) { |
|
|
wp->w_wndp = curwp; |
wp->w_wndp = curwp; |
wp->w_toprow = curwp->w_toprow; |
wp->w_toprow = curwp->w_toprow; |
wp->w_ntrows = ntru; |
wp->w_ntrows = ntru; |
++ntru; /* Mode line. */ |
|
|
/* mode line */ |
|
++ntru; |
curwp->w_toprow += ntru; |
curwp->w_toprow += ntru; |
curwp->w_ntrows = ntrl; |
curwp->w_ntrows = ntrl; |
while (ntru--) |
while (ntru--) |
lp = lforw(lp); |
lp = lforw(lp); |
} |
} |
curwp->w_linep = lp; /* Adjust the top lines */ |
|
wp->w_linep = lp; /* if necessary. */ |
/* adjust the top lines if necessary */ |
|
curwp->w_linep = lp; |
|
wp->w_linep = lp; |
|
|
curwp->w_flag |= WFMODE | WFHARD; |
curwp->w_flag |= WFMODE | WFHARD; |
wp->w_flag |= WFMODE | WFHARD; |
wp->w_flag |= WFMODE | WFHARD; |
return TRUE; |
return TRUE; |
} |
} |
|
|
/* |
/* |
* Enlarge the current window. |
* Enlarge the current window. Find the window that loses space. Make sure |
* Find the window that loses space. Make |
* it is big enough. If so, hack the window descriptions, and ask redisplay |
* sure it is big enough. If so, hack the window |
* to do all the hard work. You don't just set "force reframe" because dot |
* descriptions, and ask redisplay to do all the |
* would move. |
* hard work. You don't just set "force reframe" |
|
* because dot would move. |
|
*/ |
*/ |
/* ARGSUSED */ |
/* ARGSUSED */ |
|
int |
enlargewind(f, n) |
enlargewind(f, n) |
|
int f, n; |
{ |
{ |
register MGWIN *adjwp; |
MGWIN *adjwp; |
register LINE *lp; |
LINE *lp; |
register int i; |
int i; |
|
|
if (n < 0) |
if (n < 0) |
return shrinkwind(f, -n); |
return shrinkwind(f, -n); |
|
|
ewprintf("Impossible change"); |
ewprintf("Impossible change"); |
return FALSE; |
return FALSE; |
} |
} |
if (curwp->w_wndp == adjwp) { /* Shrink below. */ |
|
|
/* shrink below */ |
|
if (curwp->w_wndp == adjwp) { |
lp = adjwp->w_linep; |
lp = adjwp->w_linep; |
for (i = 0; i < n && lp != adjwp->w_bufp->b_linep; ++i) |
for (i = 0; i < n && lp != adjwp->w_bufp->b_linep; ++i) |
lp = lforw(lp); |
lp = lforw(lp); |
adjwp->w_linep = lp; |
adjwp->w_linep = lp; |
adjwp->w_toprow += n; |
adjwp->w_toprow += n; |
} else { /* Shrink above. */ |
/* shrink above */ |
|
} else { |
lp = curwp->w_linep; |
lp = curwp->w_linep; |
for (i = 0; i < n && lback(lp) != curbp->b_linep; ++i) |
for (i = 0; i < n && lback(lp) != curbp->b_linep; ++i) |
lp = lback(lp); |
lp = lback(lp); |
|
|
} |
} |
|
|
/* |
/* |
* Shrink the current window. |
* Shrink the current window. Find the window that gains space. Hack at the |
* Find the window that gains space. Hack at |
* window descriptions. Ask the redisplay to do all the hard work. |
* the window descriptions. Ask the redisplay to |
|
* do all the hard work. |
|
*/ |
*/ |
|
int |
shrinkwind(f, n) |
shrinkwind(f, n) |
|
int f, n; |
{ |
{ |
register MGWIN *adjwp; |
MGWIN *adjwp; |
register LINE *lp; |
LINE *lp; |
register int i; |
int i; |
|
|
if (n < 0) |
if (n < 0) |
return enlargewind(f, -n); |
return enlargewind(f, -n); |
|
|
while (adjwp->w_wndp != curwp) |
while (adjwp->w_wndp != curwp) |
adjwp = adjwp->w_wndp; |
adjwp = adjwp->w_wndp; |
} |
} |
if (curwp->w_wndp == adjwp) { /* Grow below. */ |
|
|
/* grow below */ |
|
if (curwp->w_wndp == adjwp) { |
lp = adjwp->w_linep; |
lp = adjwp->w_linep; |
for (i = 0; i < n && lback(lp) != adjwp->w_bufp->b_linep; ++i) |
for (i = 0; i < n && lback(lp) != adjwp->w_bufp->b_linep; ++i) |
lp = lback(lp); |
lp = lback(lp); |
adjwp->w_linep = lp; |
adjwp->w_linep = lp; |
adjwp->w_toprow -= n; |
adjwp->w_toprow -= n; |
} else { /* Grow above. */ |
/* grow above */ |
|
} else { |
lp = curwp->w_linep; |
lp = curwp->w_linep; |
for (i = 0; i < n && lp != curbp->b_linep; ++i) |
for (i = 0; i < n && lp != curbp->b_linep; ++i) |
lp = lforw(lp); |
lp = lforw(lp); |
|
|
} |
} |
|
|
/* |
/* |
* Delete current window. Call shrink-window to do the screen |
* Delete current window. Call shrink-window to do the screen updating, then |
* updating, then throw away the window. |
* throw away the window. |
*/ |
*/ |
/* ARGSUSED */ |
/* ARGSUSED */ |
|
int |
delwind(f, n) |
delwind(f, n) |
|
int f, n; |
{ |
{ |
register MGWIN *wp, *nwp; |
MGWIN *wp, *nwp; |
|
|
wp = curwp; /* Cheap... */ |
wp = curwp; /* Cheap... */ |
|
|
/* shrinkwind returning false means only one window... */ |
/* shrinkwind returning false means only one window... */ |
if (shrinkwind(FFRAND, wp->w_ntrows + 1) == FALSE) |
if (shrinkwind(FFRAND, wp->w_ntrows + 1) == FALSE) |
return FALSE; |
return FALSE; |
|
|
wp->w_bufp->b_markp = wp->w_markp; |
wp->w_bufp->b_markp = wp->w_markp; |
wp->w_bufp->b_marko = wp->w_marko; |
wp->w_bufp->b_marko = wp->w_marko; |
} |
} |
|
|
/* since shrinkwind did't crap out, we know we have a second window */ |
/* since shrinkwind did't crap out, we know we have a second window */ |
if (wp == wheadp) |
if (wp == wheadp) |
wheadp = curwp = wp->w_wndp; |
wheadp = curwp = wp->w_wndp; |
|
|
nwp->w_wndp = wp->w_wndp; |
nwp->w_wndp = wp->w_wndp; |
break; |
break; |
} |
} |
free((char *) wp); |
free((char *)wp); |
return TRUE; |
return TRUE; |
} |
} |
|
|
/* |
/* |
* Pick a window for a pop-up. |
* Pick a window for a pop-up. Split the screen if there is only one window. |
* Split the screen if there is only |
* Pick the uppermost window that isn't the current window. An LRU algorithm |
* one window. Pick the uppermost window that |
* might be better. Return a pointer, or NULL on error. |
* isn't the current window. An LRU algorithm |
|
* might be better. Return a pointer, or |
|
* NULL on error. |
|
*/ |
*/ |
MGWIN * |
MGWIN * |
wpopup() |
wpopup() |
{ |
{ |
register MGWIN *wp; |
MGWIN *wp; |
|
|
if (wheadp->w_wndp == NULL |
if (wheadp->w_wndp == NULL |
&& splitwind(FFRAND, 0) == FALSE) |
&& splitwind(FFRAND, 0) == FALSE) |
return NULL; |
return NULL; |
wp = wheadp; /* Find window to use */ |
|
|
/* find a window to use */ |
|
wp = wheadp; |
|
|
while (wp != NULL && wp == curwp) |
while (wp != NULL && wp == curwp) |
wp = wp->w_wndp; |
wp = wp->w_wndp; |
return wp; |
return wp; |