home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / pc / memacs / ue311c.arc / MOUSE.C < prev    next >
C/C++ Source or Header  |  1990-08-16  |  10KB  |  439 lines

  1. /*    MOUSE.C:    Mouse functionality commands
  2.             for MicroEMACS 3.10
  3.             originally written by Dave G. Conroy
  4.             modified by Jeff Lomicka and Daniel Lawrence
  5. */
  6.  
  7. #include    <stdio.h>
  8. #include    "estruct.h"
  9. #include    "eproto.h"
  10. #include        "edef.h"
  11. #include    "elang.h"
  12.  
  13. #define    MNONE    0            /* Mouse commands.        */
  14. #define    MMOVE    1
  15. #define    MREG    2
  16.  
  17. #if    MOUSE
  18. NOSHARE int    lastypos = HUGE;    /* Last mouse event row.    */
  19. NOSHARE int    lastxpos = HUGE;    /* Last mouse event column.    */
  20. NOSHARE int    lastmcmd = MNONE;    /* Last mouse command.        */
  21.  
  22. /*
  23.  * Move mouse button, down. The window that the
  24.  * mouse is in is always selected (this lets you select a
  25.  * window by clicking anyplace in it, even off the end
  26.  * of the text). If the mouse points at text then dot is
  27.  * moved to that location.
  28.  */
  29. PASCAL NEAR movemd(f, n)
  30.  
  31. int f,n;    /* prefix flag and argument */
  32.  
  33. {
  34.     register WINDOW    *wp;
  35.     register WINDOW    *lastwp;
  36.     register LINE    *lp;
  37.  
  38.     /* if anything has changed, reset the click count */
  39.     if (lastmcmd != MMOVE || lastypos!=ypos || lastxpos!=xpos)
  40.         nclicks = 0;
  41.     ++nclicks;
  42.     lastwp = mousewindow(lastypos);        /* remember least window */
  43.  
  44.     /* reset the last position */
  45.     lastypos = ypos;
  46.     lastxpos = xpos;
  47.     lastmcmd = MMOVE;
  48.  
  49.     /* if we move the mouse off the windows, don't move anything */
  50.     if ((wp=mousewindow(ypos)) == NULL)
  51.         return(FALSE);
  52.  
  53.     /* if we are on the line with the point, adjust for extended lines */
  54.     if (wp == curwp && (lp = mouseline(wp, ypos)) == curwp->w_dotp)
  55.         xpos += lbound;
  56.  
  57.     /* make the window the mouse points to current */
  58.     curwp = wp;
  59.     curbp = wp->w_bufp;
  60.  
  61.     /* if we changed windows, update the modelines */
  62.     if (wp != lastwp)
  63.         upmode();
  64.  
  65.     /* if we aren't off the end of the text, move the point to the mouse */
  66.     if ((lp=mouseline(wp, ypos)) != NULL) {
  67.         curwp->w_dotp = lp;
  68.         curwp->w_doto = mouseoffset(wp, lp, xpos);
  69.     }
  70.  
  71.     return(TRUE);
  72. }
  73.  
  74.  
  75. /*    mouse-region-down:    mouse region operations
  76.  
  77.     nclicks = 0:    move cursor to mouse
  78.             set-mark
  79.  
  80.           1:    move cursor to mouse
  81.             kill-region
  82. */
  83.  
  84. PASCAL NEAR mregdown(f, n)
  85.  
  86. int f,n;    /* prefix flag and argument */
  87.  
  88. {
  89.     register WINDOW    *wp;
  90.     register WINDOW    *lastwp;
  91.     register LINE    *lp;
  92.  
  93.     /* if anything has changed, reset the click count */
  94.     if (lastmcmd != MREG || lastypos != ypos || lastxpos != xpos)
  95.         nclicks = 0;
  96.     ++nclicks;
  97.     lastwp = mousewindow(lastypos);        /* remember least window */
  98.  
  99.     /* reset the last position */
  100.     lastypos = ypos;
  101.     lastxpos = xpos;
  102.     lastmcmd = MREG;
  103.  
  104.     /* if we move the mouse off the windows, don't move anything */
  105.     if ((wp=mousewindow(ypos)) == NULL)
  106.         return(FALSE);
  107.  
  108.     /* if we are on the line with the point, adjust for extended lines */
  109.     if (wp == curwp && (lp = mouseline(wp, ypos)) == curwp->w_dotp)
  110.         xpos += lbound;
  111.  
  112.     /* make the window the mouse points to current */
  113.     curwp = wp;
  114.     curbp = wp->w_bufp;
  115.  
  116.     /* if we changed windows, update the modelines */
  117.     if (wp != lastwp)
  118.         upmode();
  119.  
  120.     /* if we aren't off the end of the text, move the point to the mouse */
  121.     if ((lp=mouseline(wp, ypos)) != NULL) {
  122.         curwp->w_dotp = lp;
  123.         curwp->w_doto = mouseoffset(wp, lp, xpos);
  124.     }
  125.  
  126.     /* perform the region function */
  127.     if (nclicks == 1) {
  128.         return(setmark(FALSE, 0));
  129.     } else {
  130.         lastflag &= ~CFKILL;
  131.         return(killregion(FALSE, 0));
  132.     }
  133. }
  134.  
  135. /*    mouse-region-up:    mouse region operations
  136.  
  137.     If the corrosponding downclick was on a modeline, then we
  138.     wish to delete the indicated window. Otherwise we are using
  139.     this button to copy/paste.
  140.  
  141.     nclicks = 0:    move cursor to mouse
  142.             copy-region
  143.  
  144.           1:    move cursor to mouse
  145.             yank
  146.  
  147.           3:    reset nclicks to 0
  148. */
  149.  
  150. PASCAL NEAR mregup(f, n)
  151.  
  152. int f,n;    /* prefix flag and argument */
  153.  
  154. {
  155.     register WINDOW    *wp;
  156.     register WINDOW    *lastwp;
  157.     register LINE *lp;
  158.     register int lastmodeline;    /* was the dowbclick on a modeline? */
  159.  
  160.     /* if anything has changed, reset the click count */
  161.     if (lastmcmd != MREG || lastypos != ypos || lastxpos != xpos)
  162.         nclicks = 0;
  163.     ++nclicks;
  164.     lastwp = mousewindow(lastypos);        /* remember least window */
  165.  
  166.     /* did we down click on a modeline? */
  167.     lastmodeline = ismodeline(lastwp, lastypos);
  168.  
  169.     /* reset the last position */
  170.     lastypos = ypos;
  171.     lastxpos = xpos;
  172.     lastmcmd = MREG;
  173.  
  174.     /* if we started on a modeline.... */
  175.     if (lastmodeline)
  176.         return(delwind(TRUE, 0));
  177.  
  178.     /* if we move the mouse off the windows, don't move anything */
  179.     if ((wp=mousewindow(ypos)) == NULL)
  180.         return(FALSE);
  181.  
  182.     /* if we are on the line with the point, adjust for extended lines */
  183.     if (wp == curwp && (lp = mouseline(wp, ypos)) == curwp->w_dotp)
  184.         xpos += lbound;
  185.  
  186.     /* make the window the mouse points to current */
  187.     curwp = wp;
  188.     curbp = wp->w_bufp;
  189.  
  190.     /* if we aren't off the end of the text, move the point to the mouse */
  191.     if ((lp=mouseline(wp, ypos)) != NULL && nclicks < 3) {
  192.         curwp->w_dotp = lp;
  193.         curwp->w_doto = mouseoffset(wp, lp, xpos);
  194.     }
  195.  
  196.     /* if we changed windows, update the modelines, abort the new op */
  197.     if (wp != lastwp) {
  198.         upmode();
  199.         return(TRUE);
  200.     }
  201.  
  202.     /* perform the region function */
  203.     if (nclicks == 1) {
  204.         return(copyregion(FALSE, 0));
  205.     } else if (nclicks == 2) {
  206.         return(yank(FALSE, 1));
  207.     } else {
  208.         nclicks = 0;
  209.         return(TRUE);
  210.     }
  211. }
  212.  
  213. /*
  214.  * Move mouse button, up. The up click must be
  215.  * in the text region of a window. If the old click was in a
  216.  * mode line then the mode line moves to the row of the
  217.  * up click. If the old click is not in a mode line then the
  218.  * window scrolls. The code in this function is just
  219.  * too complex!
  220.  */
  221. PASCAL NEAR movemu(f, n)
  222.  
  223. int f,n;    /* prefix flag and argument */
  224.  
  225. {
  226.     register WINDOW    *lastwp;
  227.     register WINDOW    *wp;
  228.     register int    lastmodeline;    /* was the dowbclick on a modeline? */
  229.     register int    deltay;
  230.     register int    deltax;
  231.  
  232.     /* no movement... fail the command */
  233.     if (lastypos==ypos && lastxpos==xpos)
  234.         return(FALSE);
  235.  
  236.     /* if the down click was in the bottom right corner...
  237.        then we are resizing */
  238.     if (lastypos == term.t_nrow && lastxpos + 1 == term.t_ncol) {
  239.         (*term.t_eeop)();
  240.         newwidth(TRUE, xpos + 1);
  241.         newsize(TRUE, ypos + 1);
  242.         return(TRUE);
  243.     }
  244.  
  245.     /* if the down click was not in a window.. fail the command
  246.        (for example, if we click on the command line) */
  247.     if ((lastwp=mousewindow(lastypos)) == NULL)
  248.         return(FALSE);
  249.  
  250.     /* did we down click on a modeline? */
  251.     lastmodeline = ismodeline(lastwp, lastypos);
  252.  
  253.     /* are we not in a window? fail it then */
  254.     if ((wp=mousewindow(ypos)) == NULL)
  255.         return(FALSE);
  256.  
  257.     /* how far did we move? */
  258.     deltay = lastypos-ypos;
  259.     deltax = lastxpos-xpos;
  260.     lastypos = ypos;
  261.     lastxpos = xpos;
  262.  
  263.     /* if we started on a modeline.... */
  264.     if (lastmodeline) {
  265.  
  266.         /* move the window horizontally */
  267.         if (deltax != 0 && (diagflag || deltay == 0)) {
  268.             lastwp->w_fcol += deltax;
  269.             if (lastwp->w_fcol < 0)
  270.                 lastwp->w_fcol = 0;
  271.             lastwp->w_flag |= WFMODE|WFHARD;
  272.             if (deltay == 0)
  273.                 return(TRUE);
  274.         }
  275.  
  276.         /* don't allow the bottom modeline to move */
  277.         if (lastwp->w_wndp == NULL)
  278.             return(FALSE);
  279.  
  280.         /* shrink the current window */
  281.         if (deltay > 0) {
  282.             if (lastwp != wp)
  283.                 return(FALSE);
  284.             curwp = wp;
  285.             curbp = wp->w_bufp;
  286.             return(shrinkwind(TRUE, deltay));
  287.         }
  288.  
  289.         /* or grow it */
  290.         if (deltay < 0) {
  291.             if (wp != lastwp->w_wndp)
  292.                 return(FALSE);
  293.             curwp = lastwp;
  294.             curbp = lastwp->w_bufp;
  295.             return(enlargewind(TRUE, -deltay));
  296.         }
  297.     }
  298.  
  299.     /* did we up click in a modeline? fail it them */
  300.     if (ismodeline(wp, ypos) != FALSE)
  301.         return(FALSE);
  302.  
  303.     /* we can not move outside the current window */
  304.     if (lastwp != wp)
  305.         return(FALSE);
  306.  
  307.     /* move horizontally as well? */
  308.     if (deltax != 0 && (diagflag || deltay == 0)) {
  309.         wp->w_fcol += deltax;
  310.         if (wp->w_fcol < 0)
  311.             wp->w_fcol = 0;
  312.         wp->w_flag |= WFMODE;
  313.     }
  314.  
  315.     /* and move the screen */
  316.     return(mvdnwind(TRUE, deltay));
  317. }
  318.  
  319. /*
  320.  * Return a pointer to the WINDOW structure
  321.  * for the window in which "row" is located, or NULL
  322.  * if "row" isn't in any window. The mode line is
  323.  * considered to be part of the window.
  324.  */
  325.  
  326. WINDOW *PASCAL NEAR mousewindow(row)
  327.  
  328. register int    row;
  329.  
  330. {
  331.     register WINDOW    *wp;
  332.  
  333.     wp = wheadp;
  334.     while (wp != NULL) {
  335.         if (row < wp->w_ntrows+1)
  336.             return(wp);
  337.         row -= wp->w_ntrows+1;
  338.         wp = wp->w_wndp;
  339.     }
  340.     return(NULL);
  341. }
  342.  
  343. /*
  344.  * The row "row" is a row within the window
  345.  * whose WINDOW structure is pointed to by the "wp"
  346.  * argument. Find the associated line, and return a pointer
  347.  * to it. Return NULL if the mouse is on the mode line,
  348.  * or if the mouse is pointed off the end of the
  349.  * text in the buffer.
  350.  */
  351.  
  352. LINE *PASCAL NEAR mouseline(wp, row)
  353.  
  354. register WINDOW    *wp;
  355. register int    row;
  356.  
  357. {
  358.     register LINE    *lp;
  359.  
  360.     row -= wp->w_toprow;
  361.     if (row >= wp->w_ntrows)
  362.         return(NULL);
  363.     lp = wp->w_linep;
  364.     while (row--) {
  365.         if (lp == wp->w_bufp->b_linep)    /* Hit the end.        */
  366.             return(NULL);
  367.         lp = lforw(lp);
  368.     }
  369.     return(lp);
  370. }
  371.  
  372. /*
  373.  * Return the best character offset to use
  374.  * to describe column "col", as viewed from the line whose
  375.  * LINE structure is pointed to by "lp".
  376.  */
  377.  
  378. PASCAL NEAR mouseoffset(wp, lp, col)
  379.  
  380. register WINDOW *wp;
  381. register LINE    *lp;
  382. register int    col;
  383.  
  384. {
  385.     register int    c;
  386.     register int    offset;
  387.     register int    curcol;
  388.     register int    newcol;
  389.  
  390.     offset = 0;
  391.     curcol = 0;
  392.     col += wp->w_fcol;    /* adjust for extended lines */
  393.     while (offset != llength(lp)) {
  394.         newcol = curcol;
  395.         if ((c=lgetc(lp, offset)) == '\t')
  396.             newcol += -(newcol % tabsize) + (tabsize - 1);
  397.         else if (c<32)    /* ISCTRL */
  398.             ++newcol;
  399.         ++newcol;
  400.         if (newcol > col)
  401.             break;
  402.         curcol = newcol;
  403.         ++offset;
  404.     }
  405.     return(offset);
  406. }
  407.  
  408. PASCAL NEAR ismodeline(wp, row)
  409.  
  410. WINDOW    *wp;
  411. int row;
  412.  
  413. {
  414.     if (row == wp->w_toprow+wp->w_ntrows && modeflag)
  415.         return(TRUE);
  416.     return(FALSE);
  417. }
  418.  
  419. /* The mouse has been used to resize the physical window. Now we need to
  420.    let emacs know about the newsize, and have him force a re-draw
  421. */
  422.  
  423. PASCAL NEAR resizm(f, n)
  424.  
  425. int f, n;    /* these are ignored... we get the new size info from
  426.            the mouse driver */
  427. {
  428.     (*term.t_eeop)();
  429.     newwidth(TRUE, xpos);
  430.     newsize(TRUE, ypos);
  431.     return(TRUE);
  432. }
  433.  
  434. #else
  435. mousehello()
  436. {
  437. }
  438. #endif
  439.