home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / CMDS / memacs400_src.lzh / MEMACS400 / SRC / window.c < prev    next >
Text File  |  1996-04-25  |  21KB  |  918 lines

  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    "eproto.h"
  9. #include    "edef.h"
  10. #include    "elang.h"
  11.  
  12. /*
  13.  * Reposition dot in the current window to line "n". If the argument is
  14.  * positive, it is that line. If it is negative it is that line from the
  15.  * bottom. If it is 0 the window is centered (this is what the standard
  16.  * redisplay code does). With no argument it defaults to 0. Bound to M-!.
  17.  */
  18. PASCAL NEAR reposition(f, n)
  19.  
  20. int f, n;    /* prefix flag and argument */
  21.  
  22. {
  23.     if (f == FALSE)    /* default to 0 to center screen */
  24.     n = 0;
  25.     curwp->w_force = n;
  26.     curwp->w_flag |= WFFORCE;
  27.     return(TRUE);
  28.     }
  29.  
  30. /*
  31.  * Refresh the screen. With no argument, it just does the refresh. With an
  32.  * argument it recenters "." in the current window. Bound to "C-L".
  33.  */
  34. PASCAL NEAR refresh(f, n)
  35.  
  36. int f, n;    /* prefix flag and argument */
  37.  
  38. {
  39.     if (f == FALSE)
  40.     sgarbf = TRUE;
  41.     else {
  42.     curwp->w_force = 0;        /* Center dot. */
  43.     curwp->w_flag |= WFFORCE;
  44.     }
  45.  
  46.     return(TRUE);
  47. }
  48.  
  49. /*
  50.  * The command make the next window (next => down the screen) the current
  51.  * window. There are no real errors, although the command does nothing if
  52.  * there is only 1 window on the screen. Bound to "C-X C-N".
  53.  *
  54.  * with an argument this command finds the <n>th window from the top
  55.  *
  56.  */
  57. PASCAL NEAR nextwind(f, n)
  58.  
  59. int f, n;    /* default flag and numeric argument */
  60.  
  61. {
  62.     register EWINDOW *wp;
  63.     register int nwindows;        /* total number of windows */
  64.  
  65.     if (f) {
  66.  
  67.         /* first count the # of windows */
  68.         wp = wheadp;
  69.         nwindows = 1;
  70.         while (wp->w_wndp != NULL) {
  71.             nwindows++;
  72.             wp = wp->w_wndp;
  73.         }
  74.  
  75.         /* if the argument is negative, it is the nth window
  76.            from the bottom of the screen            */
  77.         if (n < 0)
  78.             n = nwindows + n + 1;
  79.  
  80.         /* if an argument, give them that window from the top */
  81.         if (n > 0 && n <= nwindows) {
  82.             wp = wheadp;
  83.             while (--n)
  84.                 wp = wp->w_wndp;
  85.         } else {
  86.             mlwrite(TEXT203);
  87. /*                "Window number out of range" */
  88.             return(FALSE);
  89.         }
  90.     } else
  91.         if ((wp = curwp->w_wndp) == NULL)
  92.             wp = wheadp;
  93.     curwp = wp;
  94.     curbp = wp->w_bufp;
  95.     upmode();
  96.     return(TRUE);
  97. }
  98.  
  99. /*
  100.  * This command makes the previous window (previous => up the screen) the
  101.  * current window. There arn't any errors, although the command does not do a
  102.  * lot if there is 1 window.
  103.  */
  104. PASCAL NEAR prevwind(f, n)
  105.  
  106. int f,n;    /* prefix flag and argument */
  107.  
  108. {
  109.     register EWINDOW *wp1;
  110.     register EWINDOW *wp2;
  111.  
  112.     /* if we have an argument, we mean the nth window from the bottom */
  113.     if (f)
  114.         return(nextwind(f, -n));
  115.  
  116.     wp1 = wheadp;
  117.     wp2 = curwp;
  118.  
  119.     if (wp1 == wp2)
  120.         wp2 = NULL;
  121.  
  122.     while (wp1->w_wndp != wp2)
  123.         wp1 = wp1->w_wndp;
  124.  
  125.     curwp = wp1;
  126.     curbp = wp1->w_bufp;
  127.     upmode();
  128.     return(TRUE);
  129. }
  130.  
  131. /*
  132.  * This command moves the current window down by "arg" lines. Recompute the
  133.  * top line in the window. The move up and move down code is almost completely
  134.  * the same; most of the work has to do with reframing the window, and picking
  135.  * a new dot. We share the code by having "move down" just be an interface to
  136.  * "move up". Magic. Bound to "C-X C-N".
  137.  */
  138. PASCAL NEAR mvdnwind(f, n)
  139.  
  140. int f, n;    /* prefix flag and argument */
  141.  
  142. {
  143.     return(mvupwind(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 "." is still on the screen. If it is, you win.
  149.  * If it isn't, then move "." to center it in the new framing of the window
  150.  * (this command does not really move "."; it moves the frame). Bound to
  151.  * "C-X C-P".
  152.  */
  153. PASCAL NEAR mvupwind(f, n)
  154.  
  155. int f, n;    /* prefix flag and argument */
  156.  
  157. {
  158.     register LINE *lp;
  159.     register int i;
  160.  
  161.     lp = curwp->w_linep;
  162.  
  163.     if (n < 0) {
  164.     while (n++ && lp!=curbp->b_linep)
  165.         lp = lforw(lp);
  166.     } else {
  167.     while (n-- && lback(lp)!=curbp->b_linep)
  168.         lp = lback(lp);
  169.     }
  170.  
  171.     curwp->w_linep = lp;
  172.     curwp->w_flag |= WFHARD;        /* Mode line is OK. */
  173.  
  174.     for (i = 0; i < curwp->w_ntrows; ++i) {
  175.     if (lp == curwp->w_dotp)
  176.         return(TRUE);
  177.     if (lp == curbp->b_linep)
  178.         break;
  179.     lp = lforw(lp);
  180.     }
  181.  
  182.     lp = curwp->w_linep;
  183.     i  = curwp->w_ntrows/2;
  184.  
  185.     while (i-- && lp != curbp->b_linep)
  186.     lp = lforw(lp);
  187.  
  188.     curwp->w_dotp  = lp;
  189.     curwp->w_doto  = 0;
  190.     return(TRUE);
  191. }
  192.  
  193. /*
  194.  * This command makes the current window the only window on the screen. Bound
  195.  * to "C-X 1". Try to set the framing so that "." does not have to move on the
  196.  * display. Some care has to be taken to keep the values of dot and mark in
  197.  * the buffer structures right if the distruction of a window makes a buffer
  198.  * become undisplayed.
  199.  */
  200. PASCAL NEAR onlywind(f, n)
  201.  
  202. int f,n;    /* prefix flag and argument */
  203.  
  204. {
  205.     register EWINDOW *wp;
  206.     register LINE    *lp;
  207.     register int    i;
  208.     int cmark;        /* current mark */
  209.  
  210.     while (wheadp != curwp) {
  211.         wp = wheadp;
  212.         first_screen->s_first_window = wheadp = wp->w_wndp;
  213.         if (--wp->w_bufp->b_nwnd == 0) {
  214.             wp->w_bufp->b_dotp  = wp->w_dotp;
  215.             wp->w_bufp->b_doto  = wp->w_doto;
  216.             for (cmark = 0; cmark < NMARKS; cmark++) {
  217.                 wp->w_bufp->b_markp[cmark] = wp->w_markp[cmark];
  218.                 wp->w_bufp->b_marko[cmark] = wp->w_marko[cmark];
  219.             }
  220.             wp->w_bufp->b_fcol  = wp->w_fcol;
  221.         }
  222.         free((char *) wp);
  223.     }
  224.     while (curwp->w_wndp != NULL) {
  225.         wp = curwp->w_wndp;
  226.         curwp->w_wndp = wp->w_wndp;
  227.         if (--wp->w_bufp->b_nwnd == 0) {
  228.             wp->w_bufp->b_dotp  = wp->w_dotp;
  229.             wp->w_bufp->b_doto  = wp->w_doto;
  230.             for (cmark = 0; cmark < NMARKS; cmark++) {
  231.                 wp->w_bufp->b_markp[cmark] = wp->w_markp[cmark];
  232.                 wp->w_bufp->b_marko[cmark] = wp->w_marko[cmark];
  233.             }
  234.             wp->w_bufp->b_fcol  = wp->w_fcol;
  235.         }
  236.         free((char *) wp);
  237.     }
  238.     lp = curwp->w_linep;
  239.     i  = curwp->w_toprow;
  240.     while (i!=0 && lback(lp)!=curbp->b_linep) {
  241.         --i;
  242.         lp = lback(lp);
  243.     }
  244.     curwp->w_toprow = 0;
  245.     curwp->w_ntrows = term.t_nrow-1;
  246.     curwp->w_linep    = lp;
  247.     curwp->w_flag  |= WFMODE|WFHARD;
  248.     return(TRUE);
  249. }
  250.  
  251. /*
  252.  * Delete the current window, placing its space in the window above,
  253.  * or, if it is the top window, the window below. Bound to C-X 0.
  254.  */
  255.  
  256. PASCAL NEAR delwind(f,n)
  257.  
  258. int f, n;    /* arguments are ignored for this command */
  259.  
  260. {
  261.     register EWINDOW *wp;    /* window to recieve deleted space */
  262.     register EWINDOW *lwp;    /* ptr window before curwp */
  263.     register int target;    /* target line to search for */
  264.     int cmark;        /* current mark */
  265.  
  266.     /* if there is only one window, don't delete it */
  267.     if (wheadp->w_wndp == NULL) {
  268.         mlwrite(TEXT204);
  269. /*            "Can not delete this window" */
  270.         return(FALSE);
  271.     }
  272.  
  273.     /* find window before curwp in linked list */
  274.     wp = wheadp;
  275.     lwp = NULL;
  276.     while (wp != NULL) {
  277.         if (wp == curwp)
  278.             break;
  279.         lwp = wp;
  280.         wp = wp->w_wndp;
  281.     }
  282.  
  283.     /* find recieving window and give up our space */
  284.     wp = wheadp;
  285.     if (curwp->w_toprow == 0) {
  286.         /* find the next window down */
  287.         target = curwp->w_ntrows + 1;
  288.         while (wp != NULL) {
  289.             if (wp->w_toprow == target)
  290.                 break;
  291.             wp = wp->w_wndp;
  292.         }
  293.         if (wp == NULL)
  294.             return(FALSE);
  295.         wp->w_toprow = 0;
  296.         wp->w_ntrows += target;
  297.     } else {
  298.         /* find the next window up */
  299.         target = curwp->w_toprow - 1;
  300.         while (wp != NULL) {
  301.             if ((wp->w_toprow + wp->w_ntrows) == target)
  302.                 break;
  303.             wp = wp->w_wndp;
  304.         }
  305.         if (wp == NULL)
  306.             return(FALSE);
  307.         wp->w_ntrows += 1 + curwp->w_ntrows;
  308.     }
  309.  
  310.     /* get rid of the current window */
  311.     if (--curwp->w_bufp->b_nwnd == 0) {
  312.         curwp->w_bufp->b_dotp  = curwp->w_dotp;
  313.         curwp->w_bufp->b_doto  = curwp->w_doto;
  314.         for (cmark = 0; cmark < NMARKS; cmark++) {
  315.             curwp->w_bufp->b_markp[cmark] = curwp->w_markp[cmark];
  316.             curwp->w_bufp->b_marko[cmark] = curwp->w_marko[cmark];
  317.         }
  318.         curwp->w_bufp->b_fcol  = curwp->w_fcol;
  319.     }
  320.     if (lwp == NULL)
  321.         first_screen->s_first_window = wheadp = curwp->w_wndp;
  322.     else
  323.         lwp->w_wndp = curwp->w_wndp;
  324.     free((char *)curwp);
  325.     curwp = wp;
  326.     wp->w_flag |= WFHARD;
  327.     curbp = wp->w_bufp;
  328.     upmode();
  329.     return(TRUE);
  330. }
  331.  
  332. /*
  333.  
  334. Split the current window.  A window smaller than 3 lines cannot be
  335. split.    (Two line windows can be split when mode lines are disabled) An
  336. argument of 1 forces the cursor into the upper window, an argument of
  337. two forces the cursor to the lower window.  The only other error that
  338. is possible is a "room" failure allocating the structure for the new
  339. window.  Bound to "C-X 2". 
  340.  
  341. */
  342.  
  343. PASCAL NEAR splitwind(f, n)
  344.  
  345. int f, n;    /* default flag and numeric argument */
  346.  
  347. {
  348.     register EWINDOW *wp;
  349.     register LINE    *lp;
  350.     register int    ntru;
  351.     register int    ntrl;
  352.     register int    ntrd;
  353.     register EWINDOW *wp1;
  354.     register EWINDOW *wp2;
  355.     int cmark;        /* current mark */
  356.  
  357.     /* make sure we have enough space */
  358.     if (curwp->w_ntrows < (modeflag ? 3 : 2)) {
  359.         mlwrite(TEXT205, curwp->w_ntrows);
  360. /*            "Cannot split a %d line window" */
  361.         return(FALSE);
  362.     }
  363.     if ((wp = (EWINDOW *)room(sizeof(EWINDOW))) == NULL) {
  364.         mlabort(TEXT94);
  365. /*            "%%Out of memory" */
  366.         return(FALSE);
  367.     }
  368.     ++curbp->b_nwnd;            /* Displayed twice.    */
  369.     wp->w_bufp  = curbp;
  370.     wp->w_dotp  = curwp->w_dotp;
  371.     wp->w_doto  = curwp->w_doto;
  372.     for (cmark = 0; cmark < NMARKS; cmark++) {
  373.         wp->w_markp[cmark] = curwp->w_markp[cmark];
  374.         wp->w_marko[cmark] = curwp->w_marko[cmark];
  375.     }
  376.     wp->w_fcol  = curwp->w_fcol;
  377.     wp->w_flag  = 0;
  378.     wp->w_force = 0;
  379. #if    COLOR
  380.     /* set the colors of the new window */
  381.     wp->w_fcolor = gfcolor;
  382.     wp->w_bcolor = gbcolor;
  383. #endif
  384.     ntru = (curwp->w_ntrows-1) / 2;     /* Upper size        */
  385.     ntrl = (curwp->w_ntrows-1) - ntru;    /* Lower size        */
  386.     lp = curwp->w_linep;
  387.     ntrd = 0;
  388.     while (lp != curwp->w_dotp) {
  389.         ++ntrd;
  390.         lp = lforw(lp);
  391.     }
  392.     lp = curwp->w_linep;
  393.     if (((f == FALSE) && (ntrd <= ntru)) || ((f == TRUE) && (n == 1))) {
  394.         /* Old is upper window. */
  395.         if (ntrd == ntru)        /* Hit mode line.    */
  396.             lp = lforw(lp);
  397.         curwp->w_ntrows = ntru;
  398.         wp->w_wndp = curwp->w_wndp;
  399.         curwp->w_wndp = wp;
  400.         wp->w_toprow = curwp->w_toprow+ntru+1;
  401.         wp->w_ntrows = ntrl;
  402.     } else {                /* Old is lower window    */
  403.         wp1 = NULL;
  404.         wp2 = wheadp;
  405.         while (wp2 != curwp) {
  406.             wp1 = wp2;
  407.             wp2 = wp2->w_wndp;
  408.         }
  409.         if (wp1 == NULL)
  410.             first_screen->s_first_window = wheadp = wp;
  411.         else
  412.             wp1->w_wndp = wp;
  413.         wp->w_wndp   = curwp;
  414.         wp->w_toprow = curwp->w_toprow;
  415.         wp->w_ntrows = ntru;
  416.         ++ntru;             /* Mode line.        */
  417.         curwp->w_toprow += ntru;
  418.         curwp->w_ntrows  = ntrl;
  419.         while (ntru--)
  420.             lp = lforw(lp);
  421.     }
  422.     curwp->w_linep = lp;            /* Adjust the top lines */
  423.     wp->w_linep = lp;            /* if necessary.    */
  424.     curwp->w_flag |= WFMODE|WFHARD;
  425.     wp->w_flag |= WFMODE|WFHARD;
  426.     return(TRUE);
  427. }
  428.  
  429. /*
  430.  * Enlarge the current window. Find the window that loses space. Make sure it
  431.  * is big enough. If so, hack the window descriptions, and ask redisplay to do
  432.  * all the hard work. You don't just set "force reframe" because dot would
  433.  * move. Bound to "C-X Z".
  434.  */
  435. PASCAL NEAR enlargewind(f, n)
  436.  
  437. int f,n;    /* prefix flag and argument */
  438.  
  439. {
  440.     register EWINDOW *adjwp;
  441.     register LINE    *lp;
  442.     register int    i;
  443.  
  444.     if (n < 0)
  445.         return(shrinkwind(f, -n));
  446.     if (wheadp->w_wndp == NULL) {
  447.         mlwrite(TEXT206);
  448. /*            "Only one window" */
  449.         return(FALSE);
  450.     }
  451.     if ((adjwp=curwp->w_wndp) == NULL) {
  452.         adjwp = wheadp;
  453.         while (adjwp->w_wndp != curwp)
  454.             adjwp = adjwp->w_wndp;
  455.     }
  456.     if ((adjwp->w_ntrows + (modeflag ? 0 : 1)) <= n) {
  457.         mlwrite(TEXT207);
  458. /*            "Impossible change" */
  459.         return(FALSE);
  460.     }
  461.     if (curwp->w_wndp == adjwp) {        /* Shrink below.    */
  462.         lp = adjwp->w_linep;
  463.         for (i=0; i<n && lp!=adjwp->w_bufp->b_linep; ++i)
  464.             lp = lforw(lp);
  465.         adjwp->w_linep    = lp;
  466.         adjwp->w_toprow += n;
  467.     } else {                /* Shrink above.    */
  468.         lp = curwp->w_linep;
  469.         for (i=0; i<n && lback(lp)!=curbp->b_linep; ++i)
  470.             lp = lback(lp);
  471.         curwp->w_linep    = lp;
  472.         curwp->w_toprow -= n;
  473.     }
  474.     curwp->w_ntrows += n;
  475.     adjwp->w_ntrows -= n;
  476.     curwp->w_flag |= WFMODE|WFHARD;
  477.     adjwp->w_flag |= WFMODE|WFHARD;
  478.     return(TRUE);
  479. }
  480.  
  481. /*
  482.  * Shrink the current window. Find the window that gains space. Hack at the
  483.  * window descriptions. Ask the redisplay to do all the hard work. Bound to
  484.  * "C-X C-Z".
  485.  */
  486. PASCAL NEAR shrinkwind(f, n)
  487.  
  488. int f,n;    /* prefix flag and argument */
  489.  
  490. {
  491.     register EWINDOW *adjwp;
  492.     register LINE    *lp;
  493.     register int    i;
  494.  
  495.     if (n < 0)
  496.         return(enlargewind(f, -n));
  497.     if (wheadp->w_wndp == NULL) {
  498.         mlwrite(TEXT206);
  499. /*            "Only one window" */
  500.         return(FALSE);
  501.     }
  502.     if ((adjwp=curwp->w_wndp) == NULL) {
  503.         adjwp = wheadp;
  504.         while (adjwp->w_wndp != curwp)
  505.             adjwp = adjwp->w_wndp;
  506.     }
  507.     if ((curwp->w_ntrows + (modeflag ? 0 : 1)) <= n) {
  508.         mlwrite(TEXT207);
  509. /*            "Impossible change" */
  510.         return(FALSE);
  511.     }
  512.     if (curwp->w_wndp == adjwp) {        /* Grow below.        */
  513.         lp = adjwp->w_linep;
  514.         for (i=0; i<n && lback(lp)!=adjwp->w_bufp->b_linep; ++i)
  515.             lp = lback(lp);
  516.         adjwp->w_linep    = lp;
  517.         adjwp->w_toprow -= n;
  518.     } else {                /* Grow above.        */
  519.         lp = curwp->w_linep;
  520.         for (i=0; i<n && lp!=curbp->b_linep; ++i)
  521.             lp = lforw(lp);
  522.         curwp->w_linep    = lp;
  523.         curwp->w_toprow += n;
  524.     }
  525.     curwp->w_ntrows -= n;
  526.     adjwp->w_ntrows += n;
  527.     curwp->w_flag |= WFMODE|WFHARD;
  528.     adjwp->w_flag |= WFMODE|WFHARD;
  529.     return(TRUE);
  530. }
  531.  
  532. /*    Resize the current window to the requested size */
  533.  
  534. PASCAL NEAR resize(f, n)
  535.  
  536. int f, n;    /* default flag and numeric argument */
  537.  
  538. {
  539.     int clines;    /* current # of lines in window */
  540.         
  541.     /* must have a non-default argument, else ignore call */
  542.     if (f == FALSE)
  543.         return(TRUE);
  544.  
  545.     /* find out what to do */
  546.     clines = curwp->w_ntrows;
  547.  
  548.     /* already the right size? */
  549.     if (clines == n)
  550.         return(TRUE);
  551.  
  552.     return(enlargewind(TRUE, n - clines));
  553. }
  554.  
  555. /*    pop up the indicated buffer
  556. */
  557.  
  558. #if    PROTO
  559. int PASCAL NEAR wpopup(BUFFER *popbuf)
  560. #else
  561. int PASCAL NEAR wpopup(popbuf)
  562.  
  563. BUFFER *popbuf;
  564. #endif
  565. {
  566.     register EWINDOW *wp;
  567.     register BUFFER *bp;
  568.     register int cmark;        /* current mark */
  569.  
  570.     /* on screen already? */
  571.     if (popbuf->b_nwnd != 0)
  572.         goto setwin;
  573.  
  574.     /* if flaged so, do a real pop up */
  575.     if (popflag)
  576.         return(pop(popbuf));
  577.  
  578.     /* find the window to split */
  579.     if (wheadp->w_wndp == NULL        /* Only 1 window    */
  580.     && splitwind(FALSE, 0) == FALSE)    /* and it won't split    */
  581.         return(FALSE);
  582.     wp = wheadp;                /* Find window to use    */
  583.     while (wp!=NULL && wp == curwp)
  584.         wp = wp->w_wndp;
  585.  
  586.     if (popbuf->b_nwnd == 0) {        /* Not on screen yet.    */
  587.         bp = wp->w_bufp;
  588.         if (--bp->b_nwnd == 0) {
  589.             bp->b_dotp  = wp->w_dotp;
  590.             bp->b_doto  = wp->w_doto;
  591.             for (cmark = 0; cmark < NMARKS; cmark++) {
  592.                 bp->b_markp[cmark] = wp->w_markp[cmark];
  593.                 bp->b_marko[cmark] = wp->w_marko[cmark];
  594.             }
  595.             bp->b_fcol  = wp->w_fcol;
  596.         }
  597.         wp->w_bufp  = popbuf;
  598.         ++popbuf->b_nwnd;
  599.     }
  600.  
  601. setwin: wp = wheadp;
  602.     while (wp != NULL) {
  603.         if (wp->w_bufp == popbuf) {
  604.             wp->w_linep = lforw(popbuf->b_linep);
  605.             wp->w_dotp  = lforw(popbuf->b_linep);
  606.             wp->w_doto  = 0;
  607.             for (cmark = 0; cmark < NMARKS; cmark++) {
  608.                 wp->w_markp[cmark] = NULL;
  609.                 wp->w_marko[cmark] = 0;
  610.             }
  611.             wp->w_flag |= WFMODE|WFHARD;
  612.             popbuf->b_mode |= MDVIEW; /* put this buffer view mode */
  613.             upmode();
  614.         }
  615.         wp = wp->w_wndp;
  616.     }
  617.     return(TRUE);
  618. }
  619.  
  620. PASCAL NEAR nextup(f, n)    /* scroll the next window up (back) a page */
  621.  
  622. int f, n;    /* prefix flag and argument */
  623.  
  624. {
  625.     nextwind(FALSE, 1);
  626.     backpage(f, n);
  627.     prevwind(FALSE, 1);
  628. }
  629.  
  630. PASCAL NEAR nextdown(f, n)    /* scroll the next window down (forward) a page */
  631.  
  632. int f, n;    /* prefix flag and argument */
  633.  
  634. {
  635.     nextwind(FALSE, 1);
  636.     forwpage(f, n);
  637.     prevwind(FALSE, 1);
  638. }
  639.  
  640. PASCAL NEAR savewnd(f, n)    /* save ptr to current window */
  641.  
  642. int f, n;    /* prefix flag and argument */
  643.  
  644. {
  645.     swindow = curwp;
  646.     return(TRUE);
  647. }
  648.  
  649. PASCAL NEAR restwnd(f, n)    /* restore the saved screen */
  650.  
  651. int f, n;    /* prefix flag and argument */
  652.  
  653. {
  654.     register EWINDOW *wp;
  655.  
  656.     /* find the window */
  657.     wp = wheadp;
  658.     while (wp != NULL) {
  659.         if (wp == swindow) {
  660.             curwp = wp;
  661.             curbp = wp->w_bufp;
  662.             upmode();
  663.             return(TRUE);
  664.         }
  665.         wp = wp->w_wndp;
  666.     }
  667.  
  668.     mlwrite(TEXT208);
  669. /*        "[No such window exists]" */
  670.     return(FALSE);
  671. }
  672.  
  673. PASCAL NEAR newsize(f, n)    /* resize the screen, re-writing the screen */
  674.  
  675. int f;    /* default flag */
  676. int n;    /* numeric argument */
  677.  
  678. {
  679.     EWINDOW *wp;    /* current window being examined */
  680.     EWINDOW *nextwp; /* next window to scan */
  681.     EWINDOW *lastwp; /* last window scanned */
  682.     int lastline;    /* screen line of last line of current window */
  683.     int cmark;        /* current mark */
  684.  
  685. #if    WINDOW_MSWIN
  686.     ++n;    /* in this implementation, the message line is not part
  687.            of the screen */
  688. #endif
  689.     /* if the command defaults, assume the largest */
  690.     if (f == FALSE)
  691. #if    WINDOW_MSWIN
  692.         return FALSE;
  693. #else
  694.         n = term.t_mrow + 1;
  695. #endif
  696.  
  697.     /* make sure it's in range */
  698.     if (n < 3 || n > term.t_mrow + 1) {
  699.         mlwrite(TEXT209);
  700. /*            "%%Screen size out of range" */
  701.         return(FALSE);
  702.     }
  703.  
  704.     if (term.t_nrow == n - 1)
  705.         return(TRUE);
  706.     else if (term.t_nrow < n - 1) {
  707.  
  708.         /* go to the last window */
  709.         wp = wheadp;
  710.         while (wp->w_wndp != NULL)
  711.             wp = wp->w_wndp;
  712.  
  713.         /* and enlarge it as needed */
  714.         wp->w_ntrows = n - wp->w_toprow - 2;
  715.         wp->w_flag |= WFHARD|WFMODE;
  716.  
  717.     } else {
  718.  
  719.         /* rebuild the window structure */
  720.         nextwp = wheadp;
  721.         wp = NULL;
  722.         lastwp = NULL;
  723.         while (nextwp != NULL) {
  724.             wp = nextwp;
  725.             nextwp = wp->w_wndp;
  726.         
  727.             /* get rid of it if it is too low */
  728.             if (wp->w_toprow > n - 2) {
  729.  
  730.                 /* save the point/mark if needed */
  731.                 if (--wp->w_bufp->b_nwnd == 0) {
  732.                     wp->w_bufp->b_dotp = wp->w_dotp;
  733.                     wp->w_bufp->b_doto = wp->w_doto;
  734.                     for (cmark = 0; cmark < NMARKS; cmark++) {
  735.                         wp->w_bufp->b_markp[cmark] = wp->w_markp[cmark];
  736.                         wp->w_bufp->b_marko[cmark] = wp->w_marko[cmark];
  737.                     }
  738.                     wp->w_bufp->b_fcol = wp->w_fcol;
  739.                 }
  740.         
  741.                 /* update curwp and lastwp if needed */
  742.                 if (wp == curwp)
  743.                     curwp = wheadp;
  744.                     curbp = curwp->w_bufp;
  745.                 if (lastwp != NULL)
  746.                     lastwp->w_wndp = NULL;
  747.  
  748.                 /* free the structure */
  749.                 free((char *)wp);
  750.                 wp = NULL;
  751.  
  752.             } else {
  753.                 /* need to change this window size? */
  754.                 lastline = wp->w_toprow + wp->w_ntrows - 1;
  755.                 if (lastline >= n - 2) {
  756.                     wp->w_ntrows = n - wp->w_toprow - 2;
  757.                     wp->w_flag |= WFHARD|WFMODE;
  758.                 }
  759.             }
  760.         
  761.             lastwp = wp;
  762.         }
  763.     }
  764.  
  765.     /* screen is garbage */
  766. #if     WINDOW_MSWIN
  767.         vtsizescr (first_screen, n - 1, first_screen->s_ncol);
  768. #else
  769.     term.t_nrow = n - 1;
  770. #endif
  771.     sgarbf = TRUE;
  772.     return(TRUE);
  773. }
  774.  
  775. PASCAL NEAR newwidth(f, n)    /* resize the screen, re-writing the screen */
  776.  
  777. int f;    /* default flag */
  778. int n;    /* numeric argument */
  779.  
  780. {
  781.     register EWINDOW *wp;
  782.  
  783.     /* if the command defaults, assume the largest */
  784.     if (f == FALSE)
  785.         n = term.t_mcol;
  786.  
  787.     /* make sure it's in range */
  788.     if (n < 10 || n > term.t_mcol) {
  789.         mlwrite(TEXT210);
  790. /*            "%%Screen width out of range" */
  791.         return(FALSE);
  792.     }
  793.  
  794.     /* otherwise, just re-width it (no big deal) */
  795. #if    WINDOW_MSWIN
  796.     vtsizescr (first_screen, first_screen->s_nrow, n);
  797. #else
  798.     term.t_ncol = n;
  799. #endif
  800.     term.t_margin = n / 10;
  801.     term.t_scrsiz = n - (term.t_margin * 2);
  802.  
  803.     /* force all windows to redraw */
  804.     wp = wheadp;
  805.     while (wp) {
  806.         wp->w_flag |= WFHARD | WFMOVE | WFMODE;
  807.         wp = wp->w_wndp;
  808.     }
  809.     sgarbf = TRUE;
  810.  
  811.     return(TRUE);
  812. }
  813.  
  814. PASCAL NEAR new_col_org(f, n)    /* reposition the screen, re-writing the screen */
  815.  
  816. int f;    /* default flag */
  817. int n;    /* numeric argument */
  818.  
  819. {
  820. #if    WINDOW_MSWIN
  821.     term.t_colorg = 0;  /* screen positions are not managed by EMACS */
  822. #else
  823.     /* if the command defaults, assume zero */
  824.     if (f == FALSE)
  825.         n = 0;
  826.  
  827.     /* make sure it's in range */
  828.     if (n < 0 || n > term.t_mcol - term.t_ncol) {
  829.         mlwrite(TEXT223);
  830. /*            "%%Column origin out of range" */
  831.         return(FALSE);
  832.     }
  833.  
  834.     /* otherwise, just re-width it (no big deal) */
  835.     term.t_colorg = n;
  836.     sgarbf = TRUE;
  837. #endif
  838.     return(TRUE);
  839. }
  840.  
  841. PASCAL NEAR new_row_org(f, n)    /* reposition the screen, re-writing the screen */
  842.  
  843. int f;    /* default flag */
  844. int n;    /* numeric argument */
  845.  
  846. {
  847. #if    WINDOW_MSWIN
  848.     term.t_roworg = 0;  /* screen positions are not managed by EMACS */
  849. #else
  850.     /* if the command defaults, assume zero */
  851.     if (f == FALSE)
  852.         n = 0;
  853.  
  854.     /* make sure it's in range */
  855.     if (n < 0 || n > term.t_mrow - term.t_nrow) {
  856.         mlwrite(TEXT224);
  857. /*            "%%Row origin out of range" */
  858.         return(FALSE);
  859.     }
  860.  
  861.     /* otherwise, just re-size it (no big deal) */
  862.     term.t_roworg = n;
  863.  
  864.     sgarbf = TRUE;
  865. #endif
  866.     return(TRUE);
  867. }
  868.  
  869. int PASCAL NEAR getwpos()    /* get screen offset of current line in current window */
  870.  
  871. {
  872.     register int sline;    /* screen line from top of window */
  873.     register LINE *lp;    /* scannile line pointer */
  874.  
  875.     /* search down the line we want */
  876.     lp = curwp->w_linep;
  877.     sline = 1;
  878.     while (lp != curwp->w_dotp) {
  879.         ++sline;
  880.         lp = lforw(lp);
  881.     }
  882.  
  883.     /* and return the value */
  884.     return(sline);
  885. }
  886.  
  887. int PASCAL NEAR getcwnum()        /* get current window number */
  888.  
  889. {
  890.     register EWINDOW *wp;
  891.     register int num;
  892.  
  893.     num = 1;
  894.     wp = wheadp;
  895.     while (wp != curwp) {
  896.         wp = wp->w_wndp;
  897.         num++;
  898.     }
  899.     return(num);
  900. }
  901.  
  902.  
  903. int PASCAL NEAR gettwnum()        /* get total window count */
  904.  
  905. {
  906.     register EWINDOW *wp;
  907.     register int ctr;
  908.  
  909.     ctr = 0;
  910.     wp = wheadp;
  911.     while (wp) {
  912.         ctr++;
  913.         wp = wp->w_wndp;
  914.     }
  915.     return(ctr);
  916. }
  917.  
  918.