[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

xserver-xorg-input-evdev: Changes to 'upstream-unstable'



 configure.ac  |    2 
 man/evdev.man |    5 +
 src/evdev.c   |  289 +++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 src/evdev.h   |   16 +++
 4 files changed, 288 insertions(+), 24 deletions(-)

New commits:
commit 891bfc56be3c45d085f4b6abd5bd265e82b8c353
Author: Peter Hutterer <peter.hutterer@redhat.com>
Date:   Tue Nov 18 17:16:33 2008 +1000

    evdev 2.0.8
    
    Expect this to be the last 2.0.x release.

diff --git a/configure.ac b/configure.ac
index 900cbb4..5f8b565 100644
--- a/configure.ac
+++ b/configure.ac
@@ -22,7 +22,7 @@
 
 AC_PREREQ(2.57)
 AC_INIT([xf86-input-evdev],
-        2.0.7,
+        2.0.8,
         [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
         xf86-input-evdev)
 

commit 6626ad5cb9a9fab9bd3c3d8a36d8b09b8cb037a0
Author: Julien Cristau <jcristau@debian.org>
Date:   Tue Oct 21 19:21:21 2008 +0200

    Fix TestBit() on 64bit
    
    Reported by Albert Damen <albrt@gmx.net>
    X.Org Bug#18150 <http://bugs.freedesktop.org/show_bug.cgi?id=18150>
    (cherry picked from commit f57e8face94c9e6986b35ca2ec231e284b9f58cf)

diff --git a/src/evdev.c b/src/evdev.c
index 3d7a76f..d186be0 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -381,7 +381,7 @@ EvdevReadInput(InputInfoPtr pInfo)
     }
 }
 
-#define TestBit(bit, array) (array[(bit) / LONG_BITS]) & (1 << ((bit) % LONG_BITS))
+#define TestBit(bit, array) (array[(bit) / LONG_BITS]) & (1L << ((bit) % LONG_BITS))
 
 static void
 EvdevPtrCtrlProc(DeviceIntPtr device, PtrCtrl *ctrl)

commit ae247ff09cb77d8e6ebc4505b44731e32b3a179b
Author: Peter Hutterer <peter.hutterer@redhat.com>
Date:   Fri Oct 17 11:42:21 2008 +1030

    evdev 2.0.7

diff --git a/configure.ac b/configure.ac
index e7198da..900cbb4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -22,7 +22,7 @@
 
 AC_PREREQ(2.57)
 AC_INIT([xf86-input-evdev],
-        2.0.6,
+        2.0.7,
         [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
         xf86-input-evdev)
 

commit 46f2b83e0130da2260559ad63f75dbf9c00bb83c
Author: Peter Hutterer <peter.hutterer@who-t.net>
Date:   Thu Oct 16 22:35:42 2008 +1030

    Don't post keycodes > 255.
    
    If we only have keys > 255 we don't set up a key class rec, so don't post
    them. It makes the server unhappy.
    
    Signed-off-by: Julien Cristau <jcristau@debian.org>
    (cherry picked from commit 7243116f55609a2a5f73bb88cf6ad6386c9bbc0b)

diff --git a/src/evdev.c b/src/evdev.c
index 019d70d..3d7a76f 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -155,6 +155,10 @@ PostKbdEvent(InputInfoPtr pInfo, struct input_event *ev, int value)
 	warned[ev->code] = 1;
     }
 
+    /* The X server can't handle keycodes > 255 anyway, just drop them.  */
+    if (code > 255)
+        return;
+
     xf86PostKeyboardEvent(pInfo->dev, code, value);
 }
 

commit d73a1732c6a2c093f76bdc5f32b3a53fdef92b15
Author: Peter Hutterer <peter.hutterer@redhat.com>
Date:   Tue Oct 14 17:02:43 2008 +1030

    Fix "Device reopened after N attempts" message.
    (cherry picked from commit 0089d931ac5fb290c82908da652b28c8b515d449)

