home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-387-Vol-3of3.iso / x / xvisrc.zoo / mouse.c < prev    next >
C/C++ Source or Header  |  1992-07-28  |  5KB  |  248 lines

  1. /* Copyright (c) 1990,1991,1992 Chris and John Downey */
  2. #ifndef lint
  3. static char *sccsid = "@(#)mouse.c    2.1 (Chris & John Downey) 7/29/92";
  4. #endif
  5.  
  6. /***
  7.  
  8. * program name:
  9.     xvi
  10. * function:
  11.     PD version of UNIX "vi" editor, with extensions.
  12. * module name:
  13.     mouse.c
  14. * module function:
  15.     Machine-independent mouse interface routines.
  16. * history:
  17.     STEVIE - ST Editor for VI Enthusiasts, Version 3.10
  18.     Originally by Tim Thompson (twitch!tjt)
  19.     Extensive modifications by Tony Andrews (onecom!wldrdg!tony)
  20.     Heavily modified by Chris & John Downey
  21. ***/
  22.  
  23. #include "xvi.h"
  24.  
  25. /*
  26.  * Find the Line corresponding to a given physical screen row.
  27.  *
  28.  * Also return (in *pstartrow) the physical screen row on which that
  29.  * Line starts.
  30.  */
  31. static Line *
  32. findline(wp, row, pstartrow)
  33. Xviwin        *wp;
  34. register int    row;
  35. int        *pstartrow;
  36. {
  37.     register int    lposn;
  38.     int            maxrow;
  39.     register Line    *lp;
  40.     Line        *lastline;
  41.  
  42.     lp = wp->w_topline;
  43.     lastline = wp->w_buffer->b_lastline;
  44.     lposn = wp->w_winpos;
  45.     maxrow = wp->w_cmdline;
  46.  
  47.     for (;;) {
  48.     register int    newposn;
  49.  
  50.     newposn = lposn + LONG2INT(plines(wp, lp));
  51.     if (
  52.         (
  53.         /*
  54.          * If we've found the right line ...
  55.          */
  56.         row >= lposn
  57.         &&
  58.         row < newposn
  59.         )
  60.         ||
  61.         (
  62.         /*
  63.          * ... or we've got to the end of the buffer ...
  64.          */
  65.         lp->l_next == wp->w_buffer->b_lastline
  66.         )
  67.         ||
  68.         (
  69.         /*
  70.          * ... or we're at the bottom of the window ...
  71.          */
  72.         newposn >= maxrow
  73.         )
  74.     ) {
  75.         /*
  76.          * ... we return this line.
  77.          */
  78.         *pstartrow = lposn;
  79.         return lp;
  80.     }
  81.     lposn = newposn;
  82.     lp = lp->l_next;
  83.     }
  84. }
  85.  
  86. /*
  87.  * Move the text cursor as near as possible to the given physical
  88.  * screen co-ordinates.
  89.  */
  90. static void
  91. setcursor(wp, row, col)
  92. Xviwin    *wp;
  93. int    row;        /* row where mouse was clicked */
  94. int    col;        /* column where mouse was clicked */
  95. {
  96.     int        startrow;    /* row at which line starts */
  97.     int        vcol;        /* virtual column */
  98.     Line    *lp;        /* logical line corresponding to row */
  99.  
  100.     lp = findline(wp, row, &startrow);
  101.     vcol = col + ((row - startrow) * wp->w_ncols);
  102.     move_cursor(wp, lp, 0);
  103.     coladvance(wp, (wp->w_curswant = vcol));
  104. }
  105.  
  106. /*
  107.  * Find the window a given physical screen row is in.
  108.  */
  109. static Xviwin *
  110. findwin(row)
  111. register int    row;
  112. {
  113.     register Xviwin    *wp;
  114.  
  115.     wp = curwin;
  116.     for (;;) {
  117.     if (wp->w_winpos <= row && row <= wp->w_cmdline) {
  118.         /*
  119.          * We've found the right window.
  120.          */
  121.         return wp;
  122.     }
  123.     if ((wp = next_window(wp)) == curwin) {
  124.         /*
  125.          * This can't happen: the mouse isn't in any
  126.          * window.
  127.          */
  128.         return NULL;
  129.     }
  130.     }
  131. }
  132.  
  133. /*
  134.  * Handle mouse drag event.
  135.  */
  136. void
  137. mousedrag(row1, row2, col1, col2)
  138. int row1, row2, col1, col2;
  139. {
  140.     if (State == NORMAL && row1 != row2 && row1 < Rows - 1) {
  141.     Xviwin *wp;
  142.  
  143.     if ((wp = findwin(row1)) == NULL) {
  144.         /*
  145.          * This can't happen.
  146.          */
  147.         return;
  148.     }
  149.  
  150.     if (wp->w_cmdline == row1) {
  151.         unsigned savecho;
  152.  
  153.         savecho = echo;
  154.         echo &= ~e_CHARUPDATE;
  155.  
  156.         (void) move_sline(wp, row2 - row1);
  157.  
  158.         echo = savecho;
  159.  
  160.         move_cursor_to_window(curwin);
  161.         update_all();
  162.         cursupdate(curwin);
  163.         wind_goto(curwin);
  164.     }
  165.     }
  166. }
  167.  
  168. /*
  169.  * This function is called by the (obviously machine-dependent) mouse
  170.  * event handling code when a mouse button is pressed & released.
  171.  *
  172.  * The algorithm we use here is semantically complicated, but seems to
  173.  * be fairly intuitive in actual use.
  174.  */
  175. void
  176. mouseclick(row, col)
  177. register int    row;    /* row the mouse cursor is in */
  178. int        col;    /* column the mouse cursor is in */
  179. {
  180.     register Xviwin    *wp;
  181.  
  182.     if (State != NORMAL) {
  183.     return;
  184.     }
  185.  
  186.     /*
  187.      * First find which window the mouse is in.
  188.      */
  189.     if ((wp = findwin(row)) == NULL) {
  190.     /*
  191.      * This can't happen.
  192.      */
  193.     return;
  194.     }
  195.  
  196.     if (wp != curwin) {
  197.     /*
  198.      * The window the mouse is in isn't the current window.
  199.      * Make it the current window.
  200.      */
  201.     curwin = wp;
  202.     curbuf = wp->w_buffer;
  203.     }
  204.  
  205.     if (row == wp->w_cmdline) {
  206.     /*
  207.      * If the mouse is on the status line of any window,
  208.      * we update the information on the status line. This
  209.      * applies whether or not it was already the current
  210.      * window.
  211.      */
  212.     show_file_info(wp);
  213.     } else {
  214.     /*
  215.      * Move the cursor as near as possible to where the
  216.      * mouse was clicked.
  217.      */
  218.     setcursor(wp, row, col);
  219.  
  220.     /*
  221.      * If the window has at least 2 text rows, and ...
  222.      */
  223.     if (wp->w_nrows > 2) {
  224.         if (row == wp->w_winpos) {
  225.         /*
  226.          * ... we're on the top line of the
  227.          * window - scroll down ...
  228.          */
  229.         scrolldown(wp, (unsigned) 1);
  230.         update_window(wp);
  231.         } else if (row == wp->w_cmdline - 1) {
  232.         /*
  233.          * ... or we're on the bottom line of
  234.          * the window - scroll up ...
  235.          */
  236.         scrollup(wp, (unsigned) 1);
  237.         update_window(wp);
  238.         }
  239.     }
  240.     }
  241.  
  242.     /*
  243.      * Make sure physical screen and cursor position are updated.
  244.      */
  245.     cursupdate(wp);
  246.     wind_goto(wp);
  247. }
  248.