mouse.c

Go to the documentation of this file.
00001 
00002 /*  $Id: mouse.c 1206 2006-04-05 23:21:19Z karstenw $    */
00003 
00004 /******************************************************************************
00005 
00006     UserLand Frontier(tm) -- High performance Web content management,
00007     object database, system-level and Internet scripting environment,
00008     including source code editing and debugging.
00009 
00010     Copyright (C) 1992-2004 UserLand Software, Inc.
00011 
00012     This program is free software; you can redistribute it and/or modify
00013     it under the terms of the GNU General Public License as published by
00014     the Free Software Foundation; either version 2 of the License, or
00015     (at your option) any later version.
00016 
00017     This program is distributed in the hope that it will be useful,
00018     but WITHOUT ANY WARRANTY; without even the implied warranty of
00019     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020     GNU General Public License for more details.
00021 
00022     You should have received a copy of the GNU General Public License
00023     along with this program; if not, write to the Free Software
00024     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00025 
00026 ******************************************************************************/
00027 
00028 #include "frontier.h"
00029 #include "standard.h"
00030 
00031 #ifdef MACVERSION 
00032 #define GetDoubleClickTime() GetDblTime()
00033 #endif
00034 
00035 #include "quickdraw.h"
00036 #include "mouse.h"
00037 
00038 
00039 
00040 tymouserecord mousestatus = {0};
00041 
00042 /*static long mouseuptime = 0; 
00043 
00044 static long mousedowntime = 0; 
00045 
00046 static Point mouseuppoint = {0, 0};
00047 
00048 static Point mousedownpoint = {0, 0};
00049 
00050 static boolean fldoubleclickdisabled = false;
00051 */
00052 
00053 
00054 void setmousedoubleclickstatus (boolean fl) {
00055     mousestatus.fldoubleclick = fl;
00056     }
00057 
00058 
00059 boolean mousebuttondown (void) {
00060     
00061     /*shellbackgroundtask ();*/ /*allow tasks to hook into this bottleneck*/
00062 #ifdef MACVERSION   
00063     return (Button ());
00064 #endif
00065 #ifdef WIN95VERSION
00066     MSG msg;
00067     return (PeekMessage (&msg, NULL, WM_LBUTTONDOWN, WM_LBUTTONDOWN, PM_NOREMOVE));
00068 #endif
00069     } /*mousebuttondown*/
00070     
00071     
00072 void waitmousebutton (boolean fl) {
00073     
00074     /*
00075     wait for the mouse button to either go up or go down.
00076     
00077     if fl is true, we wait for it to go down.
00078     
00079     if fl is false, we wait for it to come back up.
00080     */
00081 #ifdef MACVERSION   
00082     while (true) {
00083         if (Button () == fl)
00084             return;
00085             
00086         /*shellbackgroundtask ();*/ /*wired off 5/9/90 -- simplifies debugging*/
00087         } /*while*/
00088 #endif
00089 #ifdef WIN95VERSION 
00090     MSG msg;
00091 
00092     while (true) {
00093         if (fl) {
00094             if (PeekMessage (&msg, NULL, WM_LBUTTONDOWN, WM_LBUTTONDOWN, PM_NOREMOVE)) {
00095                 return;
00096                 }
00097             }
00098         else {
00099             if (PeekMessage (&msg, NULL, WM_LBUTTONUP, WM_LBUTTONUP, PM_NOREMOVE)) {
00100                 return;
00101                 }
00102             }
00103                         
00104         } /*while*/
00105 #endif
00106 
00107     } /*waitmousebutton*/
00108     
00109     
00110 void waitmouseclick (void) {
00111     
00112     waitmousebutton (false);
00113     
00114     waitmousebutton (true);
00115     } /*waitmouseclick*/
00116     
00117 
00118 boolean mousestilldown (void) {
00119     
00120     /*
00121     wait for mouse button to come back up after a mousedown.  no background
00122     tasks while this is happening.  thank you!
00123     */
00124 #ifdef MACVERSION   
00125     return (StillDown ());
00126 #endif
00127 
00128 #ifdef WIN95VERSION
00129 
00130     /* getting the keystate of the mouse, gets the physical mouse, but the user may have swapped
00131        the meaning of the buttons.  We are interested in the left logical button. */
00132     if (GetSystemMetrics(SM_SWAPBUTTON)) {
00133         return ((GetAsyncKeyState(VK_RBUTTON) & 0x8000) == 0x8000);
00134         }
00135 
00136     return ((GetAsyncKeyState(VK_LBUTTON) & 0x8000) == 0x8000);
00137 #endif  
00138     } /*mousestilldown*/
00139     
00140 
00141 boolean rightmousestilldown (void) {
00142 
00143     /*
00144     7.0b26 PBS: wait for the right-mouse-button to come back up after a mousedown.
00145     */
00146 
00147 #ifdef WIN95VERSION
00148 
00149     /* getting the keystate of the mouse, gets the physical mouse, but the user may have swapped
00150        the meaning of the buttons.  We are interested in the left logical button. */
00151     if (GetSystemMetrics(SM_SWAPBUTTON)) {
00152         return ((GetAsyncKeyState(VK_LBUTTON) & 0x8000) == 0x8000);
00153         }
00154 
00155     return ((GetAsyncKeyState(VK_RBUTTON) & 0x8000) == 0x8000);
00156 #endif
00157     
00158     return (false);
00159     } /*rightmousestilldown*/
00160 
00161 void getmousepoint (Point *pt) {
00162     
00163     /*
00164     5.0a8 dmb: Win version must use current port, not the 
00165     window that happens to contain the mouse
00166     */
00167 
00168 #ifdef MACVERSION   
00169     GetMouse (pt);
00170 #endif
00171 #ifdef WIN95VERSION
00172     POINT winpt;
00173 //  RECT winrect;
00174     HWND hwnd;
00175     
00176     GetCursorPos (&winpt);
00177     
00178 //  hwnd = ChildWindowFromPointEx (hwndMDIClient , winpt, CWP_SKIPINVISIBLE | CWP_SKIPTRANSPARENT);
00179 //  hwnd = WindowFromPoint (winpt);
00180     hwnd = getport ();
00181     
00182     if (hwnd != NULL)
00183         ScreenToClient (hwnd, &winpt);
00184     
00185     (*pt).h = (short)winpt.x;
00186     (*pt).v = (short)winpt.y;
00187 #endif
00188     } /*getmousepoint*/
00189     
00190 
00191 boolean getmousewindowpos (WindowPtr *w, Point *pt) {
00192     
00193     #ifdef MACVERSION
00194         short part;
00195 
00196         GetMouse (pt);
00197 
00198         LocalToGlobal (pt);
00199 
00200         part = FindWindow (*pt, w);
00201         
00202         //Code change by Timothy Paustian Monday, August 21, 2000 4:31:49 PM
00203         //Must pass a CGrafPtr to pushport on OS X to avoid a crash
00204         {
00205         CGrafPtr    thePort;
00206         #if TARGET_API_MAC_CARBON == 1
00207         thePort = GetWindowPort(*w);
00208         #else
00209         thePort = (CGrafPtr)(*w);
00210         #endif
00211             
00212         pushport (thePort);
00213         }       
00214 
00215         GlobalToLocal (pt);
00216 
00217         popport ();
00218     #endif
00219 
00220     #ifdef WIN95VERSION
00221         POINT winpt;
00222         
00223         GetCursorPos (&winpt);
00224         
00225         *w = WindowFromPoint (winpt);
00226         
00227         if (*w != NULL)
00228             ScreenToClient (*w, &winpt);
00229         
00230         (*pt).h = (short)winpt.x;
00231         (*pt).v = (short)winpt.y;
00232     #endif
00233     
00234     return (*w != nil);
00235     } /*findmousewindow*/
00236 
00237 
00238 boolean mousetrack (Rect r, void (*displaycallback) (boolean)) {
00239     
00240     /*
00241     hang out in this routine until the mouse button comes up.  return true if
00242     the mouse point is in the indicated rectangle when we return.
00243     
00244     7/17/90 DW: if the mouse wasn't down when we enter, return true.  this is
00245     a heuristic that may allow some mouse-dependent routines to be driven by
00246     a script.  we figure that if the mouse isn't down now, it never was down,
00247     and whether it's inside any particular rectangle is irrelevent.
00248     
00249     7/17/90 DW: add callback routine to display the object being tracked as
00250     the mouse moves in and out of the rectangle.  set it to nil if you don't
00251     need this feature.
00252     
00253     7/17/90 DW: only call the callback when the state of the object changes,
00254     assume display is correct when we're entered.
00255     */
00256     
00257     boolean flinrectnow;
00258     boolean flwasinrect;
00259     
00260     if (!mousestilldown ()) /*see comment above*/
00261         return (true);
00262     
00263     flwasinrect = true; /*at least for the first iteration of loop*/
00264     
00265     while (mousestilldown ()) { /*stay in holding pattern*/
00266     
00267         Point pt;
00268         
00269         getmousepoint (&pt);
00270     
00271         flinrectnow = pointinrect (pt, r);
00272         
00273         if (flinrectnow != flwasinrect) { /*state of object changed*/
00274         
00275             if (displaycallback != nil)
00276                 (*displaycallback) (flinrectnow);
00277             }
00278             
00279         flwasinrect = flinrectnow;
00280         } /*while*/
00281     
00282     return (flwasinrect);
00283     } /*mousetrack*/
00284 
00285 
00286 void mousedoubleclickdisable (void) { 
00287     
00288     /*
00289     call this if you just received a mouse click that can't be interpreted as
00290     part of a doubleclick.
00291     
00292     example: mousing down on a window to select it.
00293     */
00294     
00295     mousestatus.fldoubleclickdisabled = true; /*next mouseup can't be part of a doubleclick*/
00296     } /*mousedoubleclickdisable*/
00297     
00298     
00299 static boolean mousecheckdoubleclick (void) {
00300 #ifdef MACVERSION
00301     /*
00302     using the globals mouseuptime and mouseuppoint determine if a
00303     mouseclick at pt, right now, is a double click.
00304     
00305     9/6/90 dmb:  pt parameter is no longer used.  superceeded by new 
00306     mousedown globals
00307     
00308     12/6/96 dmb: now is private routine, callers examind mousestatus
00309     */
00310     
00311     register boolean fldoubleclick;
00312     register short diff;
00313     
00314     fldoubleclick = (mousestatus.mousedowntime - mousestatus.mouseuptime) < GetDoubleClickTime ();
00315     
00316     if (fldoubleclick) { /*qualifies so far*/
00317         
00318         diff = pointdist (mousestatus.mousedownpoint, mousestatus.mouseuppoint);
00319         
00320         fldoubleclick = diff < 5; /*keep it set if mouse hasn't wandered too far*/
00321         }
00322     
00323     if (fldoubleclick) { /*user must doubleclick again to get effect*/
00324         
00325         mousestatus.mouseuptime = 0L;
00326         
00327         mousestatus.mouseuppoint.h = mousestatus.mouseuppoint.v = 0;
00328         }
00329     
00330     mousestatus.fldoubleclickdisabled = fldoubleclick; /*copy into global*/
00331     
00332     return (fldoubleclick);
00333 #endif
00334 
00335 #ifdef WIN95VERSION
00336     return (mousestatus.fldoubleclick);
00337 #endif
00338     } /*mousecheckdoubleclick*/
00339 
00340 
00341 boolean mousedoubleclick (void) {
00342 
00343     return (mousestatus.fldoubleclick);
00344     } /*mousedoubleclick*/
00345 
00346 
00347 boolean ismouseleftclick (void) {
00348 
00349     return (mousestatus.whichbutton == leftmousebuttonaction);
00350     } /*ismouseleftclick*/
00351 
00352 
00353 boolean ismouserightclick (void) {
00354 
00355     return (mousestatus.whichbutton == rightmousebuttonaction);
00356     } /*ismouserightclick*/
00357 
00358 
00359 boolean ismousecenterclick (void) {
00360 
00361     return (mousestatus.whichbutton == centermousebuttonaction);
00362     } /*ismousecenterclick*/
00363 
00364 
00365 boolean ismousewheelclick (void) {
00366 
00367     return (mousestatus.whichbutton == wheelmousebuttonaction);
00368     } /*ismousewheelclick*/
00369 
00370 
00371 static short translatemouseeventtype (long eventwhat) {
00372 #ifdef MACVERSION
00373 #   pragma unused (eventwhat)
00374 #endif
00375 
00376 #ifdef WIN95VERSION
00377     switch (eventwhat) {
00378         case rmouseDown:
00379         case rmouseUp:
00380             return (rightmousebuttonaction);
00381 
00382         case cmouseDown:
00383         case cmouseUp:
00384             return (centermousebuttonaction);
00385 
00386         case wmouseDown:
00387         case wmouseUp:
00388             return (wheelmousebuttonaction);
00389 
00390         default:
00391             break;
00392         }
00393 #endif
00394 
00395     return (leftmousebuttonaction);
00396     } /*translatemouseeventtype*/
00397         
00398 
00399 void mouseup (long eventwhen, long eventposx, long eventposy, long eventwhat) {
00400     
00401     /*
00402     call this when you receive an mouse up event.  if the last mouse down was
00403     a double click, we set things up so that the next single click will not
00404     be interpreted as a double click.
00405     */
00406     
00407     if (!mousestatus.fldoubleclickdisabled) {
00408         
00409         mousestatus.mouseuptime = eventwhen;
00410         
00411         mousestatus.mouseuppoint.h = (short)eventposx;
00412         mousestatus.mouseuppoint.v = (short)eventposy;
00413         
00414         mousestatus.mousedowntime = 0L; /*hasn't happened yet*/
00415 
00416         mousestatus.whichbutton = translatemouseeventtype (eventwhat);
00417         }
00418     
00419     mousestatus.fldoubleclickdisabled = false; /*next mouse up is important*/
00420     } /*mouseup*/
00421 
00422 
00423 void mousedown (long eventwhen, long eventposx, long eventposy, long eventwhat) {
00424     
00425     /*
00426     call this when you receive a mouse down event.  we set our globals so 
00427     the we can accurately detect a double click if requested
00428     
00429     12/6/96 dmb: set new fldoubleclick field
00430     */
00431     
00432     mousestatus.mousedowntime = eventwhen; 
00433     
00434     mousestatus.mousedownpoint.h = (short)eventposx;
00435     
00436     mousestatus.mousedownpoint.v = (short)eventposy;
00437     
00438     mousestatus.fldoubleclick = mousecheckdoubleclick ();
00439 
00440     mousestatus.whichbutton = translatemouseeventtype (eventwhat);
00441     } /*mousedown*/
00442 
00443 
00444 long getmousedoubleclicktime () {
00445 
00446 #ifdef MACVERSION
00447     return (GetDoubleClickTime ());
00448 #endif
00449 
00450 #ifdef WIN95VERSION
00451     return ((GetDoubleClickTime ()*60L)/1000L);
00452 #endif
00453     } /*getmousedoubleclicktime*/
00454 
00455 
00456 #if 0
00457 
00458 void smashmouse (Point pt) {
00459     
00460     /*
00461     reset the mouse position to the indicated Point, in global coordinates.
00462     
00463     downloaded from APPDEV on Compuserve, so we're not exactly sure how this
00464     works.
00465     */
00466     
00467     register short h = pt.h, v = pt.v;
00468     register short *pint;
00469     register char *pchar;
00470     register short maxh, maxv;
00471     Rect rbounds;
00472     
00473     getcurrentscreenbounds (&rbounds);
00474     
00475     maxv = rbounds.bottom - 1;
00476     
00477     maxh = rbounds.right - 1;
00478     
00479     v = min (v, maxv); /*keep h and v within bounds of of screen*/
00480     
00481     v = max (v, 0);
00482         
00483     h = min (h, maxh);
00484     
00485     h = max (h, 0);
00486     
00487     pint = (short *) 0x828; /*point at a magic spot in memory*/
00488     
00489     *pint++ = v;
00490     
00491     *pint++ = h;
00492     
00493     *pint++ = v;
00494     
00495     *pint++ = h;
00496     
00497     *pint++ = v;
00498     
00499     *pint = h;
00500     
00501     pchar = (char *) 0x8ce; /*point at another magic spot*/
00502 
00503     *pchar = 0xff;
00504     } /*smashmouse*/
00505 
00506 #endif
00507 
00508 /*  
00509 smashmousetester (void) {
00510     
00511     register short i, j;
00512     bigstring bs;
00513     Point pt;
00514     
00515     for (i = 0; i <= 100; i++) {
00516         
00517         for (j = 0; j <= 100; j++) {
00518             
00519             /%
00520             if (optionkeydown ())
00521                 return;
00522             %/
00523                 
00524             pt.h = i;
00525             
00526             pt.v = j;
00527             
00528             smashmouse (pt);
00529             
00530             /%
00531             copystring ("\p(h = ", bs);
00532             
00533             pushint (i, bs);
00534             
00535             pushstring ("\p, v = ", bs);
00536             
00537             pushint (j, bs);
00538             
00539             pushstring ("\p)", bs);
00540             
00541             shellfrontwindowmessage (bs);
00542             %/
00543             }
00544         }
00545     } /%smashmousetester%/
00546 */
00547 
00548 
00549 void showmousecursor (void) {
00550 #ifdef MACVERSION   
00551     ShowCursor ();
00552 #endif
00553 #ifdef WIN95VERSION
00554     ShowCursor (TRUE);
00555 #endif
00556     } /*showmousecursor*/
00557 
00558 
00559 void hidemousecursor (void) {
00560     
00561 #ifdef MACVERSION   
00562     HideCursor ();
00563 #endif
00564 #ifdef WIN95VERSION
00565     ShowCursor (FALSE);
00566 #endif
00567     } /*hidemousecursor*/
00568 
00569 
00570 boolean mousecheckautoscroll (Point pt, Rect r, boolean flhoriz, tydirection *dir) {
00571     
00572     /*
00573     if the point pt is outside of the rect r in the indicated dimension (flhoriz), 
00574     return true and set dir to the corresponding scroll direction.
00575     */
00576     
00577     register tydirection d = nodirection;
00578     
00579     if (flhoriz) {
00580     
00581         if (pt.h < r.left)
00582             d = right;
00583         
00584         else if (pt.h > r.right)
00585             d = left;
00586         }
00587     else {
00588         
00589         if (pt.v < r.top)
00590             d = down;
00591         
00592         else if (pt.v > r.bottom)
00593             d = up;
00594         }
00595     
00596     *dir = d;
00597     
00598     return (d != nodirection);
00599     } /*mousecheckautoscroll*/
00600 
00601 
00602 
00603 

Generated on Wed May 31 18:19:56 2006 for frontierkernel 10.1.10a by  doxygen 1.4.6