diff --git a/src/evdev.c b/src/evdev.c
index 6958578..019d70d 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -176,12 +176,10 @@ EvdevReopenTimer(OsTimerPtr timer, CARD32 time, pointer arg)
 
     if (pInfo->fd != -1)
     {
-        pEvdev->reopen_left = 0;
-
         if (EvdevCacheCompare(pInfo, TRUE) == Success)
         {
             xf86Msg(X_INFO, "%s: Device reopened after %d attempts.\n", pInfo->name,
-                    pEvdev->reopen_attempts - pEvdev->reopen_left);
+                    pEvdev->reopen_attempts - pEvdev->reopen_left + 1);
             EvdevOn(pInfo->dev);
         } else
         {
@@ -191,6 +189,7 @@ EvdevReopenTimer(OsTimerPtr timer, CARD32 time, pointer arg)
             close(pInfo->fd);
             pInfo->fd = -1;
         }
+        pEvdev->reopen_left = 0;
         return 0;
     }
 

commit 8c332a836783b4f18b992253f4a94b694c9d0cf1
Author: Julien Cristau <jcristau@debian.org>
Date:   Sat Oct 11 02:10:48 2008 +0200

    Set pInfo->fd to -1 on DEVICE_CLOSE
    
    This allows the reopen logic to kick in later.
    DEVICE_CLOSE gets called on regen, so without this we'd keep a stale
    file descriptor in pInfo->fd in subsequent sessions.
    
    Debian bug#496101 (http://bugs.debian.org/496101)
    (cherry picked from commit b0b6399023bcdbb3337027f85c8da42d8b18c983)

diff --git a/src/evdev.c b/src/evdev.c
index b12f2ff..6958578 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -986,8 +986,10 @@ EvdevProc(DeviceIntPtr device, int what)
 
     case DEVICE_CLOSE:
 	xf86Msg(X_INFO, "%s: Close\n", pInfo->name);
-        if (pInfo->fd != -1)
+        if (pInfo->fd != -1) {
             close(pInfo->fd);
+            pInfo->fd = -1;
+        }
 	break;
     }
 

commit 91e30bb07cadb41c99b0515d8ecb49f7b045e90c
Author: Peter Hutterer <peter.hutterer@redhat.com>
Date:   Thu Oct 2 12:05:14 2008 +0930

    evdev 2.0.6

