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

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



 configure.ac    |    3 
 src/Makefile.am |    4 
 src/apple.c     |    3 
 src/emuWheel.c  |    1 
 src/evdev.c     |  480 +++++++++++++++++++++++++++-----------------------------
 src/evdev.h     |   12 -
 6 files changed, 243 insertions(+), 260 deletions(-)

New commits:
commit d9aadfd5f05abd9a65977d9d36cbe159d6e05386
Author: Peter Hutterer <peter.hutterer@who-t.net>
Date:   Mon Oct 7 09:21:57 2013 +1100

    bump to 2.8.99
    
    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>

diff --git a/configure.ac b/configure.ac
index b8a9c41..c060c3a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -23,7 +23,7 @@
 # Initialize Autoconf
 AC_PREREQ([2.60])
 AC_INIT([xf86-input-evdev],
-        [2.8.1],
+        [2.8.99],
         [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
         [xf86-input-evdev])
 AC_CONFIG_SRCDIR([Makefile.am])

commit 54a3120e339e55fc4721543abb15692c3e9ede09
Author: Peter De Wachter <pdewacht@gmail.com>
Date:   Wed Mar 20 00:35:45 2013 +0100

    Map REL_DIAL to vertical scrolling
    
    This makes the absolute axis codepath behave the same as the relative axis
    path.
    
    Signed-off-by: Peter De Wachter <pdewacht@gmail.com>
    Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>

diff --git a/src/evdev.c b/src/evdev.c
index b97b841..bafe81f 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -1574,7 +1574,7 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device, int want_scroll_axes)
                                        NO_AXIS_LIMITS, NO_AXIS_LIMITS,
                                        0, 0, 0, Relative);
             SetScrollValuator(device, pEvdev->rel_axis_map[idx],
-                              SCROLL_TYPE_HORIZONTAL, 1.0,
+                              SCROLL_TYPE_VERTICAL, -1.0,
                               SCROLL_FLAG_NONE);
         }
     }

commit 164c62a97591d4c9b649460e7442977ea82ac02b
Author: Peter Hutterer <peter.hutterer@who-t.net>
Date:   Wed May 29 07:17:41 2013 +1000

    Use libevdev as backend
    
    Removes the need to ioctl manually and check bits, with all the dangers that
    come with that. libevdev is much better prepared for invalid values, OOB
    checks, etc.
    
    Plus, we get almost free SYN_DROPPED handling as well which we didn't have
    before.
    
    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
    Reviewed-by: Adam Jackson <ajax@redhat.com>

diff --git a/configure.ac b/configure.ac
index b8a9c41..2953d15 100644
--- a/configure.ac
+++ b/configure.ac
@@ -48,6 +48,7 @@ PKG_CHECK_MODULES(XORG, [xorg-server >= 1.10] xproto inputproto)
 PKG_CHECK_MODULES(UDEV, libudev)
 
 PKG_CHECK_MODULES(XI22, [inputproto >= 2.1.99.3] [xorg-server >= 1.11.99.901], HAVE_XI22="yes", HAVE_XI22="no")
+PKG_CHECK_MODULES(LIBEVDEV, [libevdev >= 0.4])
 
 if test "x$HAVE_XI22" = xyes; then
         # Obtain compiler/linker options for mtdev
diff --git a/src/Makefile.am b/src/Makefile.am
index da76540..5e0c3b3 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -26,11 +26,11 @@
 # TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc.
 
 AM_CFLAGS = $(XORG_CFLAGS) $(CWARNFLAGS)
-AM_CPPFLAGS =-I$(top_srcdir)/include
+AM_CPPFLAGS =-I$(top_srcdir)/include $(LIBEVDEV_CFLAGS)
 
 @DRIVER_NAME@_drv_la_LTLIBRARIES = @DRIVER_NAME@_drv.la
 @DRIVER_NAME@_drv_la_LDFLAGS = -module -avoid-version
-@DRIVER_NAME@_drv_la_LIBADD = $(MTDEV_LIBS) $(UDEV_LIBS)
+@DRIVER_NAME@_drv_la_LIBADD = $(MTDEV_LIBS) $(UDEV_LIBS) $(LIBEVDEV_LIBS)
 @DRIVER_NAME@_drv_ladir = @inputdir@
 
 @DRIVER_NAME@_drv_la_SOURCES = @DRIVER_NAME@.c \
diff --git a/src/apple.c b/src/apple.c
index 8e00a84..71f1dc3 100644
--- a/src/apple.c
+++ b/src/apple.c
@@ -303,7 +303,8 @@ EvdevAppleInitProperty(DeviceIntPtr dev)
     enum fkeymode fkeymode;
 
     if (!product_check(apple_keyboard_table,
-                       pEvdev->id_vendor, pEvdev->id_product))
+                       libevdev_get_id_vendor(pEvdev->dev),
+                       libevdev_get_id_product(pEvdev->dev)))
         return;
 
     fkeymode = get_fnmode();
diff --git a/src/evdev.c b/src/evdev.c
index 209ea7e..dbc5eb4 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -178,23 +178,6 @@ static int EvdevSwitchMode(ClientPtr client, DeviceIntPtr device, int mode)
     return Success;
 }
 
-static size_t EvdevCountBits(unsigned long *array, size_t nlongs)
-{
-    unsigned int i;
-    size_t count = 0;
-
-    for (i = 0; i < nlongs; i++) {
-        unsigned long x = array[i];
-
-        while (x > 0)
-        {
-            count += (x & 0x1);
-            x >>= 1;
-        }
-    }
-    return count;
-}
-
 static inline int EvdevBitIsSet(const unsigned long *array, int bit)
 {
     return !!(array[bit / LONG_BITS] & (1LL << (bit % LONG_BITS)));
@@ -433,13 +416,16 @@ EvdevSwapAbsValuators(EvdevPtr pEvdev, ValuatorMask *mask)
 
     for(i = 0; i <= 1; i++) {
         if (valuator_mask_isset(mask, i)) {
+            const struct input_absinfo *abs1 =
+                libevdev_get_abs_info(pEvdev->dev, i);
+            const struct input_absinfo *abs2 =
+                libevdev_get_abs_info(pEvdev->dev, 1 - i);
+
             swapped_isset[1 - i] = 1;
             swapped_values[1 - i] =
                 xf86ScaleAxis(valuator_mask_get(mask, i),
-                              pEvdev->absinfo[1 - i].maximum,
-                              pEvdev->absinfo[1 - i].minimum,
-                              pEvdev->absinfo[i].maximum,
-                              pEvdev->absinfo[i].minimum);
+                              abs2->maximum, abs2->minimum,
+                              abs1->maximum, abs1->minimum);
         }
     }
 
