home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / server / ddx / mips / mipsMouse.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-07-18  |  15.5 KB  |  739 lines

  1. /*
  2.  * $XConsortium: mipsMouse.c,v 1.5 91/07/18 22:58:46 keith Exp $
  3.  *
  4.  * Copyright 1991 MIPS Computer Systems, Inc.
  5.  *
  6.  * Permission to use, copy, modify, distribute, and sell this software and its
  7.  * documentation for any purpose is hereby granted without fee, provided that
  8.  * the above copyright notice appear in all copies and that both that
  9.  * copyright notice and this permission notice appear in supporting
  10.  * documentation, and that the name of MIPS not be used in advertising or
  11.  * publicity pertaining to distribution of the software without specific,
  12.  * written prior permission.  MIPS makes no representations about the
  13.  * suitability of this software for any purpose.  It is provided "as is"
  14.  * without express or implied warranty.
  15.  *
  16.  * MIPS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
  17.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL MIPS
  18.  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  19.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  20.  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 
  21.  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  22.  */
  23. #ident    "$Header: mipsMouse.c,v 1.5 91/07/18 22:58:46 keith Exp $"
  24.  
  25. #include <sys/types.h>
  26. #include <sys/file.h>
  27. #include <sysv/sys/termio.h>
  28. #include <sysv/sys/uart_ioctl.h>
  29. #include <sys/time.h>
  30. #ifndef NOSIGNALS
  31. #include <signal.h>
  32. #endif NOSIGNALS
  33.  
  34. #include "X.h"
  35. #define  NEED_EVENTS
  36. #include "Xproto.h"
  37. #include "scrnintstr.h"
  38. #include "inputstr.h"
  39. #include "mipointer.h"
  40.  
  41. #include "mips.h"
  42. #include "mipsIo.h"
  43. #include "mipsMouse.h"
  44.  
  45. MousePriv mousePriv = {
  46.     -1,
  47.     0,
  48.     0,
  49.     1200,
  50.     0,
  51.     0, 0,
  52.     MIPS_MOUSE_DEFAULT,
  53.     0,
  54.     { {RAW_LEFT, 1},
  55.       {RAW_MIDDLE, 2},
  56.       {RAW_RIGHT, 3} },
  57. };
  58.  
  59. #if PIXIE
  60. extern int    pixie;
  61. #endif /* PIXIE */
  62.  
  63. /* mouse statistics */
  64. int    mserr = 0;
  65.  
  66. #ifdef X11R4
  67.  
  68. static long mipsEventTime();
  69. static Bool mipsCursorOffScreen();
  70. static void mipsCrossScreen();
  71. extern void miPointerQueueEvent();
  72.  
  73. miPointerCursorFuncRec mipsPointerCursorFuncs = {
  74.     mipsEventTime,
  75.     mipsCursorOffScreen,
  76.     mipsCrossScreen,
  77.     miPointerQueueEvent,
  78. };
  79.  
  80. volatile mouseQ_t    mouseQ[MOUSEQSIZE];
  81. volatile mouseQ_t    *mouseQh = mouseQ;
  82. volatile mouseQ_t    *mouseQt = mouseQ;
  83.  
  84. /* Motion buffer */
  85. int        motionBufferSize = 100;
  86. xTimecoord    *motionBuf = NULL;
  87. xTimecoord    *motionTail = NULL;
  88.  
  89. static long
  90. mipsEventTime(pScr)
  91. ScreenPtr    pScr;
  92. {
  93.     return(lastEventTime);
  94. }
  95.  
  96. #else /* X11R4 */
  97.  
  98. static Bool mipsCursorOffScreen();
  99. static void mipsCrossScreen();
  100. static void mipsWarpCursor();
  101.  
  102. miPointerScreenFuncRec mipsPointerScreenFuncs = {
  103.     mipsCursorOffScreen,
  104.     mipsCrossScreen,
  105.     mipsWarpCursor,
  106. };
  107.  
  108. static void
  109. mipsWarpCursor (pScr, x, y)
  110. ScreenPtr    pScr;
  111. int        x, y;
  112. {
  113. #ifdef SYSV
  114.     void    (*poll)();
  115.  
  116.     poll = sigset(SIGPOLL, SIG_HOLD);
  117. #else /* SYSV */
  118.     int        block;
  119.  
  120.     block = sigblock(sigmask(SIGIO));
  121. #endif /* SYSV */
  122.     miPointerWarpCursor (pScr, x, y);
  123. #ifdef SYSV
  124.     (void) sigset(SIGPOLL, poll);
  125. #else /* SYSV */
  126.     (void) sigsetmask(block);
  127. #endif /* SYSV */
  128. }
  129.  
  130. #endif /* X11R4 */
  131.  
  132. static Bool
  133. mipsCursorOffScreen(pScr, x, y)
  134. ScreenPtr    *pScr;
  135. int        *x;
  136. int        *y;
  137. {
  138.     int        i;
  139.  
  140.     if ((screenInfo.numScreens > 1) && ((*x < 0) || ((*pScr)->width <= *x))) {
  141.     i = (*pScr)->myNum;
  142.     if (*x < 0) {
  143.         if (i == 0) i = screenInfo.numScreens;
  144.         i--;
  145.         *pScr = screenInfo.screens[i];
  146.         *x += (*pScr)->width;
  147.     }
  148.     else {
  149.         *x -= (*pScr)->width;
  150.         i++;
  151.         if (i == screenInfo.numScreens) i = 0;
  152.         *pScr = screenInfo.screens[i];
  153.     }
  154.     return(TRUE);
  155.     }
  156.     return(FALSE);
  157. }
  158.  
  159. /*ARGSUSED*/
  160. static void
  161. mipsCrossScreen(pScr, enter)
  162. ScreenPtr    pScr;
  163. Bool        enter;
  164. {
  165. }
  166.  
  167. static
  168. setSpeed(fd, vmin, speed)
  169. int    fd;
  170. int    vmin;
  171. int    speed;
  172. {
  173.     struct termio    logmode;
  174.  
  175.     logmode.c_iflag = IGNBRK|IGNPAR;
  176.     logmode.c_oflag = 0;
  177.     logmode.c_lflag = 0;
  178.     logmode.c_line = 0;
  179.     logmode.c_cc[VMIN] = vmin;
  180.     logmode.c_cc[VTIME] = 0;
  181.     switch (speed) {
  182.     case 9600:
  183.         logmode.c_cflag = B9600|CS8|CSTOPB|CREAD|CLOCAL|HUPCL;
  184.         break;
  185.     case 4800:
  186.         logmode.c_cflag = B4800|CS8|CSTOPB|CREAD|CLOCAL|HUPCL;
  187.         break;
  188.     case 2400:
  189.         logmode.c_cflag = B2400|CS8|CSTOPB|CREAD|CLOCAL|HUPCL;
  190.         break;
  191.     case 1200:
  192.     default:
  193.         logmode.c_cflag = B1200|CS8|CSTOPB|CREAD|CLOCAL|HUPCL;
  194.         break;
  195.     }
  196.     if (ioctl(fd, TCSETAF, &logmode) < 0) {    /* set tty mode */
  197.     Error("cannot ioctl(TCSETAF) mouse");
  198.     return(-1);
  199.     }
  200. }
  201.  
  202. static
  203. setBaud(fd, vmin, current, new)
  204. int    fd;
  205. int    vmin;
  206. int    current;
  207. int    new;
  208. {
  209.     setSpeed(fd, vmin, current);
  210.  
  211. #if PIXIE
  212.     if (!pixie)
  213. #endif /* PIXIE */
  214.     {
  215.     write(fd, "*", 1);
  216.     switch (new) {
  217.         case 9600:
  218.         write(fd, "q", 1);  /* Set baud rate to 9600 */
  219.         break;
  220.         case 4800:
  221.         write(fd, "p", 1);  /* Set baud rate to 4800 */
  222.         break;
  223.         case 2400:
  224.         write(fd, "o", 1);  /* Set baud rate to 2400 */
  225.         break;
  226.         case 1200:
  227.         default:
  228.         write(fd, "n", 1);  /* Set baud rate to 1200 */
  229.         break;
  230.     }
  231.  
  232.     {
  233.         struct timeval    wait;
  234.  
  235.         wait.tv_sec = 0;
  236.         wait.tv_usec = 100000;
  237.  
  238.         select(0, NULL, NULL, NULL, &wait);
  239.     }
  240.     }
  241.  
  242.     setSpeed(fd, vmin, new);
  243. }
  244.  
  245. /* logfd is a real serial device... */
  246.  
  247. static int
  248. loginit(pPriv)
  249. MousePrivPtr    pPriv;
  250. {
  251.     int        vmin;
  252.     char    c;
  253.  
  254.     if (pPriv->cap & DEV_INIT) {
  255.     vmin = (pPriv->cap & DEV_TIMESTAMP) ? 40 : 5;
  256.     vmin = 1;
  257.     setBaud(pPriv->fd, vmin, 1200, pPriv->baud);
  258.     setBaud(pPriv->fd, vmin, 2400, pPriv->baud);
  259.     setBaud(pPriv->fd, vmin, 4800, pPriv->baud);
  260.     setBaud(pPriv->fd, vmin, 9600, pPriv->baud);
  261.  
  262.     switch (pPriv->type) {
  263.     default:
  264.         write(pPriv->fd, "U", 1);    /* Five byte packed binary */
  265.  
  266.         if (pPriv->rate <= 0)
  267.             write(pPriv->fd, "O", 1);    /* Continuous */
  268.         else if (125 <= pPriv->rate)
  269.             write(pPriv->fd, "N", 1);    /* 150 per second */
  270.         else if (85 <= pPriv->rate)
  271.             write(pPriv->fd, "Q", 1);    /* 100 per second */
  272.         else if (60 <= pPriv->rate)
  273.             write(pPriv->fd, "M", 1);    /* 70 per second */
  274.         else if (42 <= pPriv->rate)
  275.             write(pPriv->fd, "R", 1);    /* 50 per second */
  276.         else if (27 <= pPriv->rate)
  277.             write(pPriv->fd, "L", 1);    /* 35 per second */
  278.         else if (15 <= pPriv->rate)
  279.             write(pPriv->fd, "K", 1);    /* 20 per second */
  280.         else
  281.             write(pPriv->fd, "J", 1);    /* 10 per second */
  282.         break;
  283.     case MIPS_MOUSE_MOUSEMAN:
  284.         sleep(2);
  285.         write(pPriv->fd, "*U", 2);
  286.         sleep(2);
  287.         while ( read(pPriv->fd, &c, 1) == 1 )
  288.             /* nothing */ ;
  289.         break;
  290.     }
  291.     }
  292.     return(0);
  293. }
  294.  
  295. static int
  296. accelMouse(d)
  297. int        d;
  298. {
  299.     PtrCtrl *pctrl;
  300.  
  301.     pctrl = &mousePriv.ctrl;
  302.     if (d > 0)
  303.     return((d > pctrl->threshold) ? (d * pctrl->num) / pctrl->den : d);
  304.     else
  305.     return((-d > pctrl->threshold) ? (d * pctrl->num) / pctrl->den : d);
  306. }
  307.  
  308. #ifdef X11R4
  309. static void
  310. enqueueMouse(time, dx, dy, bmask)
  311. int    time;
  312. int    dx, dy;
  313. int    bmask;
  314. {
  315.     volatile mouseQ_t    *newQt;
  316.  
  317.     mouseQt->time = time;
  318.     mouseQt->scrn = mousePriv.scrn;
  319.     mouseQt->dx = accelMouse(dx);
  320.     mouseQt->dy = accelMouse(dy);
  321.     mouseQt->bmask = bmask;
  322.     newQt = mouseQt + 1;
  323.     if (newQt == (mouseQ + MOUSEQSIZE))
  324.     newQt = mouseQ;
  325.     if (newQt != mouseQh)
  326.     mouseQt = newQt;
  327. }
  328.  
  329. static void
  330. dequeueMouse()
  331. {
  332.     volatile mouseQ_t    *newQh;
  333.  
  334.     newQh = mouseQh + 1;
  335.     if (newQh == (mouseQ + MOUSEQSIZE))
  336.     newQh = mouseQ;
  337.     mouseQh = newQh;
  338. }
  339. #endif /* X11R4 */
  340.  
  341. #ifdef X11R4
  342. #define    mouseEvent(pm, dx, dy, bmask, time) \
  343.     enqueueMouse((time), (dx), (dy), (bmask))
  344. #endif /* X11R4 */
  345.  
  346. static int
  347. charMouse(pMouse, code, time)
  348.     DevicePtr pMouse;
  349.     char code;
  350.     int time;
  351. {
  352.     static signed char    msbuf[5];    /* mouse input buffer */
  353.     static int        state = 0;
  354.  
  355.     if ((code & 0xf8) == LSYNCBIT) {
  356.     /* Sync bit found */
  357.  
  358.     if (state) {
  359.         mouseEvent (pMouse, msbuf[1], -msbuf[2], msbuf[0], time);
  360.         mserr++;
  361.     }
  362.     state = 1;
  363.     msbuf[0] = BUTTONMASK(code);
  364.     msbuf[1] = 0;
  365.     msbuf[2] = 0;
  366.     }
  367.     else {
  368.     /* Sync bit not found */
  369.  
  370.     switch (state) {
  371.         case 0:    /* Waiting for sync byte */
  372.         mserr++;
  373.         break;
  374.         case 1:    /* Waiting for X0 */
  375.         msbuf[state++] = (signed char) code;
  376.         break;
  377.         case 2:    /* Waiting for Y0 */
  378.         msbuf[state++] = (signed char) code;
  379.         mouseEvent (pMouse, msbuf[1], -msbuf[2], msbuf[0], time);
  380.         break;
  381.         case 3:    /* Waiting for X1 */
  382.         msbuf[state++] = (signed char) code;
  383.         break;
  384.         case 4:    /* Waiting for Y1 */
  385.         msbuf[state] = (signed char) code;
  386.         mouseEvent (pMouse, msbuf[1], -msbuf[2], msbuf[0], time);
  387.         state = 0;
  388.         break;
  389.     }
  390.     }
  391. }
  392.  
  393. static
  394. timestampMouse(pMouse, code)
  395. DevicePtr    pMouse;
  396. char        code;
  397. {
  398.     static int        state = -1;
  399.     static char        data;
  400.     static time_t    time;
  401.     u_char        *ptime = (u_char *) &time;
  402.  
  403.     state++;
  404.     switch (state) {
  405.     case 0:    /* Looking for 1st sync byte */
  406.     case 1:    /* Looking for 2nd sync byte */
  407.     case 2:    /* Looking for 3rd sync byte */
  408.         if (((u_char) code) != UARTSYNCCHAR)
  409.         state = -1;
  410.         break;
  411.     case 3:    /* Looking for data */
  412.         data = code;
  413.         break;
  414.     case 4:    /* Looking for 1st time byte */
  415.     case 5:    /* Looking for 2nd time byte */
  416.     case 6:    /* Looking for 3rd time byte */
  417.         ptime[state - 4] = (u_char) code;
  418.         break;
  419.     case 7:    /* Looking for 4th time byte */
  420.         ptime[state - 4] = (u_char) code;
  421.         charMouse(pMouse, data, offsetTime(time));
  422.         state = -1;
  423.         break;
  424.     }
  425. }
  426.  
  427. void
  428. handleMouse(pMouse)
  429. DevicePtr    pMouse;
  430. {
  431.     int        nchar = 0;
  432.     int        i;
  433.     char    buf[MAXEVENTS];
  434.  
  435. #ifdef X11R4
  436. #ifdef SYSV
  437.     void    (*poll)();
  438.  
  439.     poll = sigset(SIGPOLL, SIG_HOLD);
  440. #else /* SYSV */
  441.     int        block;
  442.  
  443.     block = sigblock(sigmask(SIGIO));
  444. #endif /* SYSV */
  445. #else /* X11R4 */
  446.     if (!mousePriv.cap & DEV_TIMESTAMP)
  447.     lastEventTime = GetTimeInMillis();
  448. #endif /* X11R4 */
  449.  
  450.     if ((mousePriv.fd >= 0) && (mousePriv.cap & DEV_READ)) {
  451.     do {
  452.         if ((nchar = read(mousePriv.fd, buf, sizeof(buf))) <= 0)
  453.         break;
  454.  
  455.         if (mousePriv.cap & DEV_TIMESTAMP) {
  456.         for (i = 0; i < nchar; ++i)
  457.             timestampMouse(pMouse, buf[i]);
  458.         }
  459.         else {
  460.         for (i = 0; i < nchar; ++i)
  461.             charMouse(pMouse, buf[i], lastEventTime);
  462.         }
  463.     } while (nchar == sizeof(buf));
  464.     }
  465.  
  466. #ifdef X11R4
  467. #ifdef SYSV
  468.     (void) sigset(SIGPOLL, poll);
  469. #else /* SYSV */
  470.     (void) sigsetmask(block);
  471. #endif /* SYSV */
  472.  
  473.     while (mouseQh != mouseQt) {
  474.     mouse_event(pMouse, mouseQh);
  475.     dequeueMouse();
  476.     }
  477. #endif /* X11R4 */
  478. }
  479.  
  480. /* ARGSUSED */
  481. static void
  482. mipsChangePointerControl(pDevice, ctrl)
  483. DevicePtr    pDevice;
  484. PtrCtrl        *ctrl;
  485. {
  486.     mousePriv.ctrl = *ctrl;
  487. }
  488.  
  489. #ifdef X11R4
  490.  
  491. /* ARGSUSED */
  492. static int
  493. mipsGetMotionEvents(dev, buff, start, stop)
  494. DeviceIntPtr    dev;
  495. xTimecoord    *buff;
  496. CARD32        start, stop;
  497. {
  498.     xTimecoord    *ptc;
  499.     int        count = 0;
  500.  
  501.     if (motionBuf) {
  502.     ptc = motionTail;
  503.     do {
  504.         ptc++;
  505.         if (ptc == (motionBuf + motionBufferSize))
  506.         ptc = motionBuf;
  507.         if ((start <= ptc->time) && (ptc->time <= stop)) {
  508.         *buff++ = *ptc;
  509.         count++;
  510.         }
  511.     }
  512.     while ((ptc != motionTail) && (ptc->time <= stop));
  513.     }
  514.  
  515.     return(count);
  516. }
  517.  
  518. #endif /* X11R4 */
  519.  
  520. static mouseAsync(pPriv, set)
  521. MousePrivPtr    pPriv;
  522. Bool    set;
  523. {
  524. #if PIXIE
  525.     if (pixie)
  526.     return;
  527. #endif /* PIXIE */
  528.     if (pPriv->cap & DEV_ASYNC) {
  529.     if (mipsStreamAsync(pPriv->fd, set) < 0) {
  530.         pPriv->cap &= ~DEV_ASYNC;
  531.         Error("cannot ioctl(I_SETSIG) mouse");
  532.     }
  533.     }
  534. }
  535.  
  536. openMouse()
  537. {
  538.     if (mousePriv.fd < 0) {
  539.     if ((mousePriv.fd = open(MOUSEDEV, O_RDWR|O_NDELAY)) >= 0) {
  540. #ifndef SYSV
  541.         int        flags;
  542.  
  543.         if ((flags = fcntl(mousePriv.fd, F_GETFL, flags)) == -1)
  544.         Error("cannot fcntl(F_GETFL) mouse");
  545.         flags |= FNDELAY;
  546.         if (fcntl(mousePriv.fd, F_SETFL, flags) == -1)
  547.         Error("cannot fcntl(F_SETFL) mouse");
  548. #endif /* SYSV */
  549.         mousePriv.cap = -1;
  550.     }
  551.     else {
  552.         mousePriv.cap = 0;
  553.         Error("cannot open mouse");
  554.     }
  555.     }
  556. }
  557.  
  558.  
  559. /* ARGSUSED */
  560. int
  561. mipsMouseProc(pMouse, onoff, argc, argv)
  562. DevicePtr    pMouse;
  563. int        onoff, argc;
  564. char        *argv[];
  565. {
  566.     BYTE        map[4];
  567.     int            flags;
  568.     MousePrivPtr    pPriv;
  569.     extern int        loginit();
  570.  
  571.     pPriv = (MousePrivPtr) pMouse->devicePrivate;
  572.     switch (onoff) {
  573.     case DEVICE_INIT:
  574.         pMouse->devicePrivate = (pointer) &mousePriv;
  575.         pPriv = (MousePrivPtr) pMouse->devicePrivate;
  576.         openMouse();
  577.         pMouse->on = FALSE;
  578.         map[1] = 1;
  579.         map[2] = 2;
  580.         map[3] = 3;
  581. #ifdef X11R4
  582.         if (motionBufferSize) {
  583.         motionBuf = motionTail =
  584.             (xTimecoord *) Xalloc(motionBufferSize * sizeof(xTimecoord));
  585.         if (motionBuf)
  586.             bzero(motionBuf, motionBufferSize * sizeof(xTimecoord));
  587.         }
  588.         InitPointerDeviceStruct(pMouse, map, 3, mipsGetMotionEvents,
  589.         mipsChangePointerControl, motionBufferSize);
  590. #else /* X11R4 */
  591.         InitPointerDeviceStruct(pMouse, map, 3, miPointerGetMotionEvents,
  592.         mipsChangePointerControl, miPointerGetMotionBufferSize());
  593. #endif /* X11R4 */
  594.         break;
  595.     case DEVICE_ON:
  596.         if (pPriv->fd >= 0) {
  597.         if (pPriv->cap & DEV_TIMESTAMP) {
  598.             if (ioctl(pPriv->fd, UTCSETTIMESTAMP, 0) < 0) {
  599.             pPriv->cap &= ~DEV_TIMESTAMP;
  600.             Error("cannot ioctl(UTCSETTIMESTAMP) mouse");
  601.             }
  602.         }
  603.         if (loginit(pPriv) < 0)
  604.             ErrorF("cannot initialize mouse\n");
  605.         mouseAsync(pPriv, TRUE);
  606.         AddEnabledDevice(pPriv->fd);
  607.         }
  608.         pMouse->on = TRUE;
  609.         break;
  610.     case DEVICE_CLOSE:
  611.         pMouse->on = FALSE;
  612.         if (pPriv->fd >= 0) {
  613.         RemoveEnabledDevice(pPriv->fd);
  614.         (void) close(pPriv->fd);
  615.         }
  616.         pPriv->fd = -1;
  617.         pPriv->cap = 0;
  618. #ifdef X11R4
  619.         if (motionBuf)
  620.         Xfree(motionBuf);
  621.         motionBuf = motionTail = NULL;
  622. #endif /* X11R4 */
  623.         break;
  624.     case DEVICE_OFF:
  625.         pMouse->on = FALSE;
  626.         if (pPriv->fd >= 0)
  627.         RemoveEnabledDevice(pPriv->fd);
  628.         break;
  629.     }
  630.     return(Success);
  631. }
  632.  
  633. #ifdef X11R4
  634.  
  635. static
  636. mouse_event(pMouse, pQ)
  637. DevicePtr    pMouse;
  638. mouseQ_t    *pQ;
  639. {
  640.     xEvent        mevent;
  641.     int            i;
  642.     int            nbuttons;
  643.     MousePrivPtr    pPriv;
  644.  
  645.     lastEventTime = pQ->time;
  646.     pPriv = (MousePrivPtr) pMouse->devicePrivate;
  647.  
  648.     /* a motion event? do cursor chase */
  649.  
  650.     if (pQ->dx || pQ->dy) {
  651.     miPointerPosition(screenInfo.screens[0], &pPriv->rootX, &pPriv->rootY);
  652.     pPriv->rootX += pQ->dx;
  653.     pPriv->rootY += pQ->dy;
  654.     miPointerDeltaCursor(screenInfo.screens[0], pQ->dx, pQ->dy, TRUE);
  655.  
  656.     if (motionBuf) {
  657.         motionTail++;
  658.         if (motionTail == (motionBuf + motionBufferSize))
  659.         motionTail = motionBuf;
  660.         motionTail->time = lastEventTime;
  661.         motionTail->x = pPriv->rootX;
  662.         motionTail->y = pPriv->rootY;
  663.     }
  664.     }
  665.  
  666.     /* button change state? notify server. */
  667.  
  668.     if (nbuttons = pQ->bmask ^ pPriv->buttonstate) {
  669.     mevent.u.keyButtonPointer.time = lastEventTime;
  670.     for(i=0;i<NBUTTONS;i++)
  671.         if (pPriv->buttonmap[i].mask&nbuttons) {
  672.         mevent.u.u.type =
  673.             (pQ->bmask & pPriv->buttonmap[i].mask) ?
  674.             ButtonPress : ButtonRelease;
  675.         mevent.u.u.detail = pPriv->buttonmap[i].val;
  676.         (*pMouse->processInputProc)(&mevent, pMouse, 1);
  677.         }
  678.     }
  679.  
  680.     pPriv->buttonstate = pQ->bmask;
  681. }
  682.  
  683. #else /* X11R4 */
  684.  
  685. static int
  686. mouseAccel(pMouse, d)
  687. DevicePtr    pMouse;
  688. int        d;
  689. {
  690.     PtrCtrl *pctrl;
  691.  
  692.     pctrl = &((DeviceIntPtr) pMouse)->ptrfeed->ctrl;
  693.     if (d > 0)
  694.     return((d > pctrl->threshold) ? (d * pctrl->num) / pctrl->den : d);
  695.     else
  696.     return((-d > pctrl->threshold) ? (d * pctrl->num) / pctrl->den : d);
  697. }
  698.  
  699. static
  700. mouseEvent(pMouse, dx, dy, bmask, time)
  701. DevicePtr    pMouse;
  702. int        dx, dy, bmask;
  703. {
  704.     xEvent        mevent;
  705.     int            i;
  706.     int            nbuttons;
  707.     MousePrivPtr    pPriv;
  708.  
  709.     lastEventTime = time;
  710.     pPriv = (MousePrivPtr) pMouse->devicePrivate;
  711.  
  712.     /* a motion event? do cursor chase */
  713.  
  714.     if (dx || dy)
  715.     {
  716.     dx = mouseAccel (pMouse, dx);
  717.     dy = mouseAccel (pMouse, dy);
  718.     miPointerDeltaCursor (dx, dy, time);
  719.     }
  720.  
  721.     /* button change state? notify server. */
  722.  
  723.     if (nbuttons = bmask ^ pPriv->buttonstate) {
  724.     mevent.u.keyButtonPointer.time = lastEventTime;
  725.     for(i=0;i<NBUTTONS;i++)
  726.         if (pPriv->buttonmap[i].mask&nbuttons) {
  727.         mevent.u.u.type =
  728.             (bmask & pPriv->buttonmap[i].mask) ?
  729.             ButtonPress : ButtonRelease;
  730.         mevent.u.u.detail = pPriv->buttonmap[i].val;
  731.         mieqEnqueue (&mevent);
  732.         }
  733.     }
  734.  
  735.     pPriv->buttonstate = bmask;
  736. }
  737.  
  738. #endif /* X11R4 */
  739.