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.orig < prev    next >
Encoding:
Text File  |  1991-07-16  |  13.3 KB  |  510 lines

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