--- programs/Xserver/hw/tinyx/linux/mouse.c.old Thu Nov  2 21:51:21 2006
+++ programs/Xserver/hw/tinyx/linux/mouse.c     Thu Jun 11 03:55:09 2009
@@ -1,5 +1,5 @@
/*
- * $XFree86: xc/programs/Xserver/hw/tinyx/linux/mouse.c,v 1.3 2006/11/02 21:55:26 tsi Exp $
+ * $RCSId: xc/programs/Xserver/hw/kdrive/linux/mouse.c,v 1.6 2002/08/02 16:11:35 keithp Exp $
 *
 * Copyright � 2001 Keith Packard, member of The XFree86 Project, Inc.
 *
@@ -68,19 +68,23 @@
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
#define NEED_EVENTS
#include <X11/X.h>
#include <X11/Xproto.h>
#include "inputstr.h"
#include "scrnintstr.h"
#include "tinyx.h"
-#include <X11/Xpoll.h>
#include <errno.h>
+#include <X11/Xpoll.h>
#include <termios.h>

#undef DEBUG
#undef DEBUG_BYTES
#define KBUFIO_SIZE 256
+#define MOUSE_TIMEOUT  100

typedef struct _kbufio {
    int                    fd;
@@ -95,20 +99,32 @@
    fd_set         set;
    struct timeval  tv, *tp;
    int                    n;
+    CARD32         done;

-    FD_ZERO (&set);
-    FD_SET (fd, &set);
-    if (timeout == -1)
-       tp = 0;
-    else
+    done = GetTimeInMillis () + timeout;
+    for (;;)
    {
-       tv.tv_sec = timeout / 1000;
-       tv.tv_usec = (timeout % 1000) * 1000;
-       tp = &tv;
+       FD_ZERO (&set);
+       FD_SET (fd, &set);
+       if (timeout == -1)
+           tp = 0;
+       else
+       {
+           tv.tv_sec = timeout / 1000;
+           tv.tv_usec = (timeout % 1000) * 1000;
+           tp = &tv;
+       }
+       n = select (fd + 1, &set, 0, 0, tp);
+       if (n > 0)
+           return TRUE;
+       if (n < 0 && (errno == EAGAIN || errno == EINTR))
+       {
+           timeout = (int) (done - GetTimeInMillis ());
+           if (timeout > 0)
+               continue;
+       }
+       break;
    }
-    n = select (fd + 1, &set, 0, 0, tp);
-    if (n > 0)
-       return TRUE;
    return FALSE;
}

@@ -119,7 +135,12 @@
    if (b->avail <= b->used)
    {
       if (timeout && !MouseWaitForReadable (b->fd, timeout))
+       {
+#ifdef DEBUG_BYTES
+           ErrorF ("\tTimeout %d\n", timeout);
+#endif
           return -1;
+       }
       n = read (b->fd, b->buf, KBUFIO_SIZE);
       if (n <= 0)
           return -1;
@@ -132,7 +153,7 @@
    return b->buf[b->used++];
}

-#if 0
+#if NOTUSED
static int
MouseFlush (Kbufio *b, char *buf, int size)
{
@@ -169,7 +190,7 @@
       --b->used;
    return c;
}
-#endif
+#endif /* NOTUSED */

static Bool
MouseWaitForWritable (int fd, int timeout)
@@ -263,8 +284,7 @@
    unsigned long      state;  /* private per protocol, init to prot->state */
} Kmouse;

-static int
-mouseValid (KdMouseInfo *mi, unsigned char *ev, int ne)
+static int mouseValid (KdMouseInfo *mi, unsigned char *ev, int ne)
{
    Kmouse             *km = mi->driver;
    const KmouseProt   *prot = km->prot;
@@ -281,26 +301,22 @@
    return 0;
}

-static Bool
-threeComplete (KdMouseInfo *mi, unsigned char *ev, int ne)
+static Bool threeComplete (KdMouseInfo *mi, unsigned char *ev, int ne)
{
    return ne == 3;
}

-static Bool
-fourComplete (KdMouseInfo *mi, unsigned char *ev, int ne)
+static Bool fourComplete (KdMouseInfo *mi, unsigned char *ev, int ne)
{
    return ne == 4;
}

-static Bool
-fiveComplete (KdMouseInfo *mi, unsigned char *ev, int ne)
+static Bool fiveComplete (KdMouseInfo *mi, unsigned char *ev, int ne)
{
    return ne == 5;
}