diff --git a/configure.ac b/configure.ac
index f465f06..e7198da 100644
--- a/configure.ac
+++ b/configure.ac
@@ -22,7 +22,7 @@
 
 AC_PREREQ(2.57)
 AC_INIT([xf86-input-evdev],
-        2.0.5,
+        2.0.6,
         [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
         xf86-input-evdev)
 

commit 36d9b9f166a700d47322961d1768a6b8d6d5545c
Author: Peter Hutterer <peter.hutterer@redhat.com>
Date:   Thu Oct 2 10:56:04 2008 +0930

    Close fd on DEVICE_OFF. (LP #276887)
    
    Leaving the fd open means we still get keyboard events after VT switching
    away. Coming back, some of these events are replayed on the application that
    has the current focus.
    
    Reproduceable:
    1. open terminal, focus.
    2. VT switch away
    3. type something, preferably a password
    4. VT switch back, trigger a mouse event
    5. Observe the X server guessing your password.
    
    Closing the fd on DEVICE_OFF fixes this. Reopen is handled by the reopen
    code introduced with
    
        commit 9930477cbeb4acfd070ae70894d13ffabfc347b8
        Author: Peter Hutterer <peter.hutterer@redhat.com>
        Date:   Tue Aug 26 14:33:40 2008 +0930
    
            Attempt to re-open devices on read errors.
    
    Launchpad Bug 276887
    <https://bugs.edge.launchpad.net/ubuntu/+source/xorg-server/+bug/276887>
    (cherry picked from commit ccd48d2f50231e2837e0984833641ac79f327ba4)

diff --git a/src/evdev.c b/src/evdev.c
index c0fe244..b12f2ff 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -970,6 +970,8 @@ EvdevProc(DeviceIntPtr device, int what)
                 xf86Msg(X_WARNING, "%s: Release failed (%s)\n", pInfo->name,
                         strerror(errno));
             xf86RemoveEnabledDevice(pInfo);
+            close(pInfo->fd);
+            pInfo->fd = -1;
         }
         if (pEvdev->flags & EVDEV_INITIALIZED)
             EvdevMBEmuFinalize(pInfo);

commit 69f01976f1ba36e995809d8a91e4010d7a0f56ba
Author: Peter Hutterer <peter.hutterer@redhat.com>
Date:   Fri Sep 19 09:32:08 2008 +0930

    evdev 2.0.5

diff --git a/configure.ac b/configure.ac
index a04f694..f465f06 100644
--- a/configure.ac
+++ b/configure.ac
@@ -22,7 +22,7 @@
 
 AC_PREREQ(2.57)
 AC_INIT([xf86-input-evdev],
-        2.0.4,
+        2.0.5,
         [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
         xf86-input-evdev)
 

commit 32768f8acd49f49a3daa7965fc2672ca13306780
Author: Peter Hutterer <peter.hutterer@redhat.com>
Date:   Thu Sep 4 18:41:13 2008 +0930

    Attempt to re-open devices on read errors.
    
    Coming back from resume may leave us with a file descriptor that can be opened
    but fails on the first read (ENODEV).
    In this case, try to open the device until it becomes available or until the
    predefined count expires. To be safe, we cache the information from the device
    and compare against it when we re-open. This way we ensure that if the
    topology changes under us, we don't open a completely different device. If a
    device has changed, we disable it.
    
    Adds option "ReopenAttempts" <int>
    
    Conflicts:
    
    	man/evdev.man
    	src/evdev.c
    	src/evdev.h

diff --git a/man/evdev.man b/man/evdev.man
index f438f78..530f979 100644
--- a/man/evdev.man
+++ b/man/evdev.man
@@ -67,6 +67,11 @@ button event is registered.
 Sets the timeout (in milliseconds) that the driver waits before deciding
 if two buttons where pressed "simultaneously" when 3 button emulation is
 enabled.  Default: 50.
+.TP 7
+.BI "Option \*qReopenAttempts\*q \*q" integer \*q
+Number of reopen attempts after a read error occurs on the device (e.g. after
+waking up from suspend). In between each attempt is a 100ms wait. Default: 10.
+
 .SH AUTHORS
 Kristian Høgsberg.
 .SH "SEE ALSO"
diff --git a/src/evdev.c b/src/evdev.c
index a857db3..c0fe244 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -73,6 +73,7 @@
 #define EVDEV_RELATIVE_EVENTS	(1 << 2)
 #define EVDEV_ABSOLUTE_EVENTS	(1 << 3)
 #define EVDEV_TOUCHPAD		(1 << 4)
+#define EVDEV_INITIALIZED	(1 << 5) /* WheelInit etc. called already? */
 
 #define MIN_KEYCODE 8
 #define GLYPHS_PER_KEY 2
@@ -96,6 +97,9 @@ static const char *evdevDefaults[] = {
     NULL
 };
 
+static int EvdevOn(DeviceIntPtr);
+static int EvdevCacheCompare(InputInfoPtr pInfo, Bool compare);
+
 static void
 SetXkbOption(InputInfoPtr pInfo, char *name, char **option)
 {
@@ -154,6 +158,55 @@ PostKbdEvent(InputInfoPtr pInfo, struct input_event *ev, int value)
     xf86PostKeyboardEvent(pInfo->dev, code, value);
 }
 
+/**
+ * Coming back from resume may leave us with a file descriptor that can be
+ * opened but fails on the first read (ENODEV).
+ * In this case, try to open the device until it becomes available or until
+ * the predefined count expires.
+ */
+static CARD32
+EvdevReopenTimer(OsTimerPtr timer, CARD32 time, pointer arg)
+{
+    InputInfoPtr pInfo = (InputInfoPtr)arg;
+    EvdevPtr pEvdev = pInfo->private;
+
+    do {
+        pInfo->fd = open(pEvdev->device, O_RDWR, 0);
+    } while (pInfo->fd < 0 && errno == EINTR);
+
+    if (pInfo->fd != -1)
+    {
+        pEvdev->reopen_left = 0;
+
+        if (EvdevCacheCompare(pInfo, TRUE) == Success)
+        {
+            xf86Msg(X_INFO, "%s: Device reopened after %d attempts.\n", pInfo->name,
+                    pEvdev->reopen_attempts - pEvdev->reopen_left);
+            EvdevOn(pInfo->dev);
+        } else
+        {
+            xf86Msg(X_ERROR, "%s: Device has changed - disabling.\n",
+                    pInfo->name);
+            DisableDevice(pInfo->dev);
+            close(pInfo->fd);
+            pInfo->fd = -1;
+        }
+        return 0;
+    }
+
+    pEvdev->reopen_left--;
+
+    if (!pEvdev->reopen_left)
+    {
+        xf86Msg(X_ERROR, "%s: Failed to reopen device after %d attempts.\n",
+                pInfo->name, pEvdev->reopen_attempts);
+        DisableDevice(pInfo->dev);
+        return 0;
+    }
+
+    return 100; /* come back in 100 ms */
+}
+
 static void
 EvdevReadInput(InputInfoPtr pInfo)
 {
@@ -173,6 +226,15 @@ EvdevReadInput(InputInfoPtr pInfo)
             /* The kernel promises that we always only read a complete
              * event, so len != sizeof ev is an error. */
             xf86Msg(X_ERROR, "%s: Read error: %s\n", pInfo->name, strerror(errno));
+
+            if (errno == ENODEV) /* May happen after resume */
+            {
+                xf86RemoveEnabledDevice(pInfo);
+                close(pInfo->fd);
+                pInfo->fd = -1;
+                pEvdev->reopen_left = pEvdev->reopen_attempts;
+                pEvdev->reopen_timer = TimerSet(NULL, 0, 100, EvdevReopenTimer, pInfo);
+            }
             break;
         }
 
@@ -316,8 +378,6 @@ EvdevReadInput(InputInfoPtr pInfo)
     }
 }
 
