in the driver private, and explicitly cancel it if the server decides to close the device for real. - evdev-2.0.4-cache-info.patch: Rebase to account for same.
200 lines
6.3 KiB
Diff
200 lines
6.3 KiB
Diff
diff -up xf86-input-evdev-2.0.4/src/evdev.c.jx xf86-input-evdev-2.0.4/src/evdev.c
|
|
--- xf86-input-evdev-2.0.4/src/evdev.c.jx 2008-09-12 16:04:34.000000000 -0400
|
|
+++ xf86-input-evdev-2.0.4/src/evdev.c 2008-09-12 16:04:56.000000000 -0400
|
|
@@ -98,6 +98,7 @@ static const char *evdevDefaults[] = {
|
|
};
|
|
|
|
static int EvdevOn(DeviceIntPtr);
|
|
+static int EvdevCacheCompare(InputInfoPtr pInfo, Bool compare);
|
|
|
|
static void
|
|
SetXkbOption(InputInfoPtr pInfo, char *name, char **option)
|
|
@@ -176,12 +177,19 @@ EvdevReopenTimer(OsTimerPtr timer, CARD3
|
|
|
|
if (pInfo->fd != -1)
|
|
{
|
|
- xf86Msg(X_INFO, "%s: Device reopened after %d attempts.\n", pInfo->name,
|
|
- pEvdev->reopen_attempts - pEvdev->reopen_left);
|
|
-
|
|
pEvdev->reopen_left = 0;
|
|
pEvdev->reopen_timer = NULL;
|
|
- EvdevOn(pInfo->dev);
|
|
+ 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);
|
|
+ }
|
|
return 0;
|
|
}
|
|
|
|
@@ -370,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
|
|
@@ -1000,6 +1006,116 @@ EvdevConvert(InputInfoPtr pInfo, int fir
|
|
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)
|
|
+{
|
|
+ int i;
|
|
+ EvdevPtr pEvdev = pInfo->private;
|
|
+ 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)
|
|
{
|
|
@@ -1179,6 +1295,8 @@ EvdevPreInit(InputDriverPtr drv, IDevPtr
|
|
return NULL;
|
|
}
|
|
|
|
+ EvdevCacheCompare(pInfo, FALSE); /* cache device data */
|
|
+
|
|
return pInfo;
|
|
}
|
|
|
|
diff -up xf86-input-evdev-2.0.4/src/evdev.h.jx xf86-input-evdev-2.0.4/src/evdev.h
|
|
--- xf86-input-evdev-2.0.4/src/evdev.h.jx 2008-09-12 16:04:34.000000000 -0400
|
|
+++ xf86-input-evdev-2.0.4/src/evdev.h 2008-09-12 16:04:56.000000000 -0400
|
|
@@ -40,6 +40,9 @@
|
|
#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;
|
|
@@ -72,6 +75,15 @@ typedef struct {
|
|
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 */
|