home *** CD-ROM | disk | FTP | other *** search
/ SPACE 2 / SPACE - Library 2 - Volume 1.iso / apps / 223 / emacssrc / window.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-02-17  |  9.1 KB  |  417 lines

  1. /*
  2.  * Window management.
  3.  * Some of the functions are internal,
  4.  * and some are attached to keys that the
  5.  * user actually types.
  6.  */
  7. #include    <stdio.h>
  8. #include    "ed.h"
  9.  
  10. /*
  11.  * Reposition dot in the current
  12.  * window to line "n". If the argument is
  13.  * positive, it is that line. If it is negative it
  14.  * is that line from the bottom. If it is 0 the window
  15.  * is centered (this is what the standard redisplay code
  16.  * does). With no argument it defaults to 1. Bound to
  17.  * M-!. Because of the default, it works like in
  18.  * Gosling.
  19.  */
  20. reposition(f, n) 
  21.     {
  22.     curwp->w_force = n;
  23.     curwp->w_flag |= WFFORCE;
  24.     return (TRUE);
  25.     }
  26.  
  27. /*
  28.  * Refresh the screen. With no
  29.  * argument, it just does the refresh. With an
  30.  * argument it recenters "." in the current
  31.  * window. Bound to "C-L".
  32.  */
  33. refresh(f, n)
  34.     {
  35.     if (f == FALSE) 
  36.         {
  37.         sgarbf = TRUE;
  38.         }
  39.     else 
  40.         {
  41.         curwp->w_force = 0;        /* Center dot.        */
  42.         curwp->w_flag |= WFFORCE|WFHARD;
  43.         }
  44.     return (TRUE);
  45.     }
  46.  
  47. /*
  48.  * The command make the next
  49.  * window (next => down the screen)
  50.  * the current window. There are no real
  51.  * errors, although the command does
  52.  * nothing if there is only 1 window on
  53.  * the screen. Bound to "C-X C-N".
  54.  */
  55. nextwind(f, n)
  56.     {
  57.     register WINDOW    *wp;
  58.  
  59.     wp = curwp;
  60.     do                 /* mb: added */
  61.         {
  62.         wp = wp->w_wndp;
  63.         if (wp == NULL)
  64.             wp = wheadp;
  65.         if (wp == curwp)
  66.             return(FALSE);
  67.         }
  68.         while (wp->w_bufp->b_flag&BFTEMP);
  69.     curwp = wp;
  70.     if (curbp != wp->w_bufp)
  71.         oldbp = curbp;        /* mb: added */
  72.     curbp = wp->w_bufp;
  73.     return (TRUE);
  74.     }
  75.  
  76. /*
  77.  * This command makes the previous
  78.  * window (previous => up the screen) the
  79.  * current window. There arn't any errors,
  80.  * although the command does not do a lot
  81.  * if there is 1 window.
  82.  */
  83. prevwind(f, n)
  84.     {
  85.     register WINDOW    *wp1;
  86.     register WINDOW    *wp2;
  87.  
  88.     wp1 = curwp;
  89.     do                 /* mb: added */
  90.         {
  91.         wp2 = wp1;
  92.         if (wp2 == wheadp)
  93.             wp2 = NULL;
  94.         wp1 = wheadp;
  95.         while (wp1->w_wndp != wp2)
  96.             wp1 = wp1->w_wndp;
  97.         if (wp1 == curwp)
  98.             return(FALSE);
  99.         }
  100.         while (wp1->w_bufp->b_flag&BFTEMP);
  101.     curwp = wp1;
  102.     if (curbp != wp1->w_bufp)
  103.         oldbp = curbp;        /* mb: added */
  104.     curbp = wp1->w_bufp;
  105.     return (TRUE);
  106.     }
  107.  
  108. #if EXTRA
  109. /*
  110.  * This command moves the current
  111.  * window down by "arg" lines. Recompute
  112.  * the top line in the window. The move up and
  113.  * move down code is almost completely the same;
  114.  * most of the work has to do with reframing the
  115.  * window, and picking a new dot. We share the
  116.  * code by having "move down" just be an interface
  117.  * to "move up".  Bound to "C-X C-N".
  118.  */
  119. mvdnwind(f, n)
  120. register int    n;
  121.     {
  122.     return (mvupwind(f, -n));
  123.     }
  124.  
  125. /*
  126.  * Move the current window up by "arg"
  127.  * lines. Recompute the new top line of the window.
  128.  * Look to see if "." is still on the screen. If it is,
  129.  * you win. If it isn't, then move "." to center it
  130.  * in the new framing of the window (this command does
  131.  * not really move "."; it moves the frame). Bound
  132.  * to "C-X C-P".
  133.  */
  134. mvupwind(f, n)
  135. register int    n;
  136.     {
  137.     register LINE    *lp;
  138.     register int    i;
  139.  
  140.     lp = curwp->w_linep;
  141.     if (n < 0) 
  142.         {
  143.         while (n++ && lp!=curbp->b_linep)
  144.             lp = lforw(lp);
  145.         }
  146.     else 
  147.         {
  148.         while (n-- && lback(lp)!=curbp->b_linep)
  149.             lp = lback(lp);
  150.         }
  151.     curwp->w_linep = lp;
  152.     curwp->w_flag |= WFHARD;        /* Mode line is OK.    */
  153.     for (i=0; i<curwp->w_ntrows; ++i) 
  154.         {
  155.         if (lp == curwp->w_dotp)
  156.             return (TRUE);
  157.         if (lp == curbp->b_linep)
  158.             break;
  159.         lp = lforw(lp);
  160.         }
  161.     lp = curwp->w_linep;
  162.     i  = curwp->w_ntrows/2;
  163.     while (i-- && lp!=curbp->b_linep)
  164.         lp = lforw(lp);
  165.     curwp->w_dotp  = lp;
  166.     curwp->w_doto  = 0;
  167.     return (TRUE);
  168.     }
  169. #endif
  170.  
  171. /*
  172.  * This command makes the current
  173.  * window the only window on the screen.
  174.  * Bound to "C-X 1". Try to set the framing
  175.  * so that "." does not have to move on
  176.  * the display. Some care has to be taken
  177.  * to keep the values of dot and mark
  178.  * in the buffer structures right if the
  179.  * distruction of a window makes a buffer
  180.  * become undisplayed.
  181.  */
  182. onlywind(f, n)
  183.     {
  184.     register WINDOW    *wp;
  185.     register LINE    *lp;
  186.     register int    i;
  187.  
  188.     while (wheadp != curwp) 
  189.         {
  190.         wp = wheadp;
  191.         wheadp = wp->w_wndp;
  192.         if (--wp->w_bufp->b_nwnd == 0) 
  193.             {
  194.             wp->w_bufp->b_dotp  = wp->w_dotp;
  195.             wp->w_bufp->b_doto  = wp->w_doto;
  196.             wp->w_bufp->b_markp = wp->w_markp;
  197.             wp->w_bufp->b_marko = wp->w_marko;
  198.             }
  199.         free((char *) wp);
  200.         }
  201.     while (curwp->w_wndp != NULL) 
  202.         {
  203.         wp = curwp->w_wndp;
  204.         curwp->w_wndp = wp->w_wndp;
  205.         if (--wp->w_bufp->b_nwnd == 0) 
  206.             {
  207.             wp->w_bufp->b_dotp  = wp->w_dotp;
  208.             wp->w_bufp->b_doto  = wp->w_doto;
  209.             wp->w_bufp->b_markp = wp->w_markp;
  210.             wp->w_bufp->b_marko = wp->w_marko;
  211.             }
  212.         free((char *) wp);
  213.         }
  214.     lp = curwp->w_linep;
  215.     i  = curwp->w_toprow;
  216.     while (i!=0 && lback(lp)!=curbp->b_linep) 
  217.         {
  218.         --i;
  219.         lp = lback(lp);
  220.         }
  221.     curwp->w_toprow = 0;
  222.     curwp->w_ntrows = term.t_nrow-1;
  223.     curwp->w_linep  = lp;
  224.     curwp->w_flag  |= WFMODE|WFHARD;
  225.     return (TRUE);
  226.     }
  227.  
  228. /*
  229.  * Split the current window. A window
  230.  * smaller than 3 lines cannot be split.
  231.  * The only other error that is possible is
  232.  * a "malloc" failure allocating the structure
  233.  * for the new window. Bound to "C-X 2".
  234.  */
  235. splitwind(f, n)
  236.     {
  237.     register WINDOW    *wp;
  238.     register LINE    *lp;
  239.     register int    ntru;
  240.     register int    ntrl;
  241.     register int    ntrd;
  242.     register WINDOW    *wp1;
  243.     register WINDOW    *wp2;
  244.  
  245.     if (curwp->w_ntrows < 3) 
  246.         {
  247.         mlwrite("Cannot split a %d line window", curwp->w_ntrows);
  248.         return (FALSE);
  249.         }
  250.     if ((wp = (WINDOW *) malloc(sizeof(WINDOW))) == NULL) 
  251.         {
  252.         mlwrite("Not enough memory");
  253.         return (FALSE);
  254.         }
  255.     ++curbp->b_nwnd;            /* Displayed twice.    */
  256.     wp->w_bufp  = curbp;
  257.     wp->w_dotp  = curwp->w_dotp;
  258.     wp->w_doto  = curwp->w_doto;
  259.     wp->w_markp = curwp->w_markp;
  260.     wp->w_marko = curwp->w_marko;
  261.     wp->w_flag  = 0;
  262.     wp->w_force = 0;
  263.     ntru = (curwp->w_ntrows-1) / 2;        /* Upper size        */
  264.     ntrl = (curwp->w_ntrows-1) - ntru;    /* Lower size        */
  265.     lp = curwp->w_linep;
  266.     ntrd = 0;
  267.     while (lp != curwp->w_dotp) 
  268.         {
  269.         ++ntrd;
  270.         lp = lforw(lp);
  271.         }
  272.     lp = curwp->w_linep;
  273.     if (ntrd <= ntru)             /* Old is upper window.    */
  274.         {
  275.         if (ntrd == ntru)        /* Hit mode line.    */
  276.             lp = lforw(lp);
  277.         curwp->w_ntrows = ntru;
  278.         wp->w_wndp = curwp->w_wndp;
  279.         curwp->w_wndp = wp;
  280.         wp->w_toprow = curwp->w_toprow+ntru+1;
  281.         wp->w_ntrows = ntrl;
  282.         }
  283.     else                     /* Old is lower window    */
  284.         {
  285.         wp1 = NULL;
  286.         wp2 = wheadp;
  287.         while (wp2 != curwp) 
  288.             {
  289.             wp1 = wp2;
  290.             wp2 = wp2->w_wndp;
  291.             }
  292.         if (wp1 == NULL)
  293.             wheadp = wp;
  294.         else
  295.             wp1->w_wndp = wp;
  296.         wp->w_wndp   = curwp;
  297.         wp->w_toprow = curwp->w_toprow;
  298.         wp->w_ntrows = ntru;
  299.         ++ntru;                /* Mode line.        */
  300.         curwp->w_toprow += ntru;
  301.         curwp->w_ntrows  = ntrl;
  302.         while (ntru--)
  303.             lp = lforw(lp);
  304.         }
  305.     curwp->w_linep = lp;            /* Adjust the top lines    */
  306.     wp->w_linep = lp;            /* if necessary.    */
  307.     curwp->w_flag |= WFMODE|WFHARD;
  308.     wp->w_flag |= WFMODE|WFHARD;
  309.     thisflag |= CFSPLIT;
  310.     return (TRUE);
  311.     }
  312.  
  313. #if EXTRA
  314. /*
  315.  * Enlarge the current window.
  316.  * Find the window that loses space. Make
  317.  * sure it is big enough. If so, hack the window
  318.  * descriptions, and ask redisplay to do all the
  319.  * hard work. You don't just set "force reframe"
  320.  * because dot would move. Bound to "C-X ^".
  321.  * mb: generalized for n<0.
  322.  */
  323. enlargewind(f, n)
  324.     {
  325.     register WINDOW    *adjwp;
  326.     register LINE    *lp;
  327.     register int    i;
  328.     LINE            *lp1;
  329.  
  330.     if (wheadp->w_wndp == NULL)
  331.         return (FALSE);
  332.     if ((adjwp=curwp->w_wndp) == NULL) 
  333.         {
  334.         adjwp = wheadp;
  335.         while (adjwp->w_wndp != curwp)
  336.             adjwp = adjwp->w_wndp;
  337.         }
  338.     if (n >= adjwp->w_ntrows || -n >= adjwp->w_ntrows) 
  339.         {
  340.         return (FALSE);
  341.         }
  342.     if (curwp->w_wndp == adjwp)         /* Shrink below.    */
  343.         {
  344.         lp = adjwp->w_linep;
  345.         lp1 = adjwp->w_bufp->b_linep;
  346.         if( n >= 0 )
  347.             for (i=0; i<n && lp!=lp1; ++i)
  348.                 lp = lforw(lp);
  349.         else
  350.             for (i=0; i>n && lback(lp)!=lp1; --i)
  351.                 lp = lback(lp);
  352.         adjwp->w_linep  = lp;
  353.         adjwp->w_toprow += n;
  354.         }
  355.     else                 /* Shrink above.    */
  356.         {
  357.         lp = curwp->w_linep;
  358.         if( n >= 0 )
  359.             for (i=0; i<n && lback(lp)!=curbp->b_linep; ++i)
  360.                 lp = lback(lp);
  361.         else
  362.             for (i=0; i>n && lp!=curbp->b_linep; --i)
  363.                 lp = lforw(lp);
  364.         curwp->w_linep  = lp;
  365.         curwp->w_toprow -= n;
  366.         }
  367.     curwp->w_ntrows += n;
  368.     adjwp->w_ntrows -= n;
  369.     curwp->w_flag |= WFMODE|WFHARD;
  370.     adjwp->w_flag |= WFMODE|WFHARD;
  371.     return (TRUE);
  372.     }
  373.  
  374. /* mb: shrinkwind(f, n) deleted (use enlargewind() with n<0). */
  375. #endif
  376.  
  377. /*
  378.  * Pick a window for a pop-up.
  379.  * Split the screen if there is only
  380.  * one window. Pick the uppermost window that
  381.  * isn't the current window. An LRU algorithm
  382.  * might be better. Return a pointer, or
  383. * NULL on error.
  384.  */
  385. WINDOW    *wpopup()
  386.     {
  387.     register WINDOW    *wp;
  388.  
  389.     if (wheadp->w_wndp == NULL        /* Only 1 window    */
  390.     && splitwind(FALSE, 0) == FALSE)     /* and it won't split    */
  391.         return (NULL);
  392.     wp = wheadp;                /* Find window to use    */
  393.     while (wp!=NULL && wp==curwp)
  394.         wp = wp->w_wndp;
  395.     return (wp);
  396.     }
  397.  
  398. /* mb: added
  399.  * Scroll next window down a page.
  400.  * Bound to C-X V.
  401.  */
  402. page_nextw(f, n)
  403.     {
  404.     int s;
  405.  
  406.     nextwind(FALSE, 1);
  407.     forwpage(f, n);
  408.     prevwind(FALSE, 1);
  409.     }
  410.  
  411. /* Bound to C-X Z. */
  412.  
  413. back_nextw(f, n)
  414.     {
  415.     page_nextw(TRUE, -n);
  416.     }
  417.