-#define LONG_BITS (sizeof(long) * 8)
-#define NBITS(x) (((x) + LONG_BITS - 1) / LONG_BITS)
 #define TestBit(bit, array) (array[(bit) / LONG_BITS]) & (1 << ((bit) % LONG_BITS))
 
 static void
@@ -836,6 +896,56 @@ EvdevInit(DeviceIntPtr device)
     return Success;
 }
 
+/**
+ * Init all extras (wheel emulation, etc.) and grab the device.
+ *
+ * Coming from a resume, the grab may fail with ENODEV. In this case, we set a
+ * timer to wake up and try to reopen the device later.
+ */
+static int
+EvdevOn(DeviceIntPtr device)
+{
+    InputInfoPtr pInfo;
+    EvdevPtr pEvdev;
+    int rc = 0;
+
+    pInfo = device->public.devicePrivate;
+    pEvdev = pInfo->private;
+
+    if (pInfo->fd != -1 && !pEvdev->kernel24 &&
+        (rc = ioctl(pInfo->fd, EVIOCGRAB, (void *)1)))
+    {
+        xf86Msg(X_WARNING, "%s: Grab failed (%s)\n", pInfo->name,
+                strerror(errno));
+
+        /* ENODEV - device has disappeared after resume */
+        if (rc && errno == ENODEV)
+        {
+            close(pInfo->fd);
+            pInfo->fd = -1;
+        }
+    }
+
+    if (pInfo->fd == -1)
+    {
+        pEvdev->reopen_left = pEvdev->reopen_attempts;
+        pEvdev->reopen_timer = TimerSet(NULL, 0, 100, EvdevReopenTimer, pInfo);
+    } else
+    {
+        xf86AddEnabledDevice(pInfo);
+        if ((pEvdev->flags & EVDEV_BUTTON_EVENTS) &&
+            !(pEvdev->flags & EVDEV_INITIALIZED))
+        {
+            EvdevMBEmuPreInit(pInfo);
+        }
+        pEvdev->flags |= EVDEV_INITIALIZED;
+        device->public.on = TRUE;
+    }
+
+    return Success;
+}
+
+
 static int
 EvdevProc(DeviceIntPtr device, int what)
 {
@@ -851,30 +961,31 @@ EvdevProc(DeviceIntPtr device, int what)
 	return EvdevInit(device);
 
     case DEVICE_ON:
-        if (!pEvdev->kernel24 && ioctl(pInfo->fd, EVIOCGRAB, (void *)1))
-            xf86Msg(X_WARNING, "%s: Grab failed (%s)\n", pInfo->name,
-                    strerror(errno));
-        if (errno != ENODEV)
-        {
-            xf86AddEnabledDevice(pInfo);
-            if (pEvdev->flags & EVDEV_BUTTON_EVENTS)
-                EvdevMBEmuPreInit(pInfo);
-            device->public.on = TRUE;
-        }
-	break;
+        return EvdevOn(device);
 
     case DEVICE_OFF:
-        if (!pEvdev->kernel24 && ioctl(pInfo->fd, EVIOCGRAB, (void *)0))
-            xf86Msg(X_WARNING, "%s: Release failed (%s)\n", pInfo->name,
-                    strerror(errno));
-        xf86RemoveEnabledDevice(pInfo);
-        EvdevMBEmuFinalize(pInfo);
+        if (pInfo->fd != -1)
+        {
+            if (!pEvdev->kernel24 && ioctl(pInfo->fd, EVIOCGRAB, (void *)0))
+                xf86Msg(X_WARNING, "%s: Release failed (%s)\n", pInfo->name,
+                        strerror(errno));
+            xf86RemoveEnabledDevice(pInfo);
+        }
+        if (pEvdev->flags & EVDEV_INITIALIZED)
+            EvdevMBEmuFinalize(pInfo);
+        pEvdev->flags &= ~EVDEV_INITIALIZED;
 	device->public.on = FALSE;
+        if (pEvdev->reopen_timer)
+        {
+            TimerFree(pEvdev->reopen_timer);
+            pEvdev->reopen_timer = NULL;
+        }
 	break;
 
     case DEVICE_CLOSE:
 	xf86Msg(X_INFO, "%s: Close\n", pInfo->name);
-	close(pInfo->fd);
+        if (pInfo->fd != -1)
+            close(pInfo->fd);
 	break;
     }
 
