home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional / OS2PRO194.ISO / os2 / editor / beav / window.c < prev    next >
C/C++ Source or Header  |  1994-01-30  |  13KB  |  577 lines

  1. /*
  2. *       Window handling.
  3. */
  4. #include    "def.h"
  5.  
  6. bool mvupwind ();
  7. bool shrinkwind ();
  8.  
  9. extern char MSG_no_splt[];
  10. extern char MSG_cnt_al_w[];
  11. extern char MSG_one_w[];
  12. extern char MSG_imp_chg[];
  13. extern char MSG_scrn_rows[];
  14. extern char MSG_bad_num[];
  15.  
  16. /*
  17. * Reposition the window so as to center on the dot.
  18. */
  19. bool
  20. reposition ()
  21. {
  22.     long l_val;
  23.  
  24.     l_val = DOT_POS (curwp) - (curwp->w_ntrows * R_BYTES (curwp) / 2L);
  25.     move_ptr (curwp, l_val, FALSE, TRUE, FALSE);
  26.     curwp->w_flag |= WFHARD;
  27.     return (TRUE);
  28. }
  29.  
  30. /*
  31. * The command make the next
  32. * window (next => down the screen)
  33. * the current window. There are no real
  34. * errors, although the command does
  35. * nothing if there is only 1 window on
  36. * the screen.
  37. */
  38. bool
  39. nextwind ()
  40. {
  41.  
  42.     register WINDOW *wp;
  43.  
  44.     if ((wp = curwp->w_wndp) == NULL)
  45.     wp = wheadp;
  46.     curwp = wp;
  47.     curbp = wp->w_bufp;
  48.     return (TRUE);
  49. }
  50.  
  51. /*
  52. * This command makes the previous
  53. * window (previous => up the screen) the
  54. * current window. There arn't any errors,
  55. * although the command does not do a lot
  56. * if there is 1 window.
  57. */
  58. bool
  59. prevwind ()
  60. {
  61.  
  62.     register WINDOW *wp1;
  63.     register WINDOW *wp2;
  64.  
  65.     wp1 = wheadp;
  66.     wp2 = curwp;
  67.     if (wp1 == wp2)
  68.     wp2 = NULL;
  69.     while (wp1->w_wndp != wp2)
  70.     wp1 = wp1->w_wndp;
  71.     curwp = wp1;
  72.     curbp = wp1->w_bufp;
  73.     return (TRUE);
  74. }
  75.  
  76. /*
  77. * This command moves the current
  78. * window down by "arg" lines. Recompute
  79. * the top line in the window. The move up and
  80. * move down code is almost completely the same;
  81. * most of the work has to do with reframing the
  82. * window, and picking a new dot. We share the
  83. * code by having "move down" just be an interface
  84. * to "move up".
  85. */
  86. bool
  87. mvdnwind (f, n, k)
  88.     int f, n, k;
  89. {
  90.     return (mvupwind (f, -n, KRANDOM));
  91. }
  92.  
  93. /*
  94. * Move the current window up by "arg"
  95. * lines. Recompute the new top line of the window.
  96. * Look to see if "." is still on the screen. If it is,
  97. * you win. If it isn't, then move "." to center it
  98. * in the new framing of the window (this command does
  99. * not really move "."; it moves the frame).
  100. */
  101. bool
  102. mvupwind (f, n, k)
  103.     int f, n, k;
  104. {
  105.     A32 l_val, l_bytes;
  106.  
  107.     l_bytes = (A32) R_BYTES (curwp);    /* number of bytes in a row */
  108.     l_val = n * l_bytes;    /* number of bytes to move */
  109.     move_ptr (curwp, l_val, FALSE, TRUE, TRUE);    /* move window */
  110.  
  111.     /* check that dot is in window */
  112.     while (DOT_POS (curwp) < WIND_POS (curwp))
  113.     {
  114.     /* dot is before the first window line */
  115.     move_ptr (curwp, l_bytes, TRUE, TRUE, TRUE);
  116.     }
  117.     while (DOT_POS (curwp) >=
  118.        ((l_bytes * curwp->w_ntrows) + WIND_POS (curwp)))
  119.     {
  120.     /* dot is after the last window line */
  121.     move_ptr (curwp, -l_bytes, TRUE, TRUE, TRUE);
  122.     }
  123.     curwp->w_flag |= WFHARD;
  124.     return (TRUE);
  125. }
  126.  
  127. /*
  128. * This command makes the current
  129. * window the only window on the screen.
  130. * Try to set the framing
  131. * so that "." does not have to move on
  132. * the display. Some care has to be taken
  133. * to keep the values of dot and mark
  134. * in the buffer structures right if the
  135. * distruction of a window makes a buffer
  136. * become undisplayed.
  137. */
  138. bool
  139. onlywind ()
  140. {
  141.  
  142.     register WINDOW *wp;
  143.     register LINE *lp;
  144.     register int i;
  145.  
  146.     while (wheadp != curwp)
  147.     {
  148.  
  149.     wp = wheadp;
  150.     wheadp = wp->w_wndp;
  151.     if (--wp->w_bufp->b_nwnd == 0)
  152.     {
  153.  
  154.         wp->w_bufp->b_dotp = wp->w_dotp;
  155.         wp->w_bufp->b_doto = wp->w_doto;
  156.         wp->w_bufp->b_markp = wp->w_markp;
  157.         wp->w_bufp->b_marko = wp->w_marko;
  158.     }
  159.  
  160.     free ((char *) wp);
  161.     }
  162.  
  163.     while (curwp->w_wndp != NULL)
  164.     {
  165.  
  166.     wp = curwp->w_wndp;
  167.     curwp->w_wndp = wp->w_wndp;
  168.     if (--wp->w_bufp->b_nwnd == 0)
  169.     {
  170.  
  171.         wp->w_bufp->b_dotp = wp->w_dotp;
  172.         wp->w_bufp->b_doto = wp->w_doto;
  173.         wp->w_bufp->b_markp = wp->w_markp;
  174.         wp->w_bufp->b_marko = wp->w_marko;
  175.     }
  176.  
  177.     free ((char *) wp);
  178.     }
  179.  
  180.     lp = curwp->w_linep;
  181.     i = curwp->w_toprow;
  182.     while (i != 0 && lback (lp) != curbp->b_linep)
  183.     {
  184.  
  185.     --i;
  186.     lp = lback (lp);
  187.     }
  188.  
  189.     curwp->w_toprow = 0;
  190.     curwp->w_ntrows = nrow - 2;    /* 2 = mode, echo.  */
  191.     curwp->w_linep = lp;
  192.     curwp->w_flag |= WFMODE | WFHARD;
  193.     return (TRUE);
  194. }
  195.  
  196. /*
  197.  * Delete the current window, placing its space in the window above,
  198.  * or, if it is the top window, the window below. Bound to C-X 0.
  199.  */
  200.  
  201. bool
  202. delwind ()
  203.  
  204. {
  205.     register WINDOW *wp;    /* window to recieve deleted space */
  206.     register WINDOW *lwp;    /* ptr window before curwp */
  207.     register int target;    /* target line to search for */
  208.  
  209.     /* if there is only one window, don't delete it */
  210.     if (wheadp->w_wndp == NULL)
  211.     {
  212.     return (FALSE);
  213.     }
  214.  
  215.     /* find window before curwp in linked list */
  216.     wp = wheadp;
  217.     lwp = NULL;
  218.     while (wp != NULL)
  219.     {
  220.     if (wp == curwp)
  221.         break;
  222.     lwp = wp;
  223.     wp = wp->w_wndp;
  224.     }
  225.  
  226.     /* find recieving window and give up our space */
  227.     wp = wheadp;
  228.     if (curwp->w_toprow == 0)
  229.     {
  230.     /* find the next window down */
  231.     target = curwp->w_ntrows + 1;
  232.     while (wp != NULL)
  233.     {
  234.         if (wp->w_toprow == target)
  235.         break;
  236.         wp = wp->w_wndp;
  237.     }
  238.     if (wp == NULL)
  239.         return (FALSE);
  240.     wp->w_toprow = 0;
  241.     wp->w_ntrows += target;
  242.     }
  243.     else
  244.     {
  245.     /* find the next window up */
  246.     target = curwp->w_toprow - 1;
  247.     while (wp != NULL)
  248.     {
  249.         if ((wp->w_toprow + wp->w_ntrows) == target)
  250.         break;
  251.         wp = wp->w_wndp;
  252.     }
  253.     if (wp == NULL)
  254.         return (FALSE);
  255.     wp->w_ntrows += 1 + curwp->w_ntrows;
  256.     }
  257.  
  258.     /* get rid of the current window */
  259.     if (--curwp->w_bufp->b_nwnd == 0)
  260.     {
  261.     curwp->w_bufp->b_dotp = curwp->w_dotp;
  262.     curwp->w_bufp->b_doto = curwp->w_doto;
  263.     curwp->w_bufp->b_markp = curwp->w_markp;
  264.     curwp->w_bufp->b_marko = curwp->w_marko;
  265.     }
  266.     if (lwp == NULL)
  267.     wheadp = curwp->w_wndp;
  268.     else
  269.     lwp->w_wndp = curwp->w_wndp;
  270.     free ((char *) curwp);
  271.     curwp = wp;
  272.     wp->w_flag |= WFMODE | WFHARD;
  273.     curbp = wp->w_bufp;
  274.     return (TRUE);
  275. }
  276.  
  277. /*
  278. * Split the current window. A window
  279. * smaller than 3 lines cannot be split.
  280. * The only other error that is possible is
  281. * a "malloc" failure allocating the structure
  282. * for the new window.
  283. */
  284. bool
  285. splitwind ()
  286. {
  287.  
  288.     register WINDOW *wp;
  289.     register int ntru;
  290.     register int ntrl;
  291.     register int ntrd;
  292.     register WINDOW *wp1;
  293.     register WINDOW *wp2;
  294.     char buf[NCOL], buf1[NCOL];
  295.  
  296.     if (curwp->w_ntrows < MIN_WIN_ROWS)
  297.     {
  298.     sprintf (buf1, MSG_no_splt, R_BYTE_FMT (curwp));
  299.     sprintf (buf, buf1, curwp->w_ntrows);
  300.     writ_echo (buf);
  301.     return (FALSE);
  302.     }
  303.  
  304.     if ((wp = (WINDOW *) malloc (sizeof (WINDOW))) == NULL)
  305.     {
  306.     err_echo (MSG_cnt_al_w);
  307.     return (FALSE);
  308.     }
  309.  
  310.     ++curbp->b_nwnd;        /* Displayed twice.  */
  311.     wp->w_bufp = curbp;
  312.     wp->w_dotp = curwp->w_dotp;
  313.     wp->w_doto = curwp->w_doto;
  314.     wp->w_unit_offset = curwp->w_unit_offset;
  315.     wp->w_markp = curwp->w_markp;
  316.     wp->w_marko = curwp->w_marko;
  317.     wp->w_flag = 0;
  318.     wp->w_disp_shift = curwp->w_disp_shift;
  319.     wp->w_intel_mode = curwp->w_intel_mode;
  320.     wp->w_fmt_ptr = curwp->w_fmt_ptr;
  321.     ntru = (curwp->w_ntrows - 1) / 2;    /* Upper size         */
  322.     ntrl = (curwp->w_ntrows - 1) - ntru;    /* Lower size      */
  323.  
  324.     curwp->w_ntrows = ntru;
  325.     wp->w_wndp = curwp->w_wndp;
  326.     curwp->w_wndp = wp;
  327.     wp->w_toprow = curwp->w_toprow + ntru + 1;
  328.     wp->w_ntrows = ntrl;
  329.  
  330.     wind_on_dot (curwp);    /* put window on the dot */
  331.     wp->w_loff = curwp->w_loff;    /* do the same for the new window */
  332.     wp->w_linep = curwp->w_linep;
  333.     curwp->w_flag |= WFMODE | WFHARD;
  334.     wp->w_flag |= WFMODE | WFHARD;
  335.     return (TRUE);
  336. }
  337.  
  338. /*
  339. * Enlarge the current window.
  340. * Find the window that loses space. Make
  341. * sure it is big enough. If so, hack the window
  342. * descriptions, and ask redisplay to do all the
  343. * hard work. You don't just set "force reframe"
  344. * because dot would move.
  345. */
  346. bool
  347. enlargewind (f, n, k)
  348.     int f, n, k;
  349. {
  350.     register WINDOW *adjwp;
  351.     register LINE *lp;
  352.     register int i;
  353.  
  354.     if (n < 0)
  355.     return (shrinkwind (f, -n, KRANDOM));
  356.     if (wheadp->w_wndp == NULL)
  357.     {
  358.  
  359.     writ_echo (MSG_one_w);
  360.     return (FALSE);
  361.     }
  362.  
  363.     if ((adjwp = curwp->w_wndp) == NULL)
  364.     {
  365.     adjwp = wheadp;
  366.     while (adjwp->w_wndp != curwp)
  367.         adjwp = adjwp->w_wndp;
  368.     }
  369.  
  370.     if (adjwp->w_ntrows <= n)
  371.     {
  372.     writ_echo (MSG_imp_chg);
  373.     return (FALSE);
  374.     }
  375.  
  376.     if (curwp->w_wndp == adjwp)
  377.     {
  378.     /* Shrink below.     */
  379.     lp = adjwp->w_linep;
  380.     for (i = 0; i < n && lp != adjwp->w_bufp->b_linep; ++i)
  381.         lp = lforw (lp);
  382.     adjwp->w_linep = lp;
  383.     adjwp->w_toprow += n;
  384.     }
  385.     else
  386.     {
  387.     /* Shrink above.     */
  388.     lp = curwp->w_linep;
  389.     for (i = 0; i < n && lback (lp) != curbp->b_linep; ++i)
  390.         lp = lback (lp);
  391.     curwp->w_linep = lp;
  392.     curwp->w_toprow -= n;
  393.     }
  394.  
  395.     curwp->w_ntrows += n;
  396.     adjwp->w_ntrows -= n;
  397.     curwp->w_flag |= WFMODE | WFHARD;
  398.     adjwp->w_flag |= WFMODE | WFHARD;
  399.     return (TRUE);
  400. }
  401.  
  402. /*
  403. * Shrink the current window.
  404. * Find the window that gains space. Hack at
  405. * the window descriptions. Ask the redisplay to
  406. * do all the hard work.
  407. */
  408. bool
  409. shrinkwind (f, n, k)
  410.     int f, n, k;
  411. {
  412.     register WINDOW *adjwp;
  413.     register LINE *lp;
  414.     register int i;
  415.  
  416.     if (n < 0)
  417.     return (enlargewind (f, -n, KRANDOM));
  418.     if (wheadp->w_wndp == NULL)
  419.     {
  420.     writ_echo (MSG_one_w);
  421.     return (FALSE);
  422.     }
  423.  
  424.     if ((adjwp = curwp->w_wndp) == NULL)
  425.     {
  426.     adjwp = wheadp;
  427.     while (adjwp->w_wndp != curwp)
  428.         adjwp = adjwp->w_wndp;
  429.     }
  430.  
  431.     if (curwp->w_ntrows <= n)
  432.     {
  433.     writ_echo (MSG_imp_chg);
  434.     return (FALSE);
  435.     }
  436.  
  437.     if (curwp->w_wndp == adjwp)
  438.     {
  439.     /* Grow below.       */
  440.     lp = adjwp->w_linep;
  441.     for (i = 0; i < n && lback (lp) != adjwp->w_bufp->b_linep; ++i)
  442.         lp = lback (lp);
  443.     adjwp->w_linep = lp;
  444.     adjwp->w_toprow -= n;
  445.     }
  446.     else
  447.     {
  448.     /* Grow above.       */
  449.     lp = curwp->w_linep;
  450.     for (i = 0; i < n && lp != curbp->b_linep; ++i)
  451.         lp = lforw (lp);
  452.     curwp->w_linep = lp;
  453.     curwp->w_toprow += n;
  454.     }
  455.  
  456.     curwp->w_ntrows -= n;
  457.     adjwp->w_ntrows += n;
  458.     curwp->w_flag |= WFMODE | WFHARD;
  459.     adjwp->w_flag |= WFMODE | WFHARD;
  460.     return (TRUE);
  461. }
  462.  
  463. /*
  464. * Pick a window for a pop-up.
  465. * Split the screen if there is only
  466. * one window. Pick the uppermost window that
  467. * isn't the current window. An LRU algorithm
  468. * might be better. Return a pointer, or
  469. * NULL on error.
  470. */
  471. WINDOW *
  472. wpopup ()
  473. {
  474.  
  475.     register WINDOW *wp;
  476.  
  477.     if (wheadp->w_wndp == NULL
  478.     && splitwind () == FALSE)
  479.     return (NULL);
  480.     wp = wheadp;        /* Find window to use    */
  481.     while (wp != NULL && wp == curwp)
  482.     wp = wp->w_wndp;
  483.     return (wp);
  484. }
  485.  
  486. /*
  487. * Refresh the display.
  488. * In the normal case the
  489. * call to "update" in "main.c" refreshes the screen,
  490. * and all of the windows need not be recomputed.
  491. */
  492. bool
  493. refresh ()
  494. {
  495.     sgarbf = TRUE;
  496.     return (TRUE);
  497. }
  498.  
  499. /*  pvr
  500. * Set the number of rows on the screen.
  501. * This sets the nrow value and fixes up the windows
  502. * to account for the new size.
  503. */
  504. bool
  505. screen_rows (f, n, k)
  506.     int f, n, k;
  507. {
  508.     int new_rows;
  509.     register int s;
  510.     char buf[80];
  511.     WINDOW *wp, *cur_wp_sav;
  512.  
  513.     cur_wp_sav = curwp;
  514.  
  515.     new_rows = nrow;        /* default it if sscanf reads nothing */
  516.     sprintf (buf, "%s [%d] ", MSG_scrn_rows, nrow);
  517.     if (f == FALSE)
  518.     {
  519.     if ((s = ereply (buf, buf, sizeof (buf), 0) != TRUE))
  520.         return (s);
  521.     sscanf (buf, "%d", &new_rows);
  522.     }
  523.     else
  524.     new_rows = n;
  525.  
  526.     if (new_rows <= MIN_WIN_ROWS)
  527.     {
  528.     writ_echo (MSG_bad_num);
  529.     return (FALSE);
  530.     }
  531.  
  532.     ttmove (0, 0);
  533.     tteeop ();
  534.     refresh ();
  535.  
  536.     /* set new nrow value */
  537.     nrow = new_rows;
  538.  
  539.     while (TRUE)
  540.     {
  541.     /* find last window */
  542.     for (wp = wheadp; wp->w_wndp; wp = wp->w_wndp)
  543.         wp->w_flag |= WFHARD;    /* update all windows */
  544.  
  545.     wp->w_flag |= WFHARD;    /* update last windows */
  546.  
  547.     /* if no part of window can fit, kill it */
  548.     if ((wp->w_toprow + MIN_WIN_ROWS) >= new_rows)
  549.     {
  550.         /* don't kill last window */
  551.         if (wp == wheadp)
  552.         {
  553.         nrow = MIN_WIN_ROWS + 2;    /* set min size */
  554.         wp->w_ntrows = MIN_WIN_ROWS;
  555.         wind_on_dot (wp);
  556.         break;
  557.         }
  558.         curwp = wp;
  559.         curbp = wp->w_bufp;
  560.         delwind ();
  561.     }
  562.     else
  563.     {
  564.         /* adjust window to fit */
  565.         wp->w_ntrows = new_rows - wp->w_toprow - 2;
  566.         wind_on_dot (wp);
  567.         break;
  568.     }
  569.     }
  570.     /* free up old screen memory */
  571.     vtfree ();
  572.     /* recreate scerrn buffers */
  573.     vtinit ();
  574.     eerase ();            /* clean up prompt line */
  575.     return (TRUE);
  576. }
  577.