home *** CD-ROM | disk | FTP | other *** search
- /*
- winmouse.c 11/16/88
-
- % window mouse functions.
- by Ted.
-
- OWL 1.2
- Copyright (c) 1988, by Oakland Group, Inc.
- ALL RIGHTS RESERVED.
-
- Revision History:
- -----------------
- 3/25/89 ted Made Dclick & Holddown use CheckEventWait calls.
- 3/31/89 ted: Extracted wmgr_PointWin to winobsc.c
-
- 11/01/89 jdc added check for mouse event in win_MouseHoldDownTime
- 11/29/89 jmd added casts for DG
- 12/07/89 ted Fixed win_MouseHoldDownTime to return a keystrokes too.
- 12/07/89 ted Fixed win_MouseDblClick to check for KEY_NONE.
- 3/28/90 jmd ansi-fied
- 5/12/90 jmd preened, Changed scancodes to ints
- 6/10/90 ted Changed win-NULL error ret vals from 0 to KEY_NONE.
- 8/21/90 ted Added description for MouseCurrEvent function.
- 8/30/90 ted Added wmgr_EvClaim/EvRelease asserts.
- 9/23/90 ted Changed CurrMouseEvent to use currmev instead of lastmev.
- 9/23/90 ted Made ReadEvent set mev flags as well as x, y, & event.
- */
-
- #include "oakhead.h"
- #include "disppriv.h"
- #include "digutil.h"
- #include "scancode.h" /* for mouse pseudo-scancodes */
-
- OSTATIC boolean OWLPRIV moveout(mev_struct *firstmev, mev_struct *currmev);
-
- /* -------------------------------------------------------------------------- */
-
- int win_ReadEvent(win_type win, mev_struct *mev)
- /*
- Use this function inside a mouse handler when you want to keep control
- and receive mouse coordinates that can range outside of your window.
- NOTE: your window is not asked to accept the events.
- */
- {
- moupos_struct moupos;
- int evcode;
- opcoord tx, ty;
-
- owl_Assert(wmgr_EvClaim(1), OE_WM_REENTER); /* Here for re-entrancy protection */
-
- if (win == NULL) {
- owl_Assert(wmgr_EvRelease(1), OE_WM_REENTER);
- return(KEY_NONE);
- }
- if ((evcode = hard_ReadEvent(&moupos)) == HARD_MEV) {
- memmove((VOID *)wmgr_lastmoupos(),
- (VOID *)&moupos, sizeof(moupos_struct));
-
- /* Make the mouse coords relative to the window */
- mev->win = win;
- mev->x = moupos.x - win_GetXmin(win);
- mev->y = moupos.y - win_GetYmin(win);
- mev->event = moupos.event;
-
- mev->incurrent = (disp_GetCurrentWin() == win);
- mev->outside = (opbox_clippoint(win_pixboxp(win), &moupos.x, &moupos.y) != 0);
- tx = mev->x; ty = mev->y;
- mev->inborder = (mev->outside) ? FALSE : (win_clippoint(win, &tx, &ty) != 0);
-
- owl_Assert(wmgr_EvRelease(1), OE_WM_REENTER);
- return(MOU_EVENT);
- }
- else {
- owl_Assert(wmgr_EvRelease(1), OE_WM_REENTER);
- return(evcode);
- }
- }
- /* -------------------------------------------------------------------------- */
-
- boolean win_MouseCurrEvent(mev_struct *mev)
- /*
- In mev structure, return the mouse event that was most recently sent to any
- window.
- If the window the event was sent to no longer exists, the return
- value is FALSE and the mev contents are not valid.
- */
- {
- if (!win_Ok(wmgr_currmev()->win)) {
- return(FALSE);
- }
- memmove((VOID *) mev, (VOID *) wmgr_currmev(), sizeof(mev_struct));
-
- return(TRUE);
- }
- /* -------------------------------------------------------------------------- */
-
- int win_MouseHoldDownTime(win_type win, mev_struct *mev, unsigned duration)
- /*
- Returns MOU_HOLDDOWN if a mouse button stays pressed for 'duration'
- hundredths of a second. If duration is 0, the default mouse timeout is used.
- If a keystroke is gotten, this function returns immediately with the
- scancode value.
- On return, mev contains the last recorded mouse event.
- If no mouse events occur while control is in this function, mev is unaltered.
- */
- {
- unsigned itime, ttime, tdiff;
- mev_struct firstmev;
- int evcode;
-
- owl_Assert(wmgr_EvClaim(2), OE_WM_REENTER); /* Here for re-entrancy protection */
-
- if (win == NULL) {
- owl_Assert(wmgr_EvRelease(2), OE_WM_REENTER);
- return(KEY_NONE);
- }
- /* Wait a while for any button to go up */
- firstmev.event = TRUE; /* use firstmev.event as a first-flag */
- if (duration != (unsigned)-1) {
- itime = hard_Timer();
- }
- for (;;) {
- /* Check first in case no events pending */
- if (win_CheckEventWait(win, duration) != KEY_NONE) {
- if ((evcode = win_ReadEvent(win, mev)) == MOU_EVENT) {
-
- if (moveout(&firstmev, mev)) {
- break; /* return MOU_EVENT */
- }
- if (!mev_IsButtonDown(mev)) {
- break; /* return MOU_EVENT */
- }
- }
- else {
- break; /* return Keystroke */
- }
- }
- else {
- owl_Assert(wmgr_EvRelease(2), OE_WM_REENTER);
- return(MOU_HOLDDOWN); /* time expired with no event */
- }
-
- /* Going around again - reduce wait duration by what has now elapsed */
- if (duration != (unsigned) -1) {
- /* Note: this block of code should be made atomic somehow */
- ttime = hard_Timer();
- /* Double check in case time has now expired */
- if ((tdiff = dig_SubHsecs(itime, ttime)) > duration) {
- owl_Assert(wmgr_EvRelease(2), OE_WM_REENTER);
- return(MOU_HOLDDOWN); /* Hold-down */
- }
- duration -= tdiff;
- itime = ttime;
- }
- }
- owl_Assert(wmgr_EvRelease(2), OE_WM_REENTER);
- return(evcode);
- }
- /* -------------------------------------------------------------------------- */
-
- int win_MouseDblClick(win_type win, mev_struct *mev)
- /*
- Returns MOU_DCLICK if a fresh button press event is detected within the
- disp_MouseTimeout() interval (a few fractions of a second).
- Returns MOU_HOLDDOWN if at least one button is down during the whole
- interval, or if no button release event is ever detected.
- (It is assumed that you call this function after a button press event.)
- If a keystroke is gotten, this function returns immediately with the
- scancode value.
- On return, mev contains the last recorded mouse event.
- If no mouse event occurs before the interval expires, mev is unaltered.
- */
- {
- unsigned itime, ttime, tdiff;
- unsigned duration;
- mev_struct firstmev;
- unsigned oldevent;
- int evcode;
- boolean stillheld;
-
- owl_Assert(wmgr_EvClaim(2), OE_WM_REENTER); /* Here for re-entrancy protection */
-
- if (win == NULL) {
- owl_Assert(wmgr_EvRelease(2), OE_WM_REENTER);
- return(KEY_NONE);
- }
- /* Start as if all buttons were pressed */
- oldevent = (MEV_BUT1 | MEV_BUT2 | MEV_BUT3);
- stillheld = TRUE; /* assume function was called w/ button down */
-
- /* Wait a while for any button to go up and then get pressed again */
- duration = disp_MouseTimeout();
- firstmev.event = TRUE; /* use firstmev.event as a first-flag */
- itime = hard_Timer();
-
- for (;;) {
- /* Check first in case no events pending */
- if (win_CheckEventWait(win, duration) != KEY_NONE) {
- if ((evcode = win_ReadEvent(win, mev)) == MOU_EVENT) {
-
- if (moveout(&firstmev, mev)) {
- owl_Assert(wmgr_EvRelease(2), OE_WM_REENTER);
- return(MOU_EVENT); /* Too much motion */
- }
- if (mev_ButtonGoneDown(oldevent, mev->event)) {
- owl_Assert(wmgr_EvRelease(2), OE_WM_REENTER);
- return(MOU_DCLICK); /* Double click */
- }
- if (!mev_IsButtonDown(mev)) {
- stillheld = FALSE; /* clear hold-down flag */
- }
- oldevent = mev->event;
- }
- else {
- owl_Assert(wmgr_EvRelease(2), OE_WM_REENTER);
- return(evcode); /* return Keystroke */
- }
- }
- else {
- owl_Assert(wmgr_EvRelease(2), OE_WM_REENTER);
- return(MOU_HOLDDOWN); /* time expired with no event */
- }
-
- /* Going around again - reduce wait duration by what has now elapsed */
- /* Note: this block of code should be made atomic somehow */
- ttime = hard_Timer();
- /* Double check in case time has now expired */
- if ((tdiff = dig_SubHsecs(itime, ttime)) > duration) {
- if (stillheld) {
- owl_Assert(wmgr_EvRelease(2), OE_WM_REENTER);
- return(MOU_HOLDDOWN); /* Hold-down */
- }
- else {
- owl_Assert(wmgr_EvRelease(2), OE_WM_REENTER);
- return(MOU_EVENT); /* Timeout w/ button up */
- }
- /* Note: if stillheld is FALSE, a mouse event must have occurred */
- }
- duration -= tdiff;
- itime = ttime;
- }
- }
- /* -------------------------------------------------------------------------- */
-
- static boolean OWLPRIV moveout(mev_struct *firstmev, mev_struct *currmev)
- /*
- Returns TRUE if the mouse position moved too far.
- */
- {
- if (firstmev->event) {
- firstmev->x = currmev->x; firstmev->y = currmev->y;
- firstmev->event = FALSE;
- return(FALSE);
- }
- else {
- return(mev_MovedOut(firstmev, currmev, disp_MouseDistout()));
- }
- }
- /* -------------------------------------------------------------------------- */
-