@@ -457,6 +443,7 @@ EvdevApplyCalibration(EvdevPtr pEvdev, ValuatorMask *mask)
     int i;
 
     for (i = 0; i <= 1; i++) {
+        const struct input_absinfo *abs;
         int val;
         int calib_min;
         int calib_max;
@@ -465,6 +452,7 @@ EvdevApplyCalibration(EvdevPtr pEvdev, ValuatorMask *mask)
             continue;
 
         val = valuator_mask_get(mask, i);
+        abs = libevdev_get_abs_info(pEvdev->dev, i);
 
         if (i == 0) {
             calib_min = pEvdev->calibration.min_x;
@@ -475,13 +463,11 @@ EvdevApplyCalibration(EvdevPtr pEvdev, ValuatorMask *mask)
         }
 
         if (pEvdev->flags & EVDEV_CALIBRATED)
-            val = xf86ScaleAxis(val, pEvdev->absinfo[i].maximum,
-                                pEvdev->absinfo[i].minimum, calib_max,
-                                calib_min);
+            val = xf86ScaleAxis(val, abs->maximum, abs->minimum,
+                                calib_max, calib_min);
 
         if ((i == 0 && pEvdev->invert_x) || (i == 1 && pEvdev->invert_y))
-            val = (pEvdev->absinfo[i].maximum - val +
-                   pEvdev->absinfo[i].minimum);
+            val = (abs->maximum - val + abs->minimum);
 
         valuator_mask_set(mask, i, val);
     }
