summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2013-05-29 07:17:41 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2013-07-04 10:45:49 +1000
commitc0125f85200c16b6fcd995a09b36080a98d3d0c5 (patch)
tree8acf8b6b8fe7af0c519893e7d53fd02b2046a296
parentdb71509ed9039c3f26da746b945fe3d967a1a820 (diff)
Switch to using libevdev
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
-rw-r--r--configure.ac1
-rw-r--r--src/Makefile.am4
-rw-r--r--src/apple.c3
-rw-r--r--src/evdev.c393
-rw-r--r--src/evdev.h14
5 files changed, 178 insertions, 237 deletions
diff --git a/configure.ac b/configure.ac
index 41d1017..5fcf6d9 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)
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..ad43c1e 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_vendor_id(pEvdev->dev),
+ libevdev_get_product_id(pEvdev->dev)))
return;
fkeymode = get_fnmode();
diff --git a/src/evdev.c b/src/evdev.c
index 86af151..0ad816b 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -175,23 +175,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)));
@@ -430,13 +413,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);
}
}
@@ -454,6 +440,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;
@@ -462,6 +449,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;
@@ -471,14 +459,13 @@ EvdevApplyCalibration(EvdevPtr pEvdev, ValuatorMask *mask)
calib_max = pEvdev->calibration.max_y;
}
- if (pEvdev->flags & EVDEV_CALIBRATED)
- val = xf86ScaleAxis(val, pEvdev->absinfo[i].maximum,
- pEvdev->absinfo[i].minimum, calib_max,
- calib_min);
+ if (pEvdev->flags & EVDEV_CALIBRATED) {
+ 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);
}
@@ -759,8 +746,7 @@ EvdevProcessTouch(InputInfoPtr pInfo)
static int
num_slots(EvdevPtr pEvdev)
{
- int value = pEvdev->absinfo[ABS_MT_SLOT].maximum -
- pEvdev->absinfo[ABS_MT_SLOT].minimum + 1;
+ int 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;
@@ -769,7 +755,7 @@ num_slots(EvdevPtr pEvdev)
static int
last_mt_vals_slot(EvdevPtr pEvdev)
{
- int value = pEvdev->cur_slot - pEvdev->absinfo[ABS_MT_SLOT].minimum;
+ int value = pEvdev->cur_slot; /* FIXME: non-zero slots */
return value < num_slots(pEvdev) ? value : -1;
}
@@ -1049,7 +1035,7 @@ EvdevProcessSyncEvent(InputInfoPtr pInfo, struct input_event *ev)
* Process the events from the device; nothing is actually posted to the server
* until an EV_SYN event is received.
*/
-static void
+static int
EvdevProcessEvent(InputInfoPtr pInfo, struct input_event *ev)
{
switch (ev->type) {
@@ -1066,6 +1052,8 @@ EvdevProcessEvent(InputInfoPtr pInfo, struct input_event *ev)
EvdevProcessSyncEvent(pInfo, ev);
break;
}
+
+ return 0;
}
#undef ABS_X_VALUE
@@ -1102,9 +1090,32 @@ EvdevFreeMasks(EvdevPtr pEvdev)
static void
EvdevReadInput(InputInfoPtr pInfo)
{
- struct input_event ev[NUM_EVENTS];
- int i, len = sizeof(ev);
+ int rc = 0;
+ EvdevPtr pEvdev = pInfo->private;
+ struct input_event ev;
+ do {
+ rc = libevdev_next_event(pEvdev->dev, LIBEVDEV_READ_NORMAL, &ev);
+ if (rc < 0) {
+ if (rc == -ENODEV) /* May happen after resume */
+ xf86RemoveEnabledDevice(pInfo);
+ else if (rc != -EAGAIN)
+ LogMessageVerbSigSafe(X_ERROR, 0, "%s: Read error: %s\n", pInfo->name,
+ strerror(-rc));
+ break;
+ } else if (rc == 0)
+ EvdevProcessEvent(pInfo, &ev);
+ else {
+ /* SYN_DROPPED, need to sync properly */
+ while (rc == 1) {
+ rc = libevdev_next_event(pEvdev->dev, LIBEVDEV_READ_SYNC, &ev);
+ EvdevProcessEvent(pInfo, &ev);
+ }
+ }
+ } while (rc == 0);
+
+ /* FIXME: mtdev doesn't work with the current libevdev api */
+#if 0
while (len == sizeof(ev))
{
#ifdef MULTITOUCH
@@ -1137,6 +1148,7 @@ EvdevReadInput(InputInfoPtr pInfo)
for (i = 0; i < len/sizeof(ev[0]); i++)
EvdevProcessEvent(pInfo, &ev[i]);
}
+#endif
}
static void
@@ -1239,7 +1251,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 */
@@ -1249,25 +1261,29 @@ 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;
for (j = 0; j < ArrayLength(mt_axis_mappings); j++)
{
+ /* FIXME: check this */
if (mt_axis_mappings[j].mt_code == axis &&
- BitIsOn(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;
@@ -1295,13 +1311,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
@@ -1373,7 +1389,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;
@@ -1399,11 +1415,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
@@ -1448,28 +1464,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;
@@ -1478,6 +1496,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)
@@ -1490,13 +1510,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);
}
@@ -1506,7 +1525,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,
@@ -1519,7 +1538,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,
@@ -1532,7 +1551,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,
@@ -1554,7 +1573,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);
@@ -1603,27 +1622,29 @@ EvdevAddRelValuatorClass(DeviceIntPtr device)
{
InputInfoPtr pInfo;
EvdevPtr pEvdev;
- int num_axes, axis, i = 0;
+ int num_axes = 0, axis, 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)
@@ -1643,7 +1664,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, i = 0; i < MAX_VALUATORS && axis <= REL_MAX; axis++)
{
pEvdev->rel_axis_map[axis] = -1;
#ifndef HAVE_SMOOTH_SCROLLING
@@ -1651,7 +1672,7 @@ 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++;
@@ -1980,101 +2001,21 @@ static int
EvdevCache(InputInfoPtr pInfo)
{
EvdevPtr pEvdev = pInfo->private;
- int i, len;
- struct input_id id;
-
- char name[1024] = {0};
- 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};
- unsigned long led_bitmask[NLONGS(LED_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;
-
- if (ioctl(pInfo->fd, EVIOCGNAME(sizeof(name) - 1), name) < 0) {
- xf86IDrvMsg(pInfo, X_ERROR, "ioctl EVIOCGNAME failed: %s\n", strerror(errno));
- goto error;
- }
-
- strcpy(pEvdev->name, name);
-
- 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);
-
- len = ioctl(pInfo->fd, EVIOCGBIT(EV_LED, sizeof(led_bitmask)), led_bitmask);
- if (len < 0) {
- xf86IDrvMsg(pInfo, X_ERROR, "ioctl EVIOCGBIT for EV_LED failed: %s\n",
- strerror(errno));
- goto error;
- }
-
- memcpy(pEvdev->led_bitmask, led_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;
-
}
/**
@@ -2090,13 +2031,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;
@@ -2117,20 +2059,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);
}
}
@@ -2145,7 +2088,8 @@ EvdevProbe(InputInfoPtr pInfo)
int rc = 1;
xf86IDrvMsg(pInfo, X_PROBED, "Vendor %#hx Product %#hx\n",
- pEvdev->id_vendor, pEvdev->id_product);
+ libevdev_get_vendor_id(pEvdev->dev),
+ libevdev_get_product_id(pEvdev->dev));
/* Trinary state for ignoring axes:
- unset: do the normal thing.
@@ -2180,7 +2124,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)
@@ -2188,9 +2132,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)
{
@@ -2200,16 +2144,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)
@@ -2224,11 +2168,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");
@@ -2237,7 +2181,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;
}
@@ -2245,7 +2189,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;
}
@@ -2263,7 +2207,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 {
@@ -2275,12 +2219,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;
@@ -2289,9 +2233,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 {
@@ -2299,8 +2243,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;
@@ -2308,8 +2252,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);
}
@@ -2319,7 +2263,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;
@@ -2364,8 +2308,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;
@@ -2427,9 +2371,6 @@ 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;
@@ -2441,26 +2382,11 @@ 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;
- }
-
- 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");
@@ -2497,6 +2423,7 @@ EvdevOpenDevice(InputInfoPtr pInfo)
if (pInfo->fd < 0)
{
+
do {
pInfo->fd = open(device, O_RDWR | O_NONBLOCK, 0);
} while (pInfo->fd < 0 && errno == EINTR);
@@ -2505,6 +2432,16 @@ EvdevOpenDevice(InputInfoPtr pInfo)
xf86IDrvMsg(pInfo, X_ERROR, "Unable to open evdev device \"%s\".\n", device);
return BadValue;
}
+
+ if (libevdev_get_fd(pEvdev->dev) != -1)
+ libevdev_change_fd(pEvdev->dev, pInfo->fd);
+ else {
+ int rc = libevdev_set_fd(pEvdev->dev, pInfo->fd);
+ if (rc < 0) {
+ xf86IDrvMsg(pInfo, X_ERROR, "Unable to query fd: %s\n", strerror(-rc));
+ return BadValue;
+ }
+ }
}
/* Check major/minor of device node to avoid adding duplicate devices. */
@@ -2535,6 +2472,7 @@ EvdevCloseDevice(InputInfoPtr pInfo)
{
close(pInfo->fd);
pInfo->fd = -1;
+ libevdev_change_fd(pEvdev->dev, pInfo->fd);
}
#ifdef MULTITOUCH
@@ -2565,13 +2503,20 @@ EvdevUnInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
}
static EvdevPtr
-EvdevAlloc(void)
+EvdevAlloc(InputInfoPtr pInfo)
{
int i;
EvdevPtr pEvdev = calloc(sizeof(EvdevRec), 1);
if (!pEvdev)
return NULL;
+
+ pEvdev->dev = libevdev_new();
+ if (!pEvdev->dev) {
+ free(pEvdev);
+ return NULL;
+ }
+
/*
* We initialize pEvdev->in_proximity to 1 so that device that doesn't use
* proximity will still report events.
@@ -2602,7 +2547,7 @@ EvdevPreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
EvdevPtr pEvdev;
int rc = BadAlloc;
- if (!(pEvdev = EvdevAlloc()))
+ if (!(pEvdev = EvdevAlloc(pInfo)))
goto error;
pInfo->private = pEvdev;
@@ -2623,6 +2568,8 @@ EvdevPreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
/* If grabDevice is set, ungrab immediately since we only want to grab
* between DEVICE_ON and DEVICE_OFF. If we never get DEVICE_ON, don't
* hold a grab. */
+
+ /* FIXME: add grab device to libevdev */
if (!EvdevGrabDevice(pInfo, 1, 1))
{
xf86IDrvMsg(pInfo, X_WARNING, "Device may already be configured.\n");
@@ -2786,7 +2733,7 @@ static void EvdevInitButtonLabels(EvdevPtr pEvdev, int natoms, Atom *atoms)
for (button = BTN_MISC; button < BTN_JOYSTICK; button++)
{
- if (EvdevBitIsSet(pEvdev->key_bitmask, button))
+ if (libevdev_has_event_code(pEvdev->dev, EV_KEY, button))
{
int group = (button % 0x100)/16;
int idx = button - ((button/16) * 16);
@@ -2826,8 +2773,8 @@ EvdevInitProperty(DeviceIntPtr dev)
CARD32 product[2];
prop_product_id = MakeAtom(XI_PROP_PRODUCT_ID, strlen(XI_PROP_PRODUCT_ID), TRUE);
- product[0] = pEvdev->id_vendor;
- product[1] = pEvdev->id_product;
+ product[0] = libevdev_get_vendor_id(pEvdev->dev);
+ product[1] = libevdev_get_product_id(pEvdev->dev);
rc = XIChangeDeviceProperty(dev, prop_product_id, XA_INTEGER, 32,
PropModeReplace, 2, product, FALSE);
if (rc != Success)
diff --git a/src/evdev.h b/src/evdev.h
index 6ae389c..563d108 100644
--- a/src/evdev.h
+++ b/src/evdev.h
@@ -47,6 +47,8 @@
#include <mtdev.h>
#endif
+#include <libevdev/libevdev.h>
+
#ifndef EV_CNT /* linux 2.6.23 kernels and earlier lack _CNT defines */
#define EV_CNT (EV_MAX+1)
#endif
@@ -150,8 +152,7 @@ typedef struct {
} EventQueueRec, *EventQueuePtr;
typedef struct {
- unsigned short id_vendor;
- unsigned short id_product;
+ struct libevdev *dev;
char *device;
int grabDevice; /* grab the event device? */
@@ -234,15 +235,6 @@ typedef struct {
int reopen_left; /* number of attempts left to re-open the device */
OsTimerPtr reopen_timer;
- /* Cached info from device. */
- char name[1024];
- unsigned long bitmask[NLONGS(EV_CNT)];
- unsigned long key_bitmask[NLONGS(KEY_CNT)];
- unsigned long rel_bitmask[NLONGS(REL_CNT)];
- unsigned long abs_bitmask[NLONGS(ABS_CNT)];
- unsigned long led_bitmask[NLONGS(LED_CNT)];
- struct input_absinfo absinfo[ABS_CNT];
-
/* minor/major number */
dev_t min_maj;