home *** CD-ROM | disk | FTP | other *** search
/ Carousel Volume 2 #1 / carousel.iso / mactosh / code / microema.sit / src / window.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-06-09  |  15.6 KB  |  717 lines  |  [TEXT/Earl]

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