@@ -762,7 +748,12 @@ EvdevProcessTouch(InputInfoPtr pInfo)
 static int
 num_slots(EvdevPtr pEvdev)
 {
-    int value = pEvdev->absinfo[ABS_MT_SLOT].maximum + 1;
+    int value;
+
+    if (pEvdev->mtdev)
+        value = pEvdev->mtdev->caps.slot.maximum + 1;
+    else
+        value = libevdev_get_num_slots(pEvdev->dev);
 
     /* If we don't know how many slots there are, assume at least 10 */
     return value > 1 ? value : 10;
@@ -782,7 +773,8 @@ EvdevProcessTouchEvent(InputInfoPtr pInfo, struct input_event *ev)
     EvdevPtr pEvdev = pInfo->private;
     int map;
 
-    if (!pEvdev->mtdev && !EvdevBitIsSet(pEvdev->abs_bitmask, ABS_MT_SLOT))
+    if (!pEvdev->mtdev &&
+        !libevdev_has_event_code(pEvdev->dev, EV_ABS, ABS_MT_SLOT))
         return;
 
     if (ev->code == ABS_MT_SLOT) {
@@ -1088,7 +1080,7 @@ EvdevFreeMasks(EvdevPtr pEvdev)
     valuator_mask_free(&pEvdev->mt_mask);
     if (pEvdev->last_mt_vals)
     {
-        for (i = 0; i < num_slots(pEvdev); i++)
+        for (i = 0; i < libevdev_get_num_slots(pEvdev->dev); i++)
             valuator_mask_free(&pEvdev->last_mt_vals[i]);
         free(pEvdev->last_mt_vals);
         pEvdev->last_mt_vals = NULL;
@@ -1098,68 +1090,60 @@ EvdevFreeMasks(EvdevPtr pEvdev)
 #endif
 }
 
+#ifdef MULTITOUCH
 static void
-EvdevProcessAllEvents(InputInfoPtr pInfo, struct input_event *ev, int nevents, size_t max_events)
+EvdevHandleMTDevEvent(InputInfoPtr pInfo, struct input_event *ev)
 {
     EvdevPtr pEvdev = pInfo->private;
-    int i, more_events_left = 0;
 
-    do {
-#ifdef MULTITOUCH
-        if (pEvdev->mtdev) {
-            int nmtevents = 0;
-            for (i = 0; i < nevents; i++)
-                mtdev_put_event(pEvdev->mtdev, &ev[i]);
-
-            while (!mtdev_empty(pEvdev->mtdev) && nmtevents < max_events)
-                mtdev_get_event(pEvdev->mtdev, &ev[nmtevents++]);
-
-            /* mtdev may have converted to more events than we have space for */
-            more_events_left = nmtevents >= max_events && !mtdev_empty(pEvdev->mtdev);
-            nevents = nmtevents;
+    mtdev_put_event(pEvdev->mtdev, ev);
+    if (libevdev_event_is_code(ev, EV_SYN, SYN_REPORT)) {
+        while (!mtdev_empty(pEvdev->mtdev)) {
+            struct input_event e;
+            mtdev_get_event(pEvdev->mtdev, &e);
+            EvdevProcessEvent(pInfo, &e);
         }
-#endif
-
-        for (i = 0; i < nevents; i++)
-            EvdevProcessEvent(pInfo, &ev[i]);
-
-        nevents = 0;
-    } while(more_events_left);
+    }
 }
-
-/* just a magic number to reduce the number of reads */
-#define NUM_EVENTS 16
+#endif
 
 static void
 EvdevReadInput(InputInfoPtr pInfo)
 {
-    struct input_event ev[NUM_EVENTS];
-    int len = sizeof(ev);
-
-    while (len == sizeof(ev))
-    {
-        len = read(pInfo->fd, &ev, sizeof(ev));
+    int rc = 0;
+    EvdevPtr pEvdev = pInfo->private;
+    struct input_event ev;
 
-        if (len <= 0)
-        {
-            if (errno == ENODEV) /* May happen after resume */
+    do {
+        rc = libevdev_next_event(pEvdev->dev, LIBEVDEV_READ_FLAG_NORMAL, &ev);
+        if (rc < 0) {
+            if (rc == -ENODEV) /* May happen after resume */
                 xf86RemoveEnabledDevice(pInfo);
-            else if (errno != EAGAIN)
+            else if (rc != -EAGAIN)
                 LogMessageVerbSigSafe(X_ERROR, 0, "%s: Read error: %s\n", pInfo->name,
-                                       strerror(errno));
+                                       strerror(-rc));
             break;
+        } else if (rc == LIBEVDEV_READ_STATUS_SUCCESS) {
+#ifdef MULTITOUCH
+            if (pEvdev->mtdev)
+                EvdevHandleMTDevEvent(pInfo, &ev);
+            else
+#endif
+                EvdevProcessEvent(pInfo, &ev);
         }
-
-        /* The kernel promises that we always only read a complete
-         * event, so len != sizeof ev is an error. */
-        if (len % sizeof(ev[0])) {
-            LogMessageVerbSigSafe(X_ERROR, 0, "%s: Read error: %s\n", pInfo->name, strerror(errno));
-            break;
+        else { /* SYN_DROPPED */
+            rc = libevdev_next_event(pEvdev->dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
+            while (rc == LIBEVDEV_READ_STATUS_SYNC) {
+#ifdef MULTITOUCH
+                if (pEvdev->mtdev)
+                    EvdevHandleMTDevEvent(pInfo, &ev);
+                else
+#endif
+                    EvdevProcessEvent(pInfo, &ev);
+                rc = libevdev_next_event(pEvdev->dev, LIBEVDEV_READ_FLAG_SYNC, &ev);
+            }
         }
-
-        EvdevProcessAllEvents(pInfo, ev, len/sizeof(ev[0]), NUM_EVENTS);
-
-    }
+    } while (rc == LIBEVDEV_READ_STATUS_SUCCESS);
 }
 
 static void
@@ -1266,7 +1250,7 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device, int want_scroll_axes)
 {
     InputInfoPtr pInfo;
     EvdevPtr pEvdev;
-    int num_axes, axis, i = 0;
+    int num_axes = 0, axis, i = 0;
     int num_mt_axes = 0, /* number of MT-only axes */
         num_mt_axes_total = 0; /* total number of MT axes, including
                                   double-counted ones, excluding blacklisted */
@@ -1276,17 +1260,20 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device, int want_scroll_axes)
     pInfo = device->public.devicePrivate;
     pEvdev = pInfo->private;
 
-    if (!EvdevBitIsSet(pEvdev->bitmask, EV_ABS))
+    if (!libevdev_has_event_type(pEvdev->dev, EV_ABS))
         goto out;
 
-    num_axes = EvdevCountBits(pEvdev->abs_bitmask, NLONGS(ABS_MAX));
+    for (i = 0; i < ABS_MAX; i++)
+        if (libevdev_has_event_code(pEvdev->dev, EV_ABS, i))
+            num_axes++;
+
     if (num_axes < 1)
         goto out;
 
 #ifdef MULTITOUCH
     for (axis = ABS_MT_SLOT; axis < ABS_MAX; axis++)
     {
-        if (EvdevBitIsSet(pEvdev->abs_bitmask, axis))
+        if (libevdev_has_event_code(pEvdev->dev, EV_ABS, axis))
         {
             int j;
             Bool skip = FALSE;
@@ -1294,7 +1281,7 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device, int want_scroll_axes)
             for (j = 0; j < ArrayLength(mt_axis_mappings); j++)
             {
                 if (mt_axis_mappings[j].mt_code == axis &&
-                    EvdevBitIsSet(pEvdev->abs_bitmask, mt_axis_mappings[j].code))
+                    libevdev_has_event_code(pEvdev->dev, EV_ABS, mt_axis_mappings[j].code))
                 {
                     mt_axis_mappings[j].needs_mapping = TRUE;
                     skip = TRUE;
@@ -1322,13 +1309,13 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device, int want_scroll_axes)
 #endif
 
 #ifdef HAVE_SMOOTH_SCROLLING
-    if (want_scroll_axes && EvdevBitIsSet(pEvdev->bitmask, EV_REL))
+    if (want_scroll_axes && libevdev_has_event_type(pEvdev->dev, EV_REL))
     {
-        if (EvdevBitIsSet(pEvdev->rel_bitmask, REL_WHEEL))
+        if (libevdev_has_event_code(pEvdev->dev, EV_REL, REL_WHEEL))
             num_axes++;
-        if (EvdevBitIsSet(pEvdev->rel_bitmask, REL_HWHEEL))
+        if (libevdev_has_event_code(pEvdev->dev, EV_REL, REL_HWHEEL))
             num_axes++;
-        if (EvdevBitIsSet(pEvdev->rel_bitmask, REL_DIAL))
+        if (libevdev_has_event_code(pEvdev->dev, EV_REL, REL_DIAL))
             num_axes++;
     }
 #endif
@@ -1355,6 +1342,14 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device, int want_scroll_axes)
     }
 #ifdef MULTITOUCH
     if (num_mt_axes_total > 0) {
+        int num_slots = 0;
+
+        if (pEvdev->mtdev) {
+            num_slots = pEvdev->mtdev->caps.slot.maximum -
+                          pEvdev->mtdev->caps.slot.minimum + 1;
+        } else
+            num_slots = libevdev_get_num_slots(pEvdev->dev);
+
         pEvdev->num_mt_vals = num_mt_axes_total;
         pEvdev->mt_mask = valuator_mask_new(num_mt_axes_total);
         if (!pEvdev->mt_mask) {
@@ -1363,7 +1358,7 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device, int want_scroll_axes)
             goto out;
         }
 
-        pEvdev->last_mt_vals = calloc(num_slots(pEvdev), sizeof(ValuatorMask *));
+        pEvdev->last_mt_vals = calloc(num_slots, sizeof(ValuatorMask *));
         if (!pEvdev->last_mt_vals) {
             xf86IDrvMsg(pInfo, X_ERROR,
                         "%s: failed to allocate MT last values mask array.\n",
@@ -1371,7 +1366,7 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device, int want_scroll_axes)
             goto out;
         }
 
-        for (i = 0; i < num_slots(pEvdev); i++) {
+        for (i = 0; i < num_slots; i++) {
             pEvdev->last_mt_vals[i] = valuator_mask_new(num_mt_axes_total);
             if (!pEvdev->last_mt_vals[i]) {
                 xf86IDrvMsg(pInfo, X_ERROR,
@@ -1400,7 +1395,7 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device, int want_scroll_axes)
         int j;
 #endif
         pEvdev->abs_axis_map[axis] = -1;
-        if (!EvdevBitIsSet(pEvdev->abs_bitmask, axis) ||
+        if (!libevdev_has_event_code(pEvdev->dev, EV_ABS, axis) ||
             is_blacklisted_axis(axis))
             continue;
 
@@ -1426,11 +1421,11 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device, int want_scroll_axes)
     {
         mapping++; /* continue from abs axis mapping */
 
-        if (EvdevBitIsSet(pEvdev->rel_bitmask, REL_HWHEEL))
+        if (libevdev_has_event_code(pEvdev->dev, EV_REL, REL_HWHEEL))
             pEvdev->rel_axis_map[REL_HWHEEL] = mapping++;
-        if (EvdevBitIsSet(pEvdev->rel_bitmask, REL_DIAL))
+        if (libevdev_has_event_code(pEvdev->dev, EV_REL, REL_DIAL))
             pEvdev->rel_axis_map[REL_DIAL] = mapping++;
-        if (EvdevBitIsSet(pEvdev->rel_bitmask, REL_WHEEL))
+        if (libevdev_has_event_code(pEvdev->dev, EV_REL, REL_WHEEL))
             pEvdev->rel_axis_map[REL_WHEEL] = mapping++;
     }
 #endif
@@ -1464,10 +1459,10 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device, int want_scroll_axes)
             goto out;
         }
 
-        for (i = 0; i < num_slots(pEvdev); i++) {
+        for (i = 0; i < num_touches; i++) {
             for (axis = ABS_MT_TOUCH_MAJOR; axis < ABS_MAX; axis++) {
                 if (pEvdev->abs_axis_map[axis] >= 0) {
-                    int val = pEvdev->mtdev ? 0 : pEvdev->absinfo[axis].value;
+                    int val = pEvdev->mtdev ? 0 : libevdev_get_current_slot(pEvdev->dev);
                     /* XXX: read initial values from mtdev when it adds support
                      *      for doing so. */
                     valuator_mask_set(pEvdev->last_mt_vals[i],
@@ -1479,28 +1474,30 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device, int want_scroll_axes)
 #endif
 
     for (axis = ABS_X; axis < ABS_MT_SLOT; axis++) {
+        const struct input_absinfo *abs;
         int axnum = pEvdev->abs_axis_map[axis];
         int resolution = 0;
 
         if (axnum == -1)
             continue;
 
+        abs = libevdev_get_abs_info(pEvdev->dev, axis);
 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 30)
         /* Kernel provides units/mm, X wants units/m */
-        if (pEvdev->absinfo[axis].resolution)
-            resolution = pEvdev->absinfo[axis].resolution * 1000;
+        resolution = abs->resolution * 1000;
 #endif
 
         xf86InitValuatorAxisStruct(device, axnum,
                                    atoms[axnum],
-                                   pEvdev->absinfo[axis].minimum,
-                                   pEvdev->absinfo[axis].maximum,
+                                   abs->minimum,
+                                   abs->maximum,
                                    resolution, 0, resolution, Absolute);
         xf86InitValuatorDefaults(device, axnum);
     }
 
 #ifdef MULTITOUCH
     for (axis = ABS_MT_TOUCH_MAJOR; axis <= ABS_MAX; axis++) {
+        const struct input_absinfo *abs;
         int axnum = pEvdev->abs_axis_map[axis];
         int resolution = 0;
         int j;
@@ -1509,6 +1506,8 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device, int want_scroll_axes)
         if (axnum < 0)
             continue;
 
+        abs = libevdev_get_abs_info(pEvdev->dev, axis);
+
         for (j = 0; j < ArrayLength(mt_axis_mappings); j++)
             if (mt_axis_mappings[j].mt_code == axis &&
                     mt_axis_mappings[j].needs_mapping)
@@ -1521,13 +1520,12 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device, int want_scroll_axes)
         if (skip)
             continue;
 
-        if (pEvdev->absinfo[axis].resolution)
-            resolution = pEvdev->absinfo[axis].resolution * 1000;
+        resolution = abs->resolution * 1000;
 
         xf86InitValuatorAxisStruct(device, axnum,
                                    atoms[axnum],
-                                   pEvdev->absinfo[axis].minimum,
-                                   pEvdev->absinfo[axis].maximum,
+                                   abs->minimum,
+                                   abs->maximum,
                                    resolution, 0, resolution,
                                    Absolute);
     }
@@ -1537,7 +1535,7 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device, int want_scroll_axes)
     if (want_scroll_axes)
     {
         int idx;
-        if (EvdevBitIsSet(pEvdev->rel_bitmask, REL_WHEEL))
+        if (libevdev_has_event_code(pEvdev->dev, EV_REL, REL_WHEEL))
         {
             idx = REL_WHEEL;
             xf86InitValuatorAxisStruct(device,
@@ -1550,7 +1548,7 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device, int want_scroll_axes)
                               SCROLL_FLAG_PREFERRED);
         }
 
-        if (EvdevBitIsSet(pEvdev->rel_bitmask, REL_HWHEEL))
+        if (libevdev_has_event_code(pEvdev->dev, EV_REL, REL_HWHEEL))
         {
             idx = REL_HWHEEL;
             xf86InitValuatorAxisStruct(device,
@@ -1563,7 +1561,7 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device, int want_scroll_axes)
                               SCROLL_FLAG_NONE);
         }
 
-        if (EvdevBitIsSet(pEvdev->rel_bitmask, REL_DIAL))
+        if (libevdev_has_event_code(pEvdev->dev, EV_REL, REL_DIAL))
         {
             idx = REL_DIAL;
             xf86InitValuatorAxisStruct(device,
@@ -1585,7 +1583,7 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device, int want_scroll_axes)
         if (!pEvdev->use_proximity)
             break;
 
-        if (EvdevBitIsSet(pEvdev->key_bitmask, proximity_bits[i]))
+        if (libevdev_has_event_code(pEvdev->dev, EV_KEY, proximity_bits[i]))
         {
             InitProximityClassDeviceStruct(device);
             pEvdev->prox = valuator_mask_new(num_axes);
@@ -1634,27 +1632,29 @@ EvdevAddRelValuatorClass(DeviceIntPtr device)
 {
     InputInfoPtr pInfo;
     EvdevPtr pEvdev;
-    int num_axes, axis, i = 0;
+    int num_axes = 0, axis, map, i = 0;
     Atom *atoms;
 
     pInfo = device->public.devicePrivate;
     pEvdev = pInfo->private;
 
-    if (!EvdevBitIsSet(pEvdev->bitmask, EV_REL))
+    if (!libevdev_has_event_type(pEvdev->dev, EV_REL))
         goto out;
 
-    num_axes = EvdevCountBits(pEvdev->rel_bitmask, NLONGS(REL_MAX));
+    for (i = 0; i < REL_MAX; i++)
+        if (libevdev_has_event_code(pEvdev->dev, EV_REL, i))
+            num_axes++;
     if (num_axes < 1)
         goto out;
 
 #ifndef HAVE_SMOOTH_SCROLLING
     /* Wheels are special, we post them as button events. So let's ignore them
      * in the axes list too */
-    if (EvdevBitIsSet(pEvdev->rel_bitmask, REL_WHEEL))
+    if (libevdev_has_event_code(pEvdev->dev, EV_REL, REL_WHEEL))
         num_axes--;
-    if (EvdevBitIsSet(pEvdev->rel_bitmask, REL_HWHEEL))
+    if (libevdev_has_event_code(pEvdev->dev, EV_REL, REL_HWHEEL))
         num_axes--;
-    if (EvdevBitIsSet(pEvdev->rel_bitmask, REL_DIAL))
+    if (libevdev_has_event_code(pEvdev->dev, EV_REL, REL_DIAL))
         num_axes--;
 
     if (num_axes <= 0)
@@ -1674,7 +1674,7 @@ EvdevAddRelValuatorClass(DeviceIntPtr device)
     }
     atoms = malloc(pEvdev->num_vals * sizeof(Atom));
 
-    for (axis = REL_X; i < MAX_VALUATORS && axis <= REL_MAX; axis++)
+    for (axis = REL_X, map = 0; map < MAX_VALUATORS && axis <= REL_MAX; axis++)
     {
         pEvdev->rel_axis_map[axis] = -1;
 #ifndef HAVE_SMOOTH_SCROLLING
@@ -1682,10 +1682,10 @@ EvdevAddRelValuatorClass(DeviceIntPtr device)
         if (axis == REL_WHEEL || axis == REL_HWHEEL || axis == REL_DIAL)
             continue;
 #endif
-        if (!EvdevBitIsSet(pEvdev->rel_bitmask, axis))
+        if (!libevdev_has_event_code(pEvdev->dev, EV_REL, axis))
             continue;
-        pEvdev->rel_axis_map[axis] = i;
-        i++;
+        pEvdev->rel_axis_map[axis] = map;
+        map++;
     }
 
     EvdevInitAxesLabels(pEvdev, Relative, pEvdev->num_vals, atoms);
@@ -2011,83 +2011,21 @@ static int
 EvdevCache(InputInfoPtr pInfo)
 {
     EvdevPtr pEvdev = pInfo->private;
-    int i, len;
-    struct input_id id;
-
-    unsigned long bitmask[NLONGS(EV_CNT)]      = {0};
-    unsigned long key_bitmask[NLONGS(KEY_CNT)] = {0};
-    unsigned long rel_bitmask[NLONGS(REL_CNT)] = {0};
-    unsigned long abs_bitmask[NLONGS(ABS_CNT)] = {0};
-
-
-    if (ioctl(pInfo->fd, EVIOCGID, &id) < 0)
-    {
-        xf86IDrvMsg(pInfo, X_ERROR, "ioctl EVIOCGID failed: %s\n", strerror(errno));
-        goto error;
-    }
-
-    pEvdev->id_vendor = id.vendor;
-    pEvdev->id_product = id.product;
-
-    len = ioctl(pInfo->fd, EVIOCGBIT(0, sizeof(bitmask)), bitmask);
-    if (len < 0) {
-        xf86IDrvMsg(pInfo, X_ERROR, "ioctl EVIOCGBIT for bitmask failed: %s\n",
-                    strerror(errno));
-        goto error;
-    }
-
-    memcpy(pEvdev->bitmask, bitmask, len);
-
-    len = ioctl(pInfo->fd, EVIOCGBIT(EV_REL, sizeof(rel_bitmask)), rel_bitmask);
-    if (len < 0) {
-        xf86IDrvMsg(pInfo, X_ERROR, "ioctl EVIOCGBIT for EV_REL failed: %s\n",
-                    strerror(errno));
-        goto error;
-    }
-
-    memcpy(pEvdev->rel_bitmask, rel_bitmask, len);
-
-    len = ioctl(pInfo->fd, EVIOCGBIT(EV_ABS, sizeof(abs_bitmask)), abs_bitmask);
-    if (len < 0) {
-        xf86IDrvMsg(pInfo, X_ERROR, "ioctl EVIOCGBIT for EV_ABS failed: %s\n",
-                    strerror(errno));
-        goto error;
-    }
-
-    memcpy(pEvdev->abs_bitmask, abs_bitmask, len);
+    int i;
 
     /*
      * Do not try to validate absinfo data since it is not expected
      * to be static, always refresh it in evdev structure.
      */
     for (i = ABS_X; i <= ABS_MAX; i++) {
-        if (EvdevBitIsSet(abs_bitmask, i)) {
-            len = ioctl(pInfo->fd, EVIOCGABS(i), &pEvdev->absinfo[i]);
-            if (len < 0) {
-                xf86IDrvMsg(pInfo, X_ERROR, "ioctl EVIOCGABSi(%d) failed: %s\n",
-                            i, strerror(errno));
-                goto error;
-            }
+        if (libevdev_has_event_code(pEvdev->dev, EV_ABS, i)) {
+            const struct input_absinfo *abs = libevdev_get_abs_info(pEvdev->dev, i);
             xf86IDrvMsgVerb(pInfo, X_PROBED, 6, "absolute axis %#x [%d..%d]\n",
-                            i, pEvdev->absinfo[i].maximum, pEvdev->absinfo[i].minimum);
+                            i, abs->minimum, abs->maximum);
         }
     }
 
-    len = ioctl(pInfo->fd, EVIOCGBIT(EV_KEY, sizeof(key_bitmask)), key_bitmask);
-    if (len < 0) {
-        xf86IDrvMsg(pInfo, X_ERROR, "ioctl EVIOCGBIT for EV_KEY failed: %s\n",
-                    strerror(errno));
-        goto error;
-    }
-
-    /* Copy the data so we have reasonably up-to-date info */
-    memcpy(pEvdev->key_bitmask, key_bitmask, len);
-
     return Success;
-
-error:
-    return !Success;
-
 }
 
 /**
@@ -2103,13 +2041,14 @@ EvdevGrabDevice(InputInfoPtr pInfo, int grab, int ungrab)
 
     if (pEvdev->grabDevice)
     {
-        if (grab && ioctl(pInfo->fd, EVIOCGRAB, (void *)1)) {
+        int rc;
+        if (grab && (rc = libevdev_grab(pEvdev->dev, LIBEVDEV_GRAB)) < 0) {
             xf86IDrvMsg(pInfo, X_WARNING, "Grab failed (%s)\n",
-                        strerror(errno));
+                        strerror(-rc));
             return FALSE;
-        } else if (ungrab && ioctl(pInfo->fd, EVIOCGRAB, (void *)0))
+        } else if (ungrab && (rc = libevdev_grab(pEvdev->dev, LIBEVDEV_UNGRAB)) < 0)
             xf86IDrvMsg(pInfo, X_WARNING, "Release failed (%s)\n",
-                        strerror(errno));
+                        strerror(-rc));
     }
 
     return TRUE;
@@ -2130,20 +2069,21 @@ EvdevForceXY(InputInfoPtr pInfo, int mode)
 
     if (mode == Relative)
     {
-        EvdevSetBit(pEvdev->rel_bitmask, REL_X);
-        EvdevSetBit(pEvdev->rel_bitmask, REL_Y);
+        libevdev_enable_event_code(pEvdev->dev, EV_REL, REL_X, NULL);
+        libevdev_enable_event_code(pEvdev->dev, EV_REL, REL_Y, NULL);
     } else if (mode == Absolute)
     {
-        EvdevSetBit(pEvdev->abs_bitmask, ABS_X);
-        EvdevSetBit(pEvdev->abs_bitmask, ABS_Y);
-        pEvdev->absinfo[ABS_X].minimum = 0;
-        pEvdev->absinfo[ABS_X].maximum = 1000;
-        pEvdev->absinfo[ABS_X].value = 0;
-        pEvdev->absinfo[ABS_X].resolution = 0;
-        pEvdev->absinfo[ABS_Y].minimum = 0;
-        pEvdev->absinfo[ABS_Y].maximum = 1000;
-        pEvdev->absinfo[ABS_Y].value = 0;
-        pEvdev->absinfo[ABS_Y].resolution = 0;
+        struct input_absinfo abs;
+
+        abs.minimum = 0;
+        abs.maximum = 1000;
+        abs.value = 0;
+        abs.fuzz = 0;
+        abs.flat = 0;
+        abs.resolution = 0;
+
+        libevdev_enable_event_code(pEvdev->dev, EV_ABS, ABS_X, &abs);
+        libevdev_enable_event_code(pEvdev->dev, EV_ABS, ABS_Y, &abs);
     }
 }
 
@@ -2158,7 +2098,8 @@ EvdevProbe(InputInfoPtr pInfo)
     int rc = 1;
 
     xf86IDrvMsg(pInfo, X_PROBED, "Vendor %#hx Product %#hx\n",
-                pEvdev->id_vendor, pEvdev->id_product);
+                libevdev_get_id_vendor(pEvdev->dev),
+                libevdev_get_id_product(pEvdev->dev));
 
     /* Trinary state for ignoring axes:
        - unset: do the normal thing.
@@ -2193,7 +2134,7 @@ EvdevProbe(InputInfoPtr pInfo)
     for (i = BTN_MISC; i < BTN_JOYSTICK; i++)
     {
         int mapping = 0;
-        if (EvdevBitIsSet(pEvdev->key_bitmask, i))
+        if (libevdev_has_event_code(pEvdev->dev, EV_KEY, i))
         {
             mapping = EvdevUtilButtonEventToButtonNumber(pEvdev, i);
             if (mapping > num_buttons)
@@ -2201,9 +2142,9 @@ EvdevProbe(InputInfoPtr pInfo)
         }
     }
 
-    has_lmr = EvdevBitIsSet(pEvdev->key_bitmask, BTN_LEFT) ||
-                EvdevBitIsSet(pEvdev->key_bitmask, BTN_MIDDLE) ||
-                EvdevBitIsSet(pEvdev->key_bitmask, BTN_RIGHT);
+    has_lmr = libevdev_has_event_code(pEvdev->dev, EV_KEY, BTN_LEFT) ||
+              libevdev_has_event_code(pEvdev->dev, EV_KEY, BTN_MIDDLE) ||
+              libevdev_has_event_code(pEvdev->dev, EV_KEY, BTN_RIGHT);
 
     if (num_buttons)
     {
@@ -2213,16 +2154,16 @@ EvdevProbe(InputInfoPtr pInfo)
     }
 
     for (i = 0; i < REL_MAX; i++) {
-        if (EvdevBitIsSet(pEvdev->rel_bitmask, i)) {
+        if (libevdev_has_event_code(pEvdev->dev, EV_REL, i)) {
             has_rel_axes = TRUE;
             break;
         }
     }
 
     if (has_rel_axes) {
-        if (EvdevBitIsSet(pEvdev->rel_bitmask, REL_WHEEL) ||
-            EvdevBitIsSet(pEvdev->rel_bitmask, REL_HWHEEL) ||
-            EvdevBitIsSet(pEvdev->rel_bitmask, REL_DIAL)) {
+        if (libevdev_has_event_code(pEvdev->dev, EV_REL, REL_WHEEL) ||
+            libevdev_has_event_code(pEvdev->dev, EV_REL, REL_HWHEEL) ||
+            libevdev_has_event_code(pEvdev->dev, EV_REL, REL_DIAL)) {
             xf86IDrvMsg(pInfo, X_PROBED, "Found scroll wheel(s)\n");
             has_scroll = TRUE;
             if (!num_buttons)
@@ -2237,11 +2178,11 @@ EvdevProbe(InputInfoPtr pInfo)
             xf86IDrvMsg(pInfo, X_PROBED, "Found relative axes\n");
             pEvdev->flags |= EVDEV_RELATIVE_EVENTS;
 
-            if (EvdevBitIsSet(pEvdev->rel_bitmask, REL_X) &&
-                EvdevBitIsSet(pEvdev->rel_bitmask, REL_Y)) {
+            if (libevdev_has_event_code(pEvdev->dev, EV_REL, REL_X) &&
+                libevdev_has_event_code(pEvdev->dev, EV_REL, REL_Y)) {
                 xf86IDrvMsg(pInfo, X_PROBED, "Found x and y relative axes\n");
-            } else if (!EvdevBitIsSet(pEvdev->abs_bitmask, ABS_X) ||
-                       !EvdevBitIsSet(pEvdev->abs_bitmask, ABS_Y))
+            } else if (!libevdev_has_event_code(pEvdev->dev, EV_ABS, ABS_X) ||
+                       !libevdev_has_event_code(pEvdev->dev, EV_ABS, ABS_Y))
                 EvdevForceXY(pInfo, Relative);
         } else {
             xf86IDrvMsg(pInfo, X_INFO, "Relative axes present but ignored.\n");
@@ -2250,7 +2191,7 @@ EvdevProbe(InputInfoPtr pInfo)
     }
 
     for (i = 0; i < ABS_MAX; i++) {
-        if (EvdevBitIsSet(pEvdev->abs_bitmask, i)) {
+        if (libevdev_has_event_code(pEvdev->dev, EV_ABS, i)) {
             has_abs_axes = TRUE;
             break;
         }
@@ -2258,7 +2199,7 @@ EvdevProbe(InputInfoPtr pInfo)
 
 #ifdef MULTITOUCH
     for (i = ABS_MT_SLOT; i < ABS_MAX; i++) {
-        if (EvdevBitIsSet(pEvdev->abs_bitmask, i)) {
+        if (libevdev_has_event_code(pEvdev->dev, EV_ABS, i)) {
             has_mt = TRUE;
             break;
         }
@@ -2276,7 +2217,7 @@ EvdevProbe(InputInfoPtr pInfo)
         if (has_mt) {
             xf86IDrvMsg(pInfo, X_PROBED, "Found absolute multitouch axes\n");
             if (num_buttons == 0) {
-                if (EvdevBitIsSet(pEvdev->key_bitmask, BTN_JOYSTICK)) {
+                if (libevdev_has_event_code(pEvdev->dev, EV_KEY, BTN_JOYSTICK)) {
                     xf86IDrvMsg(pInfo, X_INFO, "Device is a Joystick with MT without buttons. Ignoring it.\n");
                     goto out;
                 } else {
@@ -2288,12 +2229,12 @@ EvdevProbe(InputInfoPtr pInfo)
             }
         }
 
-        if ((EvdevBitIsSet(pEvdev->abs_bitmask, ABS_X) &&
-             EvdevBitIsSet(pEvdev->abs_bitmask, ABS_Y))) {
+        if ((libevdev_has_event_code(pEvdev->dev, EV_ABS, ABS_X) &&
+             libevdev_has_event_code(pEvdev->dev, EV_ABS, ABS_Y))) {
             xf86IDrvMsg(pInfo, X_PROBED, "Found x and y absolute axes\n");
-            if (EvdevBitIsSet(pEvdev->key_bitmask, BTN_TOOL_PEN) ||
-                EvdevBitIsSet(pEvdev->key_bitmask, BTN_STYLUS) ||
-                EvdevBitIsSet(pEvdev->key_bitmask, BTN_STYLUS2))
+            if (libevdev_has_event_code(pEvdev->dev, EV_KEY, BTN_TOOL_PEN) ||
+                libevdev_has_event_code(pEvdev->dev, EV_KEY, BTN_STYLUS) ||
+                libevdev_has_event_code(pEvdev->dev, EV_KEY, BTN_STYLUS2))
             {
                 xf86IDrvMsg(pInfo, X_PROBED, "Found absolute tablet.\n");
                 pEvdev->flags |= EVDEV_TABLET;
@@ -2302,9 +2243,9 @@ EvdevProbe(InputInfoPtr pInfo)
                     pEvdev->num_buttons = 7; /* LMR + scroll wheels */
                     pEvdev->flags |= EVDEV_BUTTON_EVENTS;
                 }
-            } else if (EvdevBitIsSet(pEvdev->abs_bitmask, ABS_PRESSURE) ||
-                EvdevBitIsSet(pEvdev->key_bitmask, BTN_TOUCH)) {
-                if (has_lmr || EvdevBitIsSet(pEvdev->key_bitmask, BTN_TOOL_FINGER)) {
+            } else if (libevdev_has_event_code(pEvdev->dev, EV_ABS, ABS_PRESSURE) ||
+                       libevdev_has_event_code(pEvdev->dev, EV_KEY, BTN_TOUCH)) {
+                if (has_lmr || libevdev_has_event_code(pEvdev->dev, EV_KEY, BTN_TOOL_FINGER)) {
                     xf86IDrvMsg(pInfo, X_PROBED, "Found absolute touchpad.\n");
                     pEvdev->flags |= EVDEV_TOUCHPAD;
                 } else {
@@ -2312,8 +2253,8 @@ EvdevProbe(InputInfoPtr pInfo)
                     pEvdev->flags |= EVDEV_TOUCHSCREEN;
                     pEvdev->flags |= EVDEV_BUTTON_EVENTS;
                 }
-            } else if (!(EvdevBitIsSet(pEvdev->rel_bitmask, REL_X) &&
-                         EvdevBitIsSet(pEvdev->rel_bitmask, REL_Y)) && has_lmr) {
+            } else if (!(libevdev_has_event_code(pEvdev->dev, EV_REL, REL_X) &&
+                         libevdev_has_event_code(pEvdev->dev, EV_REL, REL_Y)) && has_lmr) {
                     /* some touchscreens use BTN_LEFT rather than BTN_TOUCH */
                     xf86IDrvMsg(pInfo, X_PROBED, "Found absolute touchscreen\n");
                     pEvdev->flags |= EVDEV_TOUCHSCREEN;
@@ -2321,8 +2262,8 @@ EvdevProbe(InputInfoPtr pInfo)
             }
         } else {
 #ifdef MULTITOUCH
-            if (!EvdevBitIsSet(pEvdev->abs_bitmask, ABS_MT_POSITION_X) ||
-                !EvdevBitIsSet(pEvdev->abs_bitmask, ABS_MT_POSITION_Y))
+            if (!libevdev_has_event_code(pEvdev->dev, EV_ABS, ABS_MT_POSITION_X) ||
+                !libevdev_has_event_code(pEvdev->dev, EV_ABS, ABS_MT_POSITION_Y))
 #endif
                 EvdevForceXY(pInfo, Absolute);
         }
@@ -2332,7 +2273,7 @@ EvdevProbe(InputInfoPtr pInfo)
     }
 
     for (i = 0; i < BTN_MISC; i++) {
-        if (EvdevBitIsSet(pEvdev->key_bitmask, i)) {
+        if (libevdev_has_event_code(pEvdev->dev, EV_KEY, i)) {
             xf86IDrvMsg(pInfo, X_PROBED, "Found keys\n");
             pEvdev->flags |= EVDEV_KEYBOARD_EVENTS;
             has_keys = TRUE;
@@ -2377,8 +2318,8 @@ EvdevProbe(InputInfoPtr pInfo)
             xf86IDrvMsg(pInfo, X_INFO, "Configuring as touchscreen\n");
             pInfo->type_name = XI_TOUCHSCREEN;
 	} else {
-            if (!EvdevBitIsSet(pEvdev->rel_bitmask, REL_X) ||
-                !EvdevBitIsSet(pEvdev->rel_bitmask, REL_Y))
+            if (!libevdev_has_event_code(pEvdev->dev, EV_REL, REL_X) ||
+                !libevdev_has_event_code(pEvdev->dev, EV_REL, REL_Y))
                 EvdevForceXY(pInfo, Relative);
 	    xf86IDrvMsg(pInfo, X_INFO, "Configuring as mouse\n");
 	    pInfo->type_name = XI_MOUSE;
@@ -2440,18 +2381,12 @@ static Bool
 EvdevOpenMTDev(InputInfoPtr pInfo)
 {
     EvdevPtr pEvdev = pInfo->private;
-    unsigned long bitmask[NLONGS(EV_CNT)]      = {0};
-    unsigned long abs_bitmask[NLONGS(ABS_CNT)] = {0};
-    int len;
 
     if (pEvdev->mtdev) {
         pEvdev->cur_slot = pEvdev->mtdev->caps.slot.value;
         return TRUE;
-    } else if (EvdevBitIsSet(pEvdev->abs_bitmask, ABS_MT_SLOT)) {
-        struct input_absinfo abs;
-        len = ioctl(pInfo->fd, EVIOCGABS(ABS_MT_SLOT), &abs);
-        if (len != -1)
-            pEvdev->cur_slot = abs.value;
+    } else if (libevdev_has_event_code(pEvdev->dev, EV_ABS, ABS_MT_SLOT)) {
+        pEvdev->cur_slot = libevdev_get_current_slot(pEvdev->dev);
         return TRUE;
     }
 
@@ -2460,30 +2395,15 @@ EvdevOpenMTDev(InputInfoPtr pInfo)
         return FALSE;
     }
 
-    /* Use ioctl here, this may be called before EvdevCache */
-    len = ioctl(pInfo->fd, EVIOCGBIT(0, sizeof(bitmask)), bitmask);
-    if (len < 0) {
-        xf86IDrvMsg(pInfo, X_ERROR, "ioctl EVIOCGBIT for bitmask in %s failed: %s\n",
-                    __func__, strerror(errno));
-        return FALSE;
-    }
-
-    if (!EvdevBitIsSet(bitmask, EV_ABS))
+    if (!libevdev_has_event_type(pEvdev->dev, EV_ABS))
         return TRUE;
 
-    len = ioctl(pInfo->fd, EVIOCGBIT(EV_ABS, sizeof(abs_bitmask)), abs_bitmask);
-    if (len < 0) {
-        xf86IDrvMsg(pInfo, X_ERROR, "ioctl EVIOCGBIT for EV_ABS in %s failed: %s\n",
-                    __func__, strerror(errno));
-        return FALSE;
-    }
-
     /* don't need mtdev for protocol B devices */
-    if (EvdevBitIsSet(abs_bitmask, ABS_MT_SLOT))
+    if (libevdev_has_event_code(pEvdev->dev, EV_ABS, ABS_MT_SLOT))
         return TRUE;
 
-    if (!EvdevBitIsSet(abs_bitmask, ABS_MT_POSITION_X) ||
-        !EvdevBitIsSet(abs_bitmask, ABS_MT_POSITION_Y))
+    if (!libevdev_has_event_code(pEvdev->dev, EV_ABS, ABS_MT_POSITION_X) ||
+        !libevdev_has_event_code(pEvdev->dev, EV_ABS, ABS_MT_POSITION_Y))
         return TRUE;
 
     xf86IDrvMsg(pInfo, X_INFO, "Using mtdev for this device\n");
@@ -2528,6 +2448,23 @@ EvdevOpenDevice(InputInfoPtr pInfo)
             xf86IDrvMsg(pInfo, X_ERROR, "Unable to open evdev device \"%s\".\n", device);
             return BadValue;
         }
+
+        if (libevdev_get_fd(pEvdev->dev) != -1) {
+            struct input_event ev;
+


Reply to: