home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / server / ddx / sun / sunMouse.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-07-21  |  13.3 KB  |  511 lines

  1. /* $XConsortium: sunMouse.c,v 5.11 91/11/14 13:35:56 keith Exp $ */
  2. /*-
  3.  * sunMouse.c --
  4.  *    Functions for playing cat and mouse... sorry.
  5.  *
  6.  * Copyright (c) 1987 by the Regents of the University of California
  7.  *
  8.  * Permission to use, copy, modify, and distribute this
  9.  * software and its documentation for any purpose and without
  10.  * fee is hereby granted, provided that the above copyright
  11.  * notice appear in all copies.  The University of California
  12.  * makes no representations about the suitability of this
  13.  * software for any purpose.  It is provided "as is" without
  14.  * express or implied warranty.
  15.  *
  16.  *
  17.  */
  18.  
  19. /************************************************************
  20. Copyright 1987 by Sun Microsystems, Inc. Mountain View, CA.
  21.  
  22.                     All Rights Reserved
  23.  
  24. Permission  to  use,  copy,  modify,  and  distribute   this
  25. software  and  its documentation for any purpose and without
  26. fee is hereby granted, provided that the above copyright no-
  27. tice  appear  in all copies and that both that copyright no-
  28. tice and this permission notice appear in  supporting  docu-
  29. mentation,  and  that the names of Sun or MIT not be used in
  30. advertising or publicity pertaining to distribution  of  the
  31. software  without specific prior written permission. Sun and
  32. M.I.T. make no representations about the suitability of this
  33. software for any purpose. It is provided "as is" without any
  34. express or implied warranty.
  35.  
  36. SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO  THIS  SOFTWARE,
  37. INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
  38. NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE  LI-
  39. ABLE  FOR  ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  40. ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,  DATA  OR
  41. PROFITS,  WHETHER  IN  AN  ACTION OF CONTRACT, NEGLIGENCE OR
  42. OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
  43. THE USE OR PERFORMANCE OF THIS SOFTWARE.
  44.  
  45. ********************************************************/
  46.  
  47. #ifndef    lint
  48. static char sccsid[] = "%W %G Copyright 1987 Sun Micro";
  49. #endif
  50.  
  51. #define NEED_EVENTS
  52. #include    "sun.h"
  53. #include    "mipointer.h"
  54.  
  55. Bool ActiveZaphod = TRUE;
  56.  
  57. static Bool sunCursorOffScreen();
  58. static void sunCrossScreen();
  59. static void sunWarpCursor();
  60.  
  61. miPointerScreenFuncRec sunPointerScreenFuncs = {
  62.     sunCursorOffScreen,
  63.     sunCrossScreen,
  64.     sunWarpCursor,
  65. };
  66.  
  67. typedef struct {
  68.     int        bmask;        /* Current button state */
  69. } SunMsPrivRec, *SunMsPrivPtr;
  70.  
  71. static void           sunMouseCtrl();
  72. static Firm_event     *sunMouseGetEvents();
  73. static void           sunMouseEnqueueEvent();
  74.  
  75. static SunMsPrivRec    sunMousePriv;
  76.  
  77. static PtrPrivRec     sysMousePriv = {
  78.     -1,                /* Descriptor to device */
  79.     sunMouseGetEvents,        /* Function to read events */
  80.     sunMouseEnqueueEvent,    /* Function to process an event */
  81.     (pointer)&sunMousePriv,    /* Field private to device */
  82. };
  83.  
  84. /*-
  85.  *-----------------------------------------------------------------------
  86.  * sunMouseProc --
  87.  *    Handle the initialization, etc. of a mouse
  88.  *
  89.  * Results:
  90.  *    none.
  91.  *
  92.  * Side Effects:
  93.  *
  94.  * Note:
  95.  *    When using sunwindows, all input comes off a single fd, stored in the
  96.  *    global windowFd.  Therefore, only one device should be enabled and
  97.  *    disabled, even though the application still sees both mouse and
  98.  *    keyboard.  We have arbitrarily chosen to enable and disable windowFd
  99.  *    in the keyboard routine sunKbdProc rather than in sunMouseProc.
  100.  *
  101.  *-----------------------------------------------------------------------
  102.  */
  103. int
  104. sunMouseProc (pMouse, what)
  105.     DevicePtr      pMouse;       /* Mouse to play with */
  106.     int              what;            /* What to do with it */
  107. {
  108.     register int  fd;
  109.     int              format;
  110.     static int      oformat;
  111.     BYTE          map[4];
  112.     char      *device, *getenv ();
  113.  
  114.     switch (what) {
  115.     case DEVICE_INIT:
  116.         if (pMouse != LookupPointerDevice()) {
  117.         ErrorF ("Cannot open non-system mouse");    
  118.         return (!Success);
  119.         }
  120.  
  121.         if (! sunUseSunWindows()) {
  122.         if (sysMousePriv.fd >= 0) {
  123.             fd = sysMousePriv.fd;
  124.         } else {
  125.             if (!(device = getenv ("MOUSE")) ||
  126.              (fd = open (device, O_RDWR, 0)) == -1)
  127.             fd = open ("/dev/mouse", O_RDWR, 0);
  128.             if (fd < 0) {
  129.             Error ("Opening /dev/mouse");
  130.             return (!Success);
  131.             }
  132.             if (fcntl (fd, F_SETFL, (FNDELAY|FASYNC)) < 0
  133.             || fcntl(fd, F_SETOWN, getpid()) < 0) {
  134.                 perror("sunMouseProc");
  135.                 ErrorF("Can't set up mouse on fd %d\n", fd);
  136.             }
  137.             
  138.             sysMousePriv.fd = fd;
  139.         }
  140.         }
  141.  
  142.         sunMousePriv.bmask = 0;
  143.  
  144.         pMouse->devicePrivate = (pointer) &sysMousePriv;
  145.         pMouse->on = FALSE;
  146.         map[1] = 1;
  147.         map[2] = 2;
  148.         map[3] = 3;
  149.         InitPointerDeviceStruct(
  150.         pMouse, map, 3, miPointerGetMotionEvents,
  151.          sunMouseCtrl, miPointerGetMotionBufferSize());
  152.         break;
  153.  
  154.     case DEVICE_ON:
  155.         if (! sunUseSunWindows()) {
  156.         if (ioctl (((PtrPrivPtr)pMouse->devicePrivate)->fd,
  157.             VUIDGFORMAT, &oformat) < 0) {
  158.             Error ("VUIDGFORMAT");
  159.             return(!Success);
  160.         }
  161.         format = VUID_FIRM_EVENT;
  162.         if (ioctl (((PtrPrivPtr)pMouse->devicePrivate)->fd,
  163.             VUIDSFORMAT, &format) < 0) {
  164.             Error ("VUIDSFORMAT");
  165.             return(!Success);
  166.         }
  167.         AddEnabledDevice (((PtrPrivPtr)pMouse->devicePrivate)->fd);
  168.         }
  169.  
  170.         pMouse->on = TRUE;
  171.         break;
  172.  
  173.     case DEVICE_CLOSE:
  174.         if (! sunUseSunWindows()) {
  175.         if (ioctl (((PtrPrivPtr)pMouse->devicePrivate)->fd,
  176.             VUIDSFORMAT, &oformat) < 0) {
  177.             Error ("VUIDSFORMAT");
  178.         }
  179.         }
  180.         break;
  181.  
  182.     case DEVICE_OFF:
  183.         pMouse->on = FALSE;
  184.         if (! sunUseSunWindows()) {
  185.         RemoveEnabledDevice (((PtrPrivPtr)pMouse->devicePrivate)->fd);
  186.         }
  187.         break;
  188.     }
  189.     return (Success);
  190. }
  191.         
  192. /*-
  193.  *-----------------------------------------------------------------------
  194.  * sunMouseCtrl --
  195.  *    Alter the control parameters for the mouse. Since acceleration
  196.  *    etc. is done from the PtrCtrl record in the mouse's device record,
  197.  *    there's nothing to do here.
  198.  *
  199.  * Results:
  200.  *    None.
  201.  *
  202.  * Side Effects:
  203.  *    None.
  204.  *
  205.  *-----------------------------------------------------------------------
  206.  */
  207. /*ARGSUSED*/
  208. static void
  209. sunMouseCtrl (pMouse)
  210.     DevicePtr      pMouse;
  211. {
  212. }
  213.  
  214. /*-
  215.  *-----------------------------------------------------------------------
  216.  * sunMouseGetEvents --
  217.  *    Return the events waiting in the wings for the given mouse.
  218.  *
  219.  * Results:
  220.  *    A pointer to an array of Firm_events or (Firm_event *)0 if no events
  221.  *    The number of events contained in the array.
  222.  *    A boolean as to whether more events might be available.
  223.  *
  224.  * Side Effects:
  225.  *    None.
  226.  *-----------------------------------------------------------------------
  227.  */
  228. static Firm_event *
  229. sunMouseGetEvents (pMouse, pNumEvents, pAgain)
  230.     DevicePtr      pMouse;        /* Mouse to read */
  231.     int              *pNumEvents;        /* Place to return number of events */
  232.     Bool      *pAgain;        /* whether more might be available */
  233. {
  234.     int              nBytes;        /* number of bytes of events available. */
  235.     register PtrPrivPtr      pPriv;
  236.     static Firm_event    evBuf[MAXEVENTS];   /* Buffer for Firm_events */
  237.  
  238.     pPriv = (PtrPrivPtr) pMouse->devicePrivate;
  239.  
  240.     nBytes = read (pPriv->fd, evBuf, sizeof(evBuf));
  241.  
  242.     if (nBytes < 0) {
  243.     if (errno == EWOULDBLOCK) {
  244.         *pNumEvents = 0;
  245.         *pAgain = FALSE;
  246.     } else {
  247.         Error ("Reading mouse");
  248.         FatalError ("Could not read from mouse");
  249.     }
  250.     } else {
  251.     *pNumEvents = nBytes / sizeof (Firm_event);
  252.     *pAgain = (nBytes == sizeof (evBuf));
  253.     }
  254.     return (evBuf);
  255. }
  256.  
  257.  
  258. /*-
  259.  *-----------------------------------------------------------------------
  260.  * MouseAccelerate --
  261.  *    Given a delta and a mouse, return the acceleration of the delta.
  262.  *
  263.  * Results:
  264.  *    The corrected delta
  265.  *
  266.  * Side Effects:
  267.  *    None.
  268.  *
  269.  *-----------------------------------------------------------------------
  270.  */
  271. static short
  272. MouseAccelerate (pMouse, delta)
  273.     DevicePtr      pMouse;
  274.     int              delta;
  275. {
  276.     register int  sgn = sign(delta);
  277.     register PtrCtrl *pCtrl;
  278.  
  279.     delta = abs(delta);
  280.     pCtrl = &((DeviceIntPtr) pMouse)->ptrfeed->ctrl;
  281.  
  282.     if (delta > pCtrl->threshold) {
  283.     return ((short) (sgn * (pCtrl->threshold +
  284.                 ((delta - pCtrl->threshold) * pCtrl->num) /
  285.                 pCtrl->den)));
  286.     } else {
  287.     return ((short) (sgn * delta));
  288.     }
  289. }
  290.  
  291. /*-
  292.  *-----------------------------------------------------------------------
  293.  * sunMouseEnqueueEvent --
  294.  *    Given a Firm_event for a mouse, pass it off the the dix layer
  295.  *    properly converted...
  296.  *
  297.  * Results:
  298.  *    None.
  299.  *
  300.  * Side Effects:
  301.  *    The cursor may be redrawn...? devPrivate/x/y will be altered.
  302.  *
  303.  *-----------------------------------------------------------------------
  304.  */
  305. static void
  306. sunMouseEnqueueEvent (pMouse, fe)
  307.     DevicePtr      pMouse;       /* Mouse from which the event came */
  308.     Firm_event      *fe;            /* Event to process */
  309. {
  310.     xEvent        xE;
  311.     register PtrPrivPtr    pPriv;    /* Private data for pointer */
  312.     register SunMsPrivPtr pSunPriv; /* Private data for mouse */
  313.     register int      bmask;    /* Temporary button mask */
  314.     register unsigned long  time;
  315.     int            x, y;
  316.  
  317.     pPriv = (PtrPrivPtr)pMouse->devicePrivate;
  318.     pSunPriv = (SunMsPrivPtr) pPriv->devPrivate;
  319.  
  320.     time = xE.u.keyButtonPointer.time = TVTOMILLI(fe->time);
  321.  
  322.     switch (fe->id)
  323.     {
  324.     case MS_LEFT:
  325.     case MS_MIDDLE:
  326.     case MS_RIGHT:
  327.     /*
  328.      * A button changed state. Sometimes we will get two events
  329.      * for a single state change. Should we get a button event which
  330.      * reflects the current state of affairs, that event is discarded.
  331.      *
  332.      * Mouse buttons start at 1.
  333.      */
  334.     xE.u.u.detail = (fe->id - MS_LEFT) + 1;
  335.     bmask = 1 << xE.u.u.detail;
  336.     if (fe->value == VKEY_UP) {
  337.         if (pSunPriv->bmask & bmask) {
  338.         xE.u.u.type = ButtonRelease;
  339.         pSunPriv->bmask &= ~bmask;
  340.         } else {
  341.         return;
  342.         }
  343.     } else {
  344.         if ((pSunPriv->bmask & bmask) == 0) {
  345.         xE.u.u.type = ButtonPress;
  346.         pSunPriv->bmask |= bmask;
  347.         } else {
  348.         return;
  349.         }
  350.     }
  351.     mieqEnqueue (&xE);
  352.     break;
  353.     case LOC_X_DELTA:
  354.     miPointerDeltaCursor (MouseAccelerate(pMouse,fe->value),0,time);
  355.     break;
  356.     case LOC_Y_DELTA:
  357.     /*
  358.      * For some reason, motion up generates a positive y delta
  359.      * and motion down a negative delta, so we must subtract
  360.      * here instead of add...
  361.      */
  362.     miPointerDeltaCursor (0,-MouseAccelerate(pMouse,fe->value),time);
  363.     break;
  364.     case LOC_X_ABSOLUTE:
  365.     miPointerPosition (&x, &y);
  366.     miPointerAbsoluteCursor (fe->value, y, time);
  367.     break;
  368.     case LOC_Y_ABSOLUTE:
  369.     miPointerPosition (&x, &y);
  370.     miPointerAbsoluteCursor (x, fe->value, time);
  371.     break;
  372.     default:
  373.     FatalError ("sunMouseEnqueueEvent: unrecognized id\n");
  374.     break;
  375.     }
  376. }
  377.  
  378. /*ARGSUSED*/
  379. static Bool
  380. sunCursorOffScreen (pScreen, x, y)
  381.     ScreenPtr    *pScreen;
  382.     int        *x, *y;
  383. {
  384.     int        index;
  385.  
  386.     /*
  387.      * Active Zaphod implementation:
  388.      *    increment or decrement the current screen
  389.      *    if the x is to the right or the left of
  390.      *    the current screen.
  391.      */
  392.     if (ActiveZaphod &&
  393.     screenInfo.numScreens > 1 && (*x >= (*pScreen)->width || *x < 0))
  394.     {
  395.     index = (*pScreen)->myNum;
  396.     if (*x < 0)
  397.     {
  398.         index = (index ? index : screenInfo.numScreens) - 1;
  399.         *pScreen = screenInfo.screens[index];
  400.         *x += (*pScreen)->width;
  401.     }
  402.     else
  403.     {
  404.         *x -= (*pScreen)->width;
  405.         index = (index + 1) % screenInfo.numScreens;
  406.         *pScreen = screenInfo.screens[index];
  407.     }
  408.     return TRUE;
  409.     }
  410.     return FALSE;
  411. }
  412.  
  413. static void
  414. sunCrossScreen (pScreen, entering)
  415.     ScreenPtr    pScreen;
  416.     Bool    entering;
  417. {
  418.     u_char  select;
  419.  
  420.     select = 1;
  421.     if (entering)
  422.     select = 0;
  423.     if (sunFbs[pScreen->myNum].EnterLeave)
  424.     (*sunFbs[pScreen->myNum].EnterLeave) (pScreen, select);
  425. }
  426.  
  427. static void
  428. sunWarpCursor (pScreen, x, y)
  429.     ScreenPtr    pScreen;
  430.     int        x, y;
  431. {
  432.     int        oldmask;
  433.  
  434.     oldmask = sigblock (sigmask(SIGIO));
  435.     miPointerWarpCursor (pScreen, x, y);
  436.     sigsetmask (oldmask);
  437. }
  438.  
  439. #ifdef SUN_WINDOWS
  440.  
  441. /*
  442.  * Enqueue a sunwindows mouse event.  The possible events are
  443.  *   LOC_MOVE
  444.  *   MS_LEFT
  445.  *   MS_MIDDLE
  446.  *   MS_RIGHT
  447.  */
  448.  
  449. void
  450. sunMouseEnqueueEventSunWin(pMouse,se)
  451.     DeviceRec *pMouse;
  452.     register struct inputevent *se;
  453. {   
  454.     xEvent            xE;
  455.     register int          bmask;    /* Temporary button mask */
  456.     register PtrPrivPtr        pPriv;    /* Private data for pointer */
  457.     register SunMsPrivPtr    pSunPriv; /* Private data for mouse */
  458.     int                x, y;
  459.     unsigned long        time;
  460.  
  461.     pPriv = (PtrPrivPtr)pMouse->devicePrivate;
  462.     time = xE.u.keyButtonPointer.time = TVTOMILLI(event_time(se));
  463.  
  464.     switch (event_id(se)) {
  465.         case MS_LEFT:
  466.         case MS_MIDDLE:
  467.         case MS_RIGHT:
  468.         /*
  469.          * A button changed state. Sometimes we will get two events
  470.          * for a single state change. Should we get a button event which
  471.          * reflects the current state of affairs, that event is discarded.
  472.          *
  473.          * Mouse buttons start at 1.
  474.          */
  475.         pSunPriv = (SunMsPrivPtr) pPriv->devPrivate;
  476.         xE.u.u.detail = (event_id(se) - MS_LEFT) + 1;
  477.         bmask = 1 << xE.u.u.detail;
  478.         if (win_inputnegevent(se)) {
  479.         if (pSunPriv->bmask & bmask) {
  480.             xE.u.u.type = ButtonRelease;
  481.             pSunPriv->bmask &= ~bmask;
  482.         } else {
  483.             return;
  484.         }
  485.         } else {
  486.         if ((pSunPriv->bmask & bmask) == 0) {
  487.             xE.u.u.type = ButtonPress;
  488.             pSunPriv->bmask |= bmask;
  489.         } else {
  490.             return;
  491.         }
  492.         }
  493.         mieqEnqueue (&xE);
  494.             break;
  495.         case LOC_MOVE:
  496.         miPointerAbsoluteCursor(event_x(se),event_y(se),time);
  497.         miPointerPosition (&x, &y);
  498.         if (x != event_x(se) || y != event_y(se))
  499.             /*
  500.                  * Tell SunWindows that X is constraining the mouse
  501.                  * cursor so that the server and SunWindows stay in sync.
  502.              */
  503.             win_setmouseposition(windowFd, x, y);
  504.         break;
  505.     default:
  506.         FatalError ("sunMouseEnqueueEventSunWin: unrecognized id\n");
  507.         break;
  508.     }
  509. }
  510. #endif SUN_WINDOWS
  511.