@@ -904,6 +1015,116 @@ EvdevConvert(InputInfoPtr pInfo, int first, int num, int v0, int v1, int v2,
 
     return TRUE;
 }
+/**
+ * Get as much information as we can from the fd and cache it.
+ * If compare is True, then the information retrieved will be compared to the
+ * one already cached. If the information does not match, then this function
+ * returns an error.
+ *
+ * @return Success if the information was cached, or !Success otherwise.
+ */
+static int
+EvdevCacheCompare(InputInfoPtr pInfo, Bool compare)
+{
+    EvdevPtr pEvdev = pInfo->private;
+    int i;
+
+    char name[1024]                  = {0};
+    long bitmask[NBITS(EV_MAX)]      = {0};
+    long key_bitmask[NBITS(KEY_MAX)] = {0};
+    long rel_bitmask[NBITS(REL_MAX)] = {0};
+    long abs_bitmask[NBITS(ABS_MAX)] = {0};
+    long led_bitmask[NBITS(LED_MAX)] = {0};
+    struct input_absinfo absinfo[ABS_MAX];
+
+    if (ioctl(pInfo->fd,
+              EVIOCGNAME(sizeof(name) - 1), name) < 0) {
+        xf86Msg(X_ERROR, "ioctl EVIOCGNAME failed: %s\n", strerror(errno));
+        goto error;
+    }
+
+    if (compare && strcmp(pEvdev->name, name))
+        goto error;
+
+    if (ioctl(pInfo->fd,
+              EVIOCGBIT(0, sizeof(bitmask)), bitmask) < 0) {
+        xf86Msg(X_ERROR, "ioctl EVIOCGNAME failed: %s\n", strerror(errno));
+        goto error;
+    }
+
+    if (compare && memcmp(pEvdev->bitmask, bitmask, sizeof(bitmask)))
+        goto error;
+
+
+    if (ioctl(pInfo->fd,
+              EVIOCGBIT(EV_REL, sizeof(rel_bitmask)), rel_bitmask) < 0) {
+        xf86Msg(X_ERROR, "ioctl EVIOCGBIT failed: %s\n", strerror(errno));
+        goto error;
+    }
+
+    if (compare && memcmp(pEvdev->rel_bitmask, rel_bitmask, sizeof(rel_bitmask)))
+        goto error;
+
+    if (ioctl(pInfo->fd,
+              EVIOCGBIT(EV_ABS, sizeof(abs_bitmask)), abs_bitmask) < 0) {
+        xf86Msg(X_ERROR, "ioctl EVIOCGBIT failed: %s\n", strerror(errno));
+        goto error;
+    }
+
+    if (compare && memcmp(pEvdev->abs_bitmask, abs_bitmask, sizeof(abs_bitmask)))
+        goto error;
+
+    if (ioctl(pInfo->fd,
+              EVIOCGBIT(EV_KEY, sizeof(key_bitmask)), key_bitmask) < 0) {
+        xf86Msg(X_ERROR, "ioctl EVIOCGBIT failed: %s\n", strerror(errno));
+        goto error;
+    }
+
+    if (compare && memcmp(pEvdev->key_bitmask, key_bitmask, sizeof(key_bitmask)))
+        goto error;
+
+    if (ioctl(pInfo->fd,
+              EVIOCGBIT(EV_LED, sizeof(led_bitmask)), led_bitmask) < 0) {
+        xf86Msg(X_ERROR, "ioctl EVIOCGBIT failed: %s\n", strerror(errno));
+        goto error;
+    }
+
+    if (compare && memcmp(pEvdev->led_bitmask, led_bitmask, sizeof(led_bitmask)))
+        goto error;
+
+    memset(absinfo, 0, sizeof(absinfo));
+
+    for (i = 0; i < ABS_MAX; i++)
+    {
+        if (TestBit(i, abs_bitmask))
+        {
+            if (ioctl(pInfo->fd, EVIOCGABS(i), &absinfo[i]) < 0) {
+                xf86Msg(X_ERROR, "ioctl EVIOCGABS failed: %s\n", strerror(errno));
+                goto error;
+            }
+        }
+    }
+
+    if (compare && memcmp(pEvdev->absinfo, absinfo, sizeof(absinfo)))
+            goto error;
+
+    /* cache info */
+    if (!compare)
+    {
+        strcpy(pEvdev->name, name);
+        memcpy(pEvdev->bitmask, bitmask, sizeof(bitmask));
+        memcpy(pEvdev->key_bitmask, key_bitmask, sizeof(key_bitmask));
+        memcpy(pEvdev->rel_bitmask, rel_bitmask, sizeof(rel_bitmask));
+        memcpy(pEvdev->abs_bitmask, abs_bitmask, sizeof(abs_bitmask));
+        memcpy(pEvdev->led_bitmask, led_bitmask, sizeof(led_bitmask));
+        memcpy(pEvdev->absinfo, absinfo, sizeof(absinfo));
+    }
+
+    return Success;
+
+error:
+    return !Success;
+}
 
 static int
 EvdevProbe(InputInfoPtr pInfo)
