home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / C / Samples / CSAPE32.ARJ / SOURCE / OWLSCR / WINMOUSE.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-09-24  |  8.2 KB  |  261 lines

  1. /*
  2.     winmouse.c    11/16/88
  3.  
  4.     % window mouse functions.
  5.     by Ted.
  6.  
  7.     OWL 1.2
  8.     Copyright (c) 1988, by Oakland Group, Inc.
  9.     ALL RIGHTS RESERVED.
  10.  
  11.     Revision History:
  12.     -----------------
  13.      3/25/89 ted    Made Dclick & Holddown use CheckEventWait calls.
  14.      3/31/89 ted:    Extracted wmgr_PointWin to winobsc.c
  15.  
  16.     11/01/89 jdc    added check for mouse event in win_MouseHoldDownTime
  17.     11/29/89 jmd    added casts for DG
  18.     12/07/89 ted    Fixed win_MouseHoldDownTime to return a keystrokes too.
  19.     12/07/89 ted    Fixed win_MouseDblClick to check for KEY_NONE.
  20.      3/28/90 jmd    ansi-fied
  21.      5/12/90 jmd     preened, Changed scancodes to ints
  22.      6/10/90 ted    Changed win-NULL error ret vals from 0 to KEY_NONE.
  23.      8/21/90 ted    Added description for MouseCurrEvent function.
  24.      8/30/90 ted    Added wmgr_EvClaim/EvRelease asserts.
  25.      9/23/90 ted    Changed CurrMouseEvent to use currmev instead of lastmev.
  26.      9/23/90 ted    Made ReadEvent set mev flags as well as x, y, & event.
  27. */
  28.  
  29. #include "oakhead.h"
  30. #include "disppriv.h"
  31. #include "digutil.h"
  32. #include "scancode.h"    /* for mouse pseudo-scancodes */
  33.  
  34. OSTATIC boolean OWLPRIV moveout(mev_struct *firstmev, mev_struct *currmev);
  35.  
  36. /* -------------------------------------------------------------------------- */
  37.  
  38. int win_ReadEvent(win_type win, mev_struct *mev)
  39. /*
  40.     Use this function inside a mouse handler when you want to keep control
  41.     and receive mouse coordinates that can range outside of your window.
  42.     NOTE: your window is not asked to accept the events.
  43. */
  44. {
  45.     moupos_struct moupos;
  46.     int evcode;
  47.     opcoord tx, ty;
  48.  
  49.     owl_Assert(wmgr_EvClaim(1), OE_WM_REENTER); /* Here for re-entrancy protection */
  50.  
  51.     if (win == NULL) {
  52.         owl_Assert(wmgr_EvRelease(1), OE_WM_REENTER);
  53.         return(KEY_NONE);
  54.     }
  55.     if ((evcode = hard_ReadEvent(&moupos)) == HARD_MEV) {
  56.         memmove((VOID *)wmgr_lastmoupos(),
  57.                 (VOID *)&moupos, sizeof(moupos_struct));
  58.  
  59.         /* Make the mouse coords relative to the window */
  60.         mev->win = win;
  61.         mev->x = moupos.x - win_GetXmin(win);
  62.         mev->y = moupos.y - win_GetYmin(win);
  63.         mev->event = moupos.event;
  64.  
  65.         mev->incurrent = (disp_GetCurrentWin() == win);
  66.         mev->outside = (opbox_clippoint(win_pixboxp(win), &moupos.x, &moupos.y) != 0);
  67.         tx = mev->x; ty = mev->y;
  68.         mev->inborder = (mev->outside) ? FALSE : (win_clippoint(win, &tx, &ty) != 0);
  69.  
  70.         owl_Assert(wmgr_EvRelease(1), OE_WM_REENTER);
  71.         return(MOU_EVENT);
  72.     }
  73.     else {
  74.         owl_Assert(wmgr_EvRelease(1), OE_WM_REENTER);
  75.         return(evcode);
  76.     }
  77. }
  78. /* -------------------------------------------------------------------------- */
  79.  
  80. boolean win_MouseCurrEvent(mev_struct *mev)
  81. /*
  82.     In mev structure, return the mouse event that was most recently sent to any
  83.     window.
  84.     If the window the event was sent to no longer exists, the return
  85.     value is FALSE and the mev contents are not valid.
  86. */
  87. {
  88.     if (!win_Ok(wmgr_currmev()->win)) {
  89.         return(FALSE);
  90.     }
  91.     memmove((VOID *) mev, (VOID *) wmgr_currmev(), sizeof(mev_struct));
  92.  
  93.     return(TRUE);
  94. }
  95. /* -------------------------------------------------------------------------- */
  96.  
  97. int win_MouseHoldDownTime(win_type win, mev_struct *mev, unsigned duration)
  98. /*
  99.     Returns MOU_HOLDDOWN if a mouse button stays pressed for 'duration'
  100.     hundredths of a second.    If duration is 0, the default mouse timeout is used.
  101.     If a keystroke is gotten, this function returns immediately with the
  102.     scancode value.
  103.     On return, mev contains the last recorded mouse event.
  104.     If no mouse events occur while control is in this function, mev is unaltered.
  105. */
  106. {
  107.     unsigned itime, ttime, tdiff;
  108.     mev_struct firstmev;
  109.     int evcode;
  110.  
  111.     owl_Assert(wmgr_EvClaim(2), OE_WM_REENTER); /* Here for re-entrancy protection */
  112.  
  113.     if (win == NULL) {
  114.         owl_Assert(wmgr_EvRelease(2), OE_WM_REENTER);
  115.         return(KEY_NONE);
  116.     }
  117. /* Wait a while for any button to go up */
  118.     firstmev.event = TRUE;    /* use firstmev.event as a first-flag */
  119.     if (duration != (unsigned)-1) {
  120.         itime = hard_Timer();
  121.     }
  122.     for (;;) {
  123.         /* Check first in case no events pending */
  124.         if (win_CheckEventWait(win, duration) != KEY_NONE) {
  125.             if ((evcode = win_ReadEvent(win, mev)) == MOU_EVENT) {
  126.  
  127.                 if (moveout(&firstmev, mev)) {
  128.                     break;    /* return MOU_EVENT */
  129.                 }
  130.                 if (!mev_IsButtonDown(mev)) {
  131.                     break;    /* return MOU_EVENT */
  132.                 }
  133.             }
  134.             else {
  135.                 break;        /* return Keystroke */
  136.             }
  137.         }
  138.         else {
  139.             owl_Assert(wmgr_EvRelease(2), OE_WM_REENTER);
  140.             return(MOU_HOLDDOWN); /* time expired with no event */
  141.         }
  142.  
  143.         /* Going around again - reduce wait duration by what has now elapsed */
  144.         if (duration != (unsigned) -1) {
  145.             /* Note: this block of code should be made atomic somehow */
  146.             ttime = hard_Timer();
  147.             /* Double check in case time has now expired */
  148.             if ((tdiff = dig_SubHsecs(itime, ttime)) > duration) {
  149.                 owl_Assert(wmgr_EvRelease(2), OE_WM_REENTER);
  150.                 return(MOU_HOLDDOWN);    /* Hold-down */
  151.             }
  152.             duration -= tdiff;
  153.             itime = ttime;
  154.         }
  155.     }
  156.     owl_Assert(wmgr_EvRelease(2), OE_WM_REENTER);
  157.     return(evcode);
  158. }
  159. /* -------------------------------------------------------------------------- */
  160.  
  161. int win_MouseDblClick(win_type win, mev_struct *mev)
  162. /*
  163.     Returns MOU_DCLICK if a fresh button press event is detected within the
  164.     disp_MouseTimeout() interval (a few fractions of a second).
  165.     Returns MOU_HOLDDOWN if at least one button is down during the whole
  166.     interval, or if no button release event is ever detected.
  167.     (It is assumed that you call this function after a button press event.)
  168.     If a keystroke is gotten, this function returns immediately with the
  169.     scancode value.
  170.     On return, mev contains the last recorded mouse event.
  171.     If no mouse event occurs before the interval expires, mev is unaltered.
  172. */
  173. {
  174.     unsigned itime, ttime, tdiff;
  175.     unsigned duration;
  176.     mev_struct firstmev;
  177.     unsigned oldevent;
  178.     int evcode;
  179.     boolean stillheld;
  180.  
  181.     owl_Assert(wmgr_EvClaim(2), OE_WM_REENTER); /* Here for re-entrancy protection */
  182.  
  183.     if (win == NULL) {
  184.         owl_Assert(wmgr_EvRelease(2), OE_WM_REENTER);
  185.         return(KEY_NONE);
  186.     }
  187. /* Start as if all buttons were pressed */
  188.     oldevent = (MEV_BUT1 | MEV_BUT2 | MEV_BUT3);
  189.     stillheld = TRUE;        /* assume function was called w/ button down */
  190.  
  191. /* Wait a while for any button to go up and then get pressed again */
  192.     duration = disp_MouseTimeout();
  193.     firstmev.event = TRUE;    /* use firstmev.event as a first-flag */
  194.     itime = hard_Timer();
  195.  
  196.     for (;;) {
  197.         /* Check first in case no events pending */
  198.         if (win_CheckEventWait(win, duration) != KEY_NONE) {
  199.             if ((evcode = win_ReadEvent(win, mev)) == MOU_EVENT) {
  200.  
  201.                 if (moveout(&firstmev, mev)) {
  202.                     owl_Assert(wmgr_EvRelease(2), OE_WM_REENTER);
  203.                     return(MOU_EVENT);    /* Too much motion */
  204.                 }
  205.                 if (mev_ButtonGoneDown(oldevent, mev->event)) {
  206.                     owl_Assert(wmgr_EvRelease(2), OE_WM_REENTER);
  207.                     return(MOU_DCLICK);    /* Double click */
  208.                 }
  209.                 if (!mev_IsButtonDown(mev)) {
  210.                     stillheld = FALSE;    /* clear hold-down flag */
  211.                 }
  212.                 oldevent = mev->event;
  213.             }
  214.             else {
  215.                 owl_Assert(wmgr_EvRelease(2), OE_WM_REENTER);
  216.                 return(evcode);    /* return Keystroke */
  217.             }
  218.         }
  219.         else {
  220.             owl_Assert(wmgr_EvRelease(2), OE_WM_REENTER);
  221.             return(MOU_HOLDDOWN); /* time expired with no event */
  222.         }
  223.  
  224.         /* Going around again - reduce wait duration by what has now elapsed */
  225.         /* Note: this block of code should be made atomic somehow */
  226.         ttime = hard_Timer();
  227.         /* Double check in case time has now expired */
  228.         if ((tdiff = dig_SubHsecs(itime, ttime)) > duration) {
  229.             if (stillheld) {
  230.                 owl_Assert(wmgr_EvRelease(2), OE_WM_REENTER);
  231.                 return(MOU_HOLDDOWN);    /* Hold-down */
  232.             }
  233.             else {
  234.                 owl_Assert(wmgr_EvRelease(2), OE_WM_REENTER);
  235.                 return(MOU_EVENT);        /* Timeout w/ button up */
  236.             }
  237.             /* Note: if stillheld is FALSE, a mouse event must have occurred */
  238.         }
  239.         duration -= tdiff;
  240.         itime = ttime;
  241.     }
  242. }
  243. /* -------------------------------------------------------------------------- */
  244.  
  245. static boolean OWLPRIV moveout(mev_struct *firstmev, mev_struct *currmev)
  246. /*
  247.     Returns TRUE if the mouse position moved too far.
  248. */
  249. {
  250.     if (firstmev->event) {
  251.         firstmev->x = currmev->x; firstmev->y = currmev->y;
  252.         firstmev->event = FALSE;
  253.         return(FALSE);
  254.     }
  255.     else {
  256.         return(mev_MovedOut(firstmev, currmev, disp_MouseDistout()));
  257.     }
  258. }
  259. /* -------------------------------------------------------------------------- */
  260.  
  261.