-static Bool
-MouseReasonable (KdMouseInfo *mi, unsigned long flags, int dx, int dy)
+static Bool MouseReasonable (KdMouseInfo *mi, unsigned long flags, int dx, int dy)
{
    Kmouse             *km = mi->driver;

@@ -326,12 +342,12 @@
/*
 * Standard PS/2 mouse protocol
 */
-static Bool
-ps2Parse (KdMouseInfo *mi, unsigned char *ev, int ne)
+static Bool ps2Parse (KdMouseInfo *mi, unsigned char *ev, int ne)
{
    Kmouse         *km = mi->driver;
    int                    dx, dy, dz;
    unsigned long   flags;
+    unsigned long   flagsrelease = 0;

    flags = KD_MOUSE_DELTA;
    if (ev[0] & 4)
@@ -344,10 +360,16 @@
    if (ne > 3)
    {
       dz = (int) (signed char) ev[3];
-       if (dz > 0)
+       if (dz < 0)
+       {
           flags |= KD_BUTTON_4;
-       else if (dz < 0)
+           flagsrelease = KD_BUTTON_4;
+       }
+       else if (dz > 0)
+       {
           flags |= KD_BUTTON_5;
+           flagsrelease = KD_BUTTON_5;
+       }
    }

    dx = ev[1];
@@ -360,7 +382,14 @@
    if (!MouseReasonable (mi, flags, dx, dy))
       return FALSE;
    if (km->stage == MouseWorking)
+    {
       KdEnqueueMouseEvent (mi, flags, dx, dy);
+       if (flagsrelease)
+       {
+           flags &= ~flagsrelease;
+           KdEnqueueMouseEvent (mi, flags, dx, dy);
+       }
+    }
    return TRUE;
}

@@ -470,7 +499,7 @@
ps2SkipInit (KdMouseInfo *mi, int ninit, Bool ret_next)
{
    Kmouse  *km = mi->driver;
-    int            c = 0;
+    int            c = -1;
    int            skipping;
    Bool    waiting;

@@ -478,7 +507,7 @@
    waiting = FALSE;
    while (ninit || ret_next)
    {
-       c = MouseReadByte (&km->iob, 100);
+       c = MouseReadByte (&km->iob, MOUSE_TIMEOUT);
       if (c == -1)
           break;
       /* look for ACK */
@@ -508,7 +537,7 @@
    int                    ninit;

    /* Send Intellimouse initialization sequence */
-    MouseWriteBytes (km->iob.fd, intelli_init, strlen ((char *)intelli_init), 100);
+    MouseWriteBytes (km->iob.fd, intelli_init, strlen (intelli_init), 100);
    /*
     * Send ID command
     */
@@ -535,7 +564,7 @@
       break;
    }
    if (init)
-       MouseWriteBytes (km->iob.fd, init, strlen ((char *)init), 100);
+       MouseWriteBytes (km->iob.fd, init, strlen (init), 100);
    /*
     * Flush out the available data to eliminate responses to the
     * initialization string.  Make sure any partial event is
@@ -545,8 +574,7 @@
    return TRUE;
}

-static Bool
-busParse (KdMouseInfo *mi, unsigned char *ev, int ne)
+static Bool busParse (KdMouseInfo *mi, unsigned char *ev, int ne)
{
    Kmouse         *km = mi->driver;
    int                    dx, dy;
@@ -579,8 +607,7 @@
 * Standard MS serial protocol, three bytes
 */

-static Bool
-msParse (KdMouseInfo *mi, unsigned char *ev, int ne)
+static Bool msParse (KdMouseInfo *mi, unsigned char *ev, int ne)
{
    Kmouse         *km = mi->driver;
    int                    dx, dy;
@@ -619,8 +646,7 @@
 * first byte of a synchronized protocol stream and see if it's got
 * any bits turned on that can't occur in that fourth byte
 */
-static Bool
-logiComplete (KdMouseInfo *mi, unsigned char *ev, int ne)
+static Bool logiComplete (KdMouseInfo *mi, unsigned char *ev, int ne)
{
    Kmouse             *km = mi->driver;

@@ -631,8 +657,7 @@
    return FALSE;
}

-static int
-logiValid (KdMouseInfo *mi, unsigned char *ev, int ne)
+static int logiValid (KdMouseInfo *mi, unsigned char *ev, int ne)
{
    Kmouse             *km = mi->driver;
    const KmouseProt   *prot = km->prot;
@@ -653,8 +678,7 @@
    return 0;
}

-static Bool
-logiParse (KdMouseInfo *mi, unsigned char *ev, int ne)
+static Bool logiParse (KdMouseInfo *mi, unsigned char *ev, int ne)
{
    Kmouse         *km = mi->driver;
    int                    dx, dy;
@@ -704,8 +728,7 @@
/*
 * Mouse systems protocol, 5 bytes
 */
-static Bool
-mscParse (KdMouseInfo *mi, unsigned char *ev, int ne)
+static Bool mscParse (KdMouseInfo *mi, unsigned char *ev, int ne)
{
    Kmouse         *km = mi->driver;
    int                    dx, dy;
@@ -878,6 +901,8 @@
           km->invalid += i + km->tested;
           km->valid = 0;
           km->tested = 0;
+           if (km->stage == MouseWorking)
+               km->i_prot--;
           km->stage = MouseBroken;
           if (km->invalid > MAX_SKIP)
           {
@@ -921,7 +946,7 @@
                               km->stage = MouseBroken;
                       }
                       break;
-                   default:
+                   case MouseWorking:
                       break;
                   }
               }
@@ -936,7 +961,7 @@
               timeout = 0;
           }
           else
-               timeout = 100;
+               timeout = MOUSE_TIMEOUT;
       }
    }
}
@@ -954,11 +979,11 @@

#define NUM_DEFAULT_MOUSE    (sizeof (kdefaultMouse) / sizeof (kdefaultMouse[0]))

-static int
+static Bool
MouseInit (void)
{
    int                i;
-    int                fd = -1;
+    int                fd;
    Kmouse     *km;
    KdMouseInfo        *mi, *next;
    int                n = 0;
@@ -977,8 +1002,6 @@
       {
           for (i = 0; i < NUM_DEFAULT_MOUSE; i++)
           {
-               if (kdNoSerialMouse && strstr(kdefaultMouse[i], "/dev/ttyS"))
-                   continue;
               fd = open (kdefaultMouse[i], 2);
               if (fd >= 0)
               {
@@ -1010,7 +1033,7 @@
               close (fd);
       }
    }
-    return n;
+    return TRUE;
}

static void