home *** CD-ROM | disk | FTP | other *** search
/ Black Box 4 / BlackBox.cdr / progc / ce331src.arj / WINDOW.C < prev    next >
C/C++ Source or Header  |  1991-03-10  |  18KB  |  799 lines

  1. /*
  2.  *    W I N D O W . C
  3.  *
  4.  *    purpose:
  5.  *        Window management. Some of the functions are internal, and some are
  6.  *        attached to keys that the user actually types.
  7.  */
  8.  
  9. #include <stdio.h>            /* Turbo C++ verison 1.0 */
  10. #include <stdlib.h>
  11. #include <dos.h>
  12.  
  13. #include <pdefs.h>            /* PforCe version 1.05 (includes jwg.h) */
  14. #include <pf_ansi.h>
  15.  
  16. #include "struct.h"
  17. #include "def.h"
  18. #include "protos.h"
  19.  
  20. /**
  21.  * Reposition dot in the current window to line "n". If the argument is
  22.  * positive, it is that line. If it is negative it is that line from the
  23.  * bottom. If it is 0 the window is centered (this is what the standard
  24.  * redisplay code does). With no argument it defaults to 0.
  25.  */
  26. int Reposition(f, n)
  27.   int    f, n;
  28. {
  29.     if (f == FALSE)     /* default to 0 to center screen */
  30.         n = 0;
  31.     curwp->w_force = (char)n;
  32.     curwp->w_flag |= WFFORCE;
  33.     return(TRUE);
  34. }
  35.  
  36. /**
  37.  * Refresh the screen. With no argument, it just does the Refresh. With an
  38.  * argument it recenters dot in the current window.
  39.  */
  40. int Refresh(f, n)
  41.   int    f, n;
  42. {
  43.     if (f == FALSE)
  44.         sgarbf = TRUE;
  45.     else
  46.     {
  47.         curwp->w_force = 0;             /* center dot */
  48.         curwp->w_flag |= WFFORCE;
  49.     }
  50.     return(TRUE);
  51. }
  52.  
  53. /**
  54.  * This command make the next window the current window. There are no real
  55.  * errors, although the command does nothing if there is only 1 window on
  56.  * the screen. With an argument this command finds the <n>th window from
  57.  * the top.
  58.  */
  59. int NextWind(f, n)
  60.   int        f;
  61.   int        n;
  62. {
  63.   WINDOW    *wp;
  64.   int        nwindows;    /* total number of windows */
  65.  
  66.     if (f)
  67.     {
  68.         /* first count the # of windows */
  69.         wp = wheadp;
  70.         nwindows = 1;
  71.         while (wp->w_wndp != NULLWPTR)
  72.         {
  73.             nwindows++;
  74.             wp = wp->w_wndp;
  75.         }
  76.  
  77.         /* if argument is negative, it is nth window from bottom of screen */
  78.         if (n < 0)
  79.             n += nwindows + 1;
  80.  
  81.         /* if an argument, give them that window from the top */
  82.         if (n > 0 && n <= nwindows)
  83.         {
  84.             wp = wheadp;
  85.             while (--n)
  86.                 wp = wp->w_wndp;
  87.         }
  88.         else
  89.         {
  90.             MlWrite("Window number out of range");
  91.             return(FALSE);
  92.         }
  93.     }
  94.     else
  95.         if ((wp = curwp->w_wndp) == NULLWPTR)
  96.             wp = wheadp;
  97.     curwp = wp;
  98.     curbp = wp->w_bufp;
  99.     UpMode();
  100.     return(TRUE);
  101. }
  102.  
  103. /**
  104.  * This command makes the previous window (previous => up the screen) the
  105.  * current window. There arn't any errors, although the command does not do
  106.  * a lot if there is only one window.
  107.  */
  108. int PrevWind(f, n)
  109.   int        f, n;
  110. {
  111.   WINDOW    *wp1;
  112.   WINDOW    *wp2;
  113.  
  114.     /* if we have an argument, we mean the nth window from the bottom */
  115.     if (f)
  116.         return(NextWind(f, -n));
  117.  
  118.     wp1 = wheadp;
  119.     wp2 = curwp;
  120.  
  121.     if (wp1 == wp2)
  122.         wp2 = NULLWPTR;
  123.  
  124.     while (wp1->w_wndp != wp2)
  125.         wp1 = wp1->w_wndp;
  126.  
  127.     curwp = wp1;
  128.     curbp = wp1->w_bufp;
  129.     UpMode();
  130.     return(TRUE);
  131. }
  132.  
  133. /**
  134.  * This command moves the current window down by "arg" lines. Recompute the
  135.  * top line in the window. The move up and move down code is almost completely
  136.  * the same; most of the work has to do with reframing the window, and picking
  137.  * a new dot. We share the code by having "move down" just be an interface to
  138.  * "move up". Magic.
  139.  */
  140. int MoveWindDn(f, n)
  141.   int    f, n;
  142. {
  143.     return(MoveWindUp(f, -n));
  144. }
  145.  
  146. /**
  147.  * Move the current window up by "arg" lines. Recompute the new top line of
  148.  * the window. Look to see if dot is still on the screen. If it is, you win.
  149.  * If it isn't, then move dot to center it in the new framing of the window
  150.  * (this command does not really move dot; it moves the frame).
  151.  */
  152. int MoveWindUp(f, n)
  153.   int    f;
  154.   int    n;
  155. {
  156.   LINE    *lp;
  157.   int    i;
  158.  
  159.     lp = curwp->w_linep;
  160.  
  161.     if (n < 0)
  162.     {
  163.         while (n++ && lp != curbp->b_linep)
  164.             lp = lforw(lp);
  165.     }
  166.     else
  167.     {
  168.         while (n-- && lback(lp) != curbp->b_linep)
  169.             lp = lback(lp);
  170.     }
  171.  
  172.     curwp->w_linep = lp;
  173.     curwp->w_flag |= WFHARD;            /* mode line is OK */
  174.  
  175.     for (i = 0; i < curwp->w_ntrows; ++i)
  176.     {
  177.         if (lp == curwp->w_dotp)
  178.             return(TRUE);
  179.         if (lp == curbp->b_linep)
  180.             break;
  181.         lp = lforw(lp);
  182.     }
  183.  
  184.     lp = curwp->w_linep;
  185.     i = curwp->w_ntrows / 2;
  186.  
  187.     while (i-- && lp != curbp->b_linep)
  188.         lp = lforw(lp);
  189.  
  190.     curwp->w_dotp = lp;
  191.     curwp->w_doto = 0;
  192.     return(TRUE);
  193. }
  194.  
  195. /**
  196.  * This command makes the current window the only window on the screen.
  197.  * Try to set the framing so that dot does not have to move on the display.
  198.  * Some care has to be taken to keep the values of dot and mark in the buffer
  199.  * structures right if the destruction of a window makes a buffer become
  200.  * undisplayed.
  201.  */
  202. int OnlyWind(f, n)
  203.   int        f, n;
  204. {
  205.   WINDOW    *wp;
  206.   LINE        *lp;
  207. #if BMARKS
  208.   int        bmark;
  209. #endif
  210.   int        i;
  211.  
  212.     while (wheadp != curwp)
  213.     {
  214.         wp = wheadp;
  215.         wheadp = wp->w_wndp;
  216.         if (--wp->w_bufp->b_nwnd == 0)
  217.         {
  218.             wp->w_bufp->b_dotp = wp->w_dotp;
  219.             wp->w_bufp->b_doto = wp->w_doto;
  220.             wp->w_bufp->b_markp = wp->w_markp;
  221.             wp->w_bufp->b_marko = wp->w_marko;
  222.             wp->w_bufp->b_anchorp = wp->w_anchorp;
  223.             wp->w_bufp->b_anchoro = wp->w_anchoro;
  224.             wp->w_bufp->b_fcol = wp->w_fcol;
  225. #if BMARKS
  226.             for (bmark = 0; bmark < NBMARKS; bmark++)
  227.             {
  228.                 wp->w_bufp->b_bmarkp[bmark] = wp->w_bmarkp[bmark];
  229.                 wp->w_bufp->b_bmarko[bmark] = wp->w_bmarko[bmark];
  230.             }
  231. #endif
  232.         }
  233.         free((char *)wp);
  234.     }
  235.     while (curwp->w_wndp != NULLWPTR)
  236.     {
  237.         wp = curwp->w_wndp;
  238.         curwp->w_wndp = wp->w_wndp;
  239.         if (--wp->w_bufp->b_nwnd == 0)
  240.         {
  241.             wp->w_bufp->b_dotp = wp->w_dotp;
  242.             wp->w_bufp->b_doto = wp->w_doto;
  243.             wp->w_bufp->b_markp = wp->w_markp;
  244.             wp->w_bufp->b_marko = wp->w_marko;
  245.             wp->w_bufp->b_anchorp = wp->w_anchorp;
  246.             wp->w_bufp->b_anchoro = wp->w_anchoro;
  247.             wp->w_bufp->b_fcol = wp->w_fcol;
  248. #if BMARKS
  249.             for (bmark = 0; bmark < NBMARKS; bmark++)
  250.             {
  251.                 wp->w_bufp->b_bmarkp[bmark] = wp->w_bmarkp[bmark];
  252.                 wp->w_bufp->b_bmarko[bmark] = wp->w_bmarko[bmark];
  253.             }
  254. #endif
  255.         }
  256.         free((char *)wp);
  257.     }
  258.     lp = curwp->w_linep;
  259.     i = curwp->w_toprow;
  260.     while (i != 0 && lback(lp) != curbp->b_linep)
  261.     {
  262.         --i;
  263.         lp = lback(lp);
  264.     }
  265.     curwp->w_toprow = 0;
  266.     curwp->w_ntrows = (char)term.t_nrow - 1;
  267.     curwp->w_linep = lp;
  268.     curwp->w_flag |= WFMODE | WFHARD;
  269.     return(TRUE);
  270. }
  271.  
  272. /**
  273.  * Delete the current window, placing its space in the window above,
  274.  * or, if it is the top window, the window below.
  275.  */
  276. int DelWind(f, n)
  277.   int        f, n;
  278. {
  279.   WINDOW    *wp;         /* window to recieve deleted space */
  280.   WINDOW    *lwp;        /* ptr window before curwp */
  281.   int        target;     /* target line to search for */
  282. #if BMARKS
  283.   int        bmark;
  284. #endif
  285.  
  286.     /* if there is only one window, don't delete it */
  287.     if (wheadp->w_wndp == NULLWPTR)
  288.     {
  289.         MlWrite("Can't delete the only window");
  290.         return(FALSE);
  291.     }
  292.  
  293.     /* find window before curwp in linked list */
  294.     wp = wheadp;
  295.     lwp = NULLWPTR;
  296.     while (wp != NULLWPTR)
  297.     {
  298.         if (wp == curwp)
  299.             break;
  300.         lwp = wp;
  301.         wp = wp->w_wndp;
  302.     }
  303.  
  304.     /* find receiving window and give up our space */
  305.     wp = wheadp;
  306.     if (curwp->w_toprow == 0)
  307.     {
  308.         /* find the next window down */
  309.         target = curwp->w_ntrows + 1;
  310.         while (wp != NULLWPTR)
  311.         {
  312.             if (wp->w_toprow == (char)target)
  313.                 break;
  314.             wp = wp->w_wndp;
  315.         }
  316.         if (wp == NULLWPTR)
  317.             return(FALSE);
  318.         wp->w_toprow = 0;
  319.         wp->w_ntrows += (char)target;
  320.     }
  321.     else
  322.     {
  323.         /* find the next window up */
  324.         target = curwp->w_toprow - 1;
  325.         while (wp != NULLWPTR)
  326.         {
  327.             if ((wp->w_toprow + wp->w_ntrows) == (char)target)
  328.                 break;
  329.             wp = wp->w_wndp;
  330.         }
  331.         if (wp == NULLWPTR)
  332.             return(FALSE);
  333.         wp->w_ntrows += curwp->w_ntrows + 1;
  334.     }
  335.  
  336.     /* get rid of the current window */
  337.     if (--curwp->w_bufp->b_nwnd == 0)
  338.     {
  339.         curwp->w_bufp->b_dotp = curwp->w_dotp;
  340.         curwp->w_bufp->b_doto = curwp->w_doto;
  341.         curwp->w_bufp->b_markp = curwp->w_markp;
  342.         curwp->w_bufp->b_marko = curwp->w_marko;
  343.         curwp->w_bufp->b_anchorp = curwp->w_anchorp;
  344.         curwp->w_bufp->b_anchoro = curwp->w_anchoro;
  345.         curwp->w_bufp->b_fcol = curwp->w_fcol;
  346. #if BMARKS
  347.         for (bmark = 0; bmark < NBMARKS; bmark++)
  348.         {
  349.             curwp->w_bufp->b_bmarkp[bmark] = curwp->w_bmarkp[bmark];
  350.             curwp->w_bufp->b_bmarko[bmark] = curwp->w_bmarko[bmark];
  351.         }
  352. #endif
  353.     }
  354.     if (lwp == NULLWPTR)
  355.         wheadp = curwp->w_wndp;
  356.     else
  357.         lwp->w_wndp = curwp->w_wndp;
  358.     free((char *)curwp);
  359.     curwp = wp;
  360.     wp->w_flag |= WFHARD;
  361.     curbp = wp->w_bufp;
  362.     UpMode();
  363.     return(TRUE);
  364. }
  365.  
  366. /**
  367.  * Split the current window.  A window smaller than 3 lines cannot be split.
  368.  * An argument of 1 forces the cursor into the upper window, an argument of
  369.  * two forces the cursor to the lower window.  The only other error that is
  370.  * possible is a "malloc" failure allocating the structure for the new window.
  371.  */
  372. int SplitWind(f, n)
  373.   int        f, n;
  374. {
  375.   WINDOW    *wp;
  376.   LINE        *lp;
  377.   int        ntru;
  378.   int        ntrl;
  379.   int        ntrd;
  380.   WINDOW    *wp1;
  381.   WINDOW    *wp2;
  382. #if BMARKS
  383.   int        bmark;
  384. #endif
  385.   char        buf[NSTRING];
  386.  
  387.     if (curwp->w_ntrows < 3)
  388.     {
  389.         strfmt(buf, "Can't split a %d line window", curwp->w_ntrows);
  390.         MlWrite(buf);
  391.         return(FALSE);
  392.     }
  393.     if ((wp = (WINDOW *)malloc(sizeof(WINDOW))) == NULLWPTR)
  394.     {
  395.         OutOfMem();
  396.         return(FALSE);
  397.     }
  398.     ++curbp->b_nwnd;                        /* displayed twice */
  399.     wp->w_bufp = curbp;
  400.     wp->w_dotp = curwp->w_dotp;
  401.     wp->w_doto = curwp->w_doto;
  402.     wp->w_markp = curwp->w_markp;
  403.     wp->w_marko = curwp->w_marko;
  404.     wp->w_anchorp = curwp->w_anchorp;
  405.     wp->w_anchoro = curwp->w_anchoro;
  406.     wp->w_fcol = curwp->w_fcol;
  407. #if BMARKS
  408.     for (bmark = 0; bmark < NBMARKS; bmark++)
  409.     {
  410.         wp->w_bmarkp[bmark] = curwp->w_bmarkp[bmark];
  411.         wp->w_bmarko[bmark] = curwp->w_bmarko[bmark];
  412.     }
  413. #endif
  414.     wp->w_flag = 0;
  415.     wp->w_force = 0;
  416.     /* set the colors of the new window */
  417.     wp->w_fcolor = (char)gfcolor;
  418.     wp->w_bcolor = (char)gbcolor;
  419.     ntru = (curwp->w_ntrows-1) / 2;         /* upper size */
  420.     ntrl = (curwp->w_ntrows-1) - ntru;        /* lower size */
  421.     lp = curwp->w_linep;
  422.     ntrd = 0;
  423.     while (lp != curwp->w_dotp)
  424.     {
  425.         ++ntrd;
  426.         lp = lforw(lp);
  427.     }
  428.     lp = curwp->w_linep;
  429.     if (((f == FALSE) && (ntrd <= ntru)) || ((f == TRUE) && (n == 1)))
  430.     {
  431.         /* old is upper window */
  432.         if (ntrd == ntru)                    /* hit mode line */
  433.             lp = lforw(lp);
  434.         curwp->w_ntrows = (char)ntru;
  435.         wp->w_wndp = curwp->w_wndp;
  436.         curwp->w_wndp = wp;
  437.         wp->w_toprow = curwp->w_toprow + ntru + 1;
  438.         wp->w_ntrows = (char)ntrl;
  439.     }
  440.     else
  441.     {                                        /* old is lower window */
  442.         wp1 = NULLWPTR;
  443.         wp2 = wheadp;
  444.         while (wp2 != curwp)
  445.         {
  446.             wp1 = wp2;
  447.             wp2 = wp2->w_wndp;
  448.         }
  449.         if (wp1 == NULLWPTR)
  450.             wheadp = wp;
  451.         else
  452.             wp1->w_wndp = wp;
  453.         wp->w_wndp = curwp;
  454.         wp->w_toprow = curwp->w_toprow;
  455.         wp->w_ntrows = (char)ntru;
  456.         ++ntru;                             /* mode line */
  457.         curwp->w_toprow += (char)ntru;
  458.         curwp->w_ntrows = (char)ntrl;
  459.         while (ntru--)
  460.         lp = lforw(lp);
  461.     }
  462.     curwp->w_linep = lp;                    /* adjust the top lines */
  463.     wp->w_linep = lp;                        /*     if necessary */
  464.     curwp->w_flag |= WFMODE | WFHARD;
  465.     wp->w_flag |= WFMODE | WFHARD;
  466.     return(TRUE);
  467. }
  468.  
  469. /**
  470.  * Enlarge the current window. Find the window that loses space. Make sure it
  471.  * is big enough. If so, hack the window descriptions, and ask redisplay to do
  472.  * all the hard work. You don't just set "force reframe" because dot would
  473.  * move.
  474.  */
  475. int EnlargeWind(f, n)
  476.   int        f, n;
  477. {
  478.   WINDOW    *adjwp;
  479.   LINE        *lp;
  480.   int        i;
  481.  
  482.     if (n < 0)
  483.         return(ShrinkWind(f, -n));
  484.     if (wheadp->w_wndp == NULLWPTR)
  485.     {
  486.         MlWrite("Only one window");
  487.         return(FALSE);
  488.     }
  489.     if ((adjwp = curwp->w_wndp) == NULLWPTR)
  490.     {
  491.         adjwp = wheadp;
  492.         while (adjwp->w_wndp != curwp)
  493.             adjwp = adjwp->w_wndp;
  494.     }
  495.     if (adjwp->w_ntrows <= (char)n)
  496.     {
  497.         MlWrite("Impossible change");
  498.         return(FALSE);
  499.     }
  500.     if (curwp->w_wndp == adjwp)             /* shrink below */
  501.     {
  502.         lp = adjwp->w_linep;
  503.         for (i = 0; i < n && lp != adjwp->w_bufp->b_linep; ++i)
  504.             lp = lforw(lp);
  505.         adjwp->w_linep = lp;
  506.         adjwp->w_toprow += (char)n;
  507.     }
  508.     else
  509.     {                                        /* shrink above */
  510.         lp = curwp->w_linep;
  511.         for (i = 0; i < n && lback(lp) != curbp->b_linep; ++i)
  512.             lp = lback(lp);
  513.         curwp->w_linep = lp;
  514.         curwp->w_toprow -= (char)n;
  515.     }
  516.     curwp->w_ntrows += (char)n;
  517.     adjwp->w_ntrows -= (char)n;
  518.     curwp->w_flag |= WFMODE | WFHARD;
  519.     adjwp->w_flag |= WFMODE | WFHARD;
  520.     return(TRUE);
  521. }
  522.  
  523. /**
  524.  * Shrink the current window. Find the window that gains space. Hack at the
  525.  * window descriptions. Ask the redisplay to do all the hard work.
  526.  */
  527. int ShrinkWind(f, n)
  528.   int        f, n;
  529. {
  530.   WINDOW    *adjwp;
  531.   LINE        *lp;
  532.   int        i;
  533.  
  534.     if (n < 0)
  535.         return(EnlargeWind(f, -n));
  536.     if (wheadp->w_wndp == NULLWPTR)
  537.     {
  538.         MlWrite("Only one window");
  539.         return(FALSE);
  540.     }
  541.     if ((adjwp = curwp->w_wndp) == NULLWPTR)
  542.     {
  543.         adjwp = wheadp;
  544.         while (adjwp->w_wndp != curwp)
  545.             adjwp = adjwp->w_wndp;
  546.     }
  547.     if (curwp->w_ntrows <= (char)n)
  548.     {
  549.         MlWrite("Impossible change");
  550.         return(FALSE);
  551.     }
  552.     if (curwp->w_wndp == adjwp)             /* grow below */
  553.     {
  554.         lp = adjwp->w_linep;
  555.         for (i = 0; i < n && lback(lp) != adjwp->w_bufp->b_linep; ++i)
  556.             lp = lback(lp);
  557.         adjwp->w_linep = lp;
  558.         adjwp->w_toprow -= (char)n;
  559.     }
  560.     else
  561.     {                                        /* grow above */
  562.         lp = curwp->w_linep;
  563.         for (i = 0; i < n && lp != curbp->b_linep; ++i)
  564.             lp = lforw(lp);
  565.         curwp->w_linep    = lp;
  566.         curwp->w_toprow += (char)n;
  567.     }
  568.     curwp->w_ntrows -= (char)n;
  569.     adjwp->w_ntrows += (char)n;
  570.     curwp->w_flag |= WFMODE | WFHARD;
  571.     adjwp->w_flag |= WFMODE | WFHARD;
  572.     return(TRUE);
  573. }
  574.  
  575. /**
  576.  * Resize the current window to the requested size
  577.  */
  578. int Resize(f, n)
  579.   int    f, n;
  580. {
  581.   int    clines;     /* current # of lines in window */
  582.         
  583.     /* must have a non-default argument, else ignore call */
  584.     if (f == FALSE)
  585.         return(TRUE);
  586.  
  587.     /* find out what to do */
  588.     clines = curwp->w_ntrows;
  589.  
  590.     /* already the right size? */
  591.     if (clines == n)
  592.         return(TRUE);
  593.  
  594.     return(EnlargeWind(TRUE, n - clines));
  595. }
  596.  
  597. /**
  598.  * Pick a window for a pop-up. Split the screen if there is only one window.
  599.  * Pick the uppermost window that isn't the current window. An LRU algorithm
  600.  * might be better. Return a pointer, or NULL on error.
  601.  */
  602. WINDOW * WindPopUp()
  603. {
  604.   WINDOW    *wp;
  605.  
  606.     if    (
  607.                 wheadp->w_wndp == NULLWPTR        /* only 1 window */
  608.             &&
  609.                 SplitWind(FALSE, 0) == FALSE    /* and it won't split */
  610.         )
  611.         return(NULLWPTR);
  612.     wp = wheadp;                                /* find window to use */
  613.     while (wp != NULLWPTR && wp == curwp)
  614.         wp = wp->w_wndp;
  615.     return(wp);
  616. }
  617.  
  618. /**
  619.  * Scroll the next window up (back) a page
  620.  */
  621. int NextWindUp(f, n)
  622.   int    f, n;
  623. {
  624.     NextWind(FALSE, 1);
  625.     BackPage(f, n);
  626.     PrevWind(FALSE, 1);
  627.     return(TRUE);
  628. }
  629.  
  630. /**
  631.  * Scroll the next window down (forward) a page
  632.  */
  633. int NextWindDn(f, n)
  634.   int    f, n;
  635. {
  636.     NextWind(FALSE, 1);
  637.     ForwPage(f, n);
  638.     PrevWind(FALSE, 1);
  639.     return(TRUE);
  640. }
  641.  
  642. /**
  643.  * Save ptr to current window
  644.  */
  645. int SaveWind()
  646. {
  647.     swindow = curwp;
  648.     return(TRUE);
  649. }
  650.  
  651. /**
  652.  * Restore the saved screen
  653.  */
  654. int RestWind()
  655. {
  656.   WINDOW    *wp;
  657.  
  658.     /* find the window */
  659.     wp = wheadp;
  660.     while (wp != NULLWPTR)
  661.     {
  662.         if (wp == swindow)
  663.         {
  664.             curwp = wp;
  665.             curbp = wp->w_bufp;
  666.             UpMode();
  667.             return(TRUE);
  668.         }
  669.         wp = wp->w_wndp;
  670.     }
  671.  
  672.     MlWrite("No such window");
  673.     return(FALSE);
  674. }
  675.  
  676. /**
  677.  * Resize the screen, re-writing the screen
  678.  */
  679. int NewSize(f, n)
  680.   int        f;
  681.   int        n;
  682. {
  683.   WINDOW    *wp;         /* current window being examined */
  684.   WINDOW    *nextwp;     /* next window to scan */
  685.   WINDOW    *lastwp;     /* last window scanned */
  686.   int        lastline;    /* screen line of last line of current window */
  687. #if BMARKS
  688.   int        bmark;
  689. #endif
  690.  
  691.     /* if the command defaults, assume the largest */
  692.     if (f == FALSE)
  693.         n = term.t_mrow + 1;
  694.  
  695.     /* make sure it's in range */
  696.     if (n < 3 || n > term.t_mrow + 1)
  697.     {
  698.         MlWrite("Screen size out of range");
  699.         return(FALSE);
  700.     }
  701.  
  702.     if (term.t_nrow == n - 1)
  703.         return(TRUE);
  704.     else if (term.t_nrow < n - 1)
  705.     {
  706.         /* go to the last window */
  707.         wp = wheadp;
  708.         while (wp->w_wndp != NULLWPTR)
  709.             wp = wp->w_wndp;
  710.  
  711.         /* and enlarge it as needed */
  712.         wp->w_ntrows = (char)n - wp->w_toprow - 2;
  713.         wp->w_flag |= WFHARD | WFMODE;
  714.  
  715.     }
  716.     else
  717.     {
  718.         /* rebuild the window structure */
  719.         nextwp = wheadp;
  720.         wp = NULLWPTR;
  721.         lastwp = NULLWPTR;
  722.         while (nextwp != NULLWPTR)
  723.         {
  724.             wp = nextwp;
  725.             nextwp = wp->w_wndp;
  726.         
  727.             /* get rid of it if it is too low */
  728.             if (wp->w_toprow > (char)n - 2)
  729.             {
  730.                 /* save the point/mark if needed */
  731.                 if (--wp->w_bufp->b_nwnd == 0)
  732.                 {
  733.                     wp->w_bufp->b_dotp = wp->w_dotp;
  734.                     wp->w_bufp->b_doto = wp->w_doto;
  735.                     wp->w_bufp->b_markp = wp->w_markp;
  736.                     wp->w_bufp->b_marko = wp->w_marko;
  737.                     wp->w_bufp->b_anchorp = wp->w_anchorp;
  738.                     wp->w_bufp->b_anchoro = wp->w_anchoro;
  739.                     wp->w_bufp->b_fcol = wp->w_fcol;
  740. #if BMARKS
  741.                     for (bmark = 0; bmark < NBMARKS; bmark++)
  742.                     {
  743.                         wp->w_bufp->b_bmarkp[bmark] = wp->w_bmarkp[bmark];
  744.                         wp->w_bufp->b_bmarko[bmark] = wp->w_bmarko[bmark];
  745.                     }
  746. #endif
  747.                 }
  748.         
  749.                 /* Update curwp and lastwp if needed */
  750.                 if (wp == curwp)
  751.                     curwp = wheadp;
  752.                 curbp = curwp->w_bufp;
  753.                 if (lastwp != NULLWPTR)
  754.                     lastwp->w_wndp = NULLWPTR;
  755.  
  756.                 /* free the structure */
  757.                 free((char *)wp);
  758.                 wp = NULLWPTR;
  759.  
  760.             }
  761.             else
  762.             {
  763.                 lastline = wp->w_toprow + wp->w_ntrows - 1;
  764.                 if (lastline >= n - 2)
  765.                 {
  766.                     wp->w_ntrows = (char)n - wp->w_toprow - 2;
  767.                     wp->w_flag |= WFHARD | WFMODE;
  768.                 }
  769.             }
  770.             lastwp = wp;
  771.         }
  772.     }
  773.     /* screen is garbage */
  774.     term.t_nrow = n - 1;
  775.     sgarbf = TRUE;
  776.     return(TRUE);
  777. }
  778.  
  779. /**
  780.  * Get screen offset of current line in current window
  781.  */
  782. int GetWindPos()
  783. {
  784.   int    sline;    /* screen line from top of window */
  785.   LINE    *lp;     /* scannile line pointer */
  786.  
  787.     /* search down the line we want */
  788.     lp = curwp->w_linep;
  789.     sline = 1;
  790.     while (lp != curwp->w_dotp)
  791.     {
  792.         ++sline;
  793.         lp = lforw(lp);
  794.     }
  795.  
  796.     /* and return the value */
  797.     return(sline);
  798. }
  799.