@@ -1060,11 +1281,12 @@ EvdevPreInit(InputDriverPtr drv, IDevPtr dev, int flags)
         return NULL;
     }
 
+    pEvdev->device = device;
+
     xf86Msg(deviceFrom, "%s: Device: \"%s\"\n", pInfo->name, device);
     do {
         pInfo->fd = open(device, O_RDWR, 0);
-    }
-    while (pInfo->fd < 0 && errno == EINTR);
+    } while (pInfo->fd < 0 && errno == EINTR);
 
     if (pInfo->fd < 0) {
         xf86Msg(X_ERROR, "Unable to open evdev device \"%s\".\n", device);
@@ -1072,6 +1294,8 @@ EvdevPreInit(InputDriverPtr drv, IDevPtr dev, int flags)
         return NULL;
     }
 
+    pEvdev->reopen_attempts = xf86SetIntOption(pInfo->options, "ReopenAttempts", 10);
+
     pEvdev->noXkb = noXkbExtension;
     /* parse the XKB options during kbd setup */
 
@@ -1081,6 +1305,8 @@ EvdevPreInit(InputDriverPtr drv, IDevPtr dev, int flags)
         return NULL;
     }
 
+    EvdevCacheCompare(pInfo, FALSE); /* cache device data */
+
     return pInfo;
 }
 
diff --git a/src/evdev.h b/src/evdev.h
index cad1eed..9f16b81 100644
--- a/src/evdev.h
+++ b/src/evdev.h
@@ -40,7 +40,11 @@
 #include <X11/extensions/XKBstr.h>
 #endif
 
+#define LONG_BITS (sizeof(long) * 8)
+#define NBITS(x) (((x) + LONG_BITS - 1) / LONG_BITS)
+
 typedef struct {
+    const char *device;
     int kernel24;
     int screen;
     int min_x, min_y, max_x, max_y;
@@ -67,6 +71,18 @@ typedef struct {
         Time                expires;     /* time of expiry */
         Time                timeout;
     } emulateMB;
+    int reopen_attempts; /* max attempts to re-open after read failure */
+    int reopen_left;     /* number of attempts left to re-open the device */
+    OsTimerPtr reopen_timer;
+
+    /* Cached info from device. */
+    char name[1024];
+    long bitmask[NBITS(EV_MAX)];
+    long key_bitmask[NBITS(KEY_MAX)];
+    long rel_bitmask[NBITS(REL_MAX)];
+    long abs_bitmask[NBITS(ABS_MAX)];
+    long led_bitmask[NBITS(LED_MAX)];
+    struct input_absinfo absinfo[ABS_MAX];
 } EvdevRec, *EvdevPtr;
 
 /* Middle Button emulation */

commit ed1382866c54ffa34e3d0352ad65414650497f78
Author: Peter Hutterer <peter.hutterer@redhat.com>
Date:   Thu Aug 14 23:17:16 2008 +0930

    evdev 2.0.4

diff --git a/configure.ac b/configure.ac
index 251c431..a04f694 100644
--- a/configure.ac
+++ b/configure.ac
@@ -22,7 +22,7 @@
 
 AC_PREREQ(2.57)
 AC_INIT([xf86-input-evdev],
-        2.0.3,
+        2.0.4,
         [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
         xf86-input-evdev)
 

commit 8fe38b228702bddebe26a6d2c5c170a2a91d6ebc
Author: Adam Jackson <ajax@redhat.com>
Date:   Thu Aug 7 09:21:26 2008 +0930

    Print a warning if a keycode exceeds the range accepted by the server.
    
    Keycodes over 255 are silently ignored in the server. The least we can do is
    put a warning in the logs.
    
    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
    (cherry picked from commit c1f7f8c3d22ecae7839f82ea8b584069f54f1f5e)

diff --git a/src/evdev.c b/src/evdev.c
index 164346a..a857db3 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -131,6 +131,9 @@ PostButtonClicks(InputInfoPtr pInfo, int button, int count)
 static void
 PostKbdEvent(InputInfoPtr pInfo, struct input_event *ev, int value)
 {
+    int code = ev->code + MIN_KEYCODE;
+    static char warned[KEY_MAX];
+
     /* filter repeat events for chording keys */
     if (value == 2 &&
         (ev->code == KEY_LEFTCTRL || ev->code == KEY_RIGHTCTRL ||
@@ -141,7 +144,14 @@ PostKbdEvent(InputInfoPtr pInfo, struct input_event *ev, int value)
          ev->code == KEY_SCROLLLOCK)) /* XXX windows keys? */
         return;
 
-    xf86PostKeyboardEvent(pInfo->dev, ev->code + MIN_KEYCODE, value);
+    if (code > 255 && ev->code < KEY_MAX) {
+	if (!warned[ev->code])
+	    xf86Msg(X_WARNING, "%s: unable to handle keycode %d\n",
+		    pInfo->name, ev->code);
+	warned[ev->code] = 1;
+    }
+
+    xf86PostKeyboardEvent(pInfo->dev, code, value);
 }
 
 static void


Reply to: