mirror of
https://github.com/X11Libre/xf86-input-evdev.git
synced 2026-03-24 01:34:04 +00:00
Merge branch 'libevdev'
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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();
|
||||
|
||||
471
src/evdev.c
471
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,8 +748,12 @@ 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;
|
||||
|
||||
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;
|
||||
@@ -772,7 +762,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;
|
||||
|
||||
return value < num_slots(pEvdev) ? value : -1;
|
||||
}
|
||||
@@ -783,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) {
|
||||
@@ -1089,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;
|
||||
@@ -1099,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);
|
||||
int rc = 0;
|
||||
EvdevPtr pEvdev = pInfo->private;
|
||||
struct input_event ev;
|
||||
|
||||
while (len == sizeof(ev))
|
||||
{
|
||||
len = read(pInfo->fd, &ev, sizeof(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
|
||||
@@ -1267,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 */
|
||||
@@ -1277,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;
|
||||
@@ -1295,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;
|
||||
@@ -1323,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
|
||||
@@ -1356,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) {
|
||||
@@ -1364,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",
|
||||
@@ -1372,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,
|
||||
@@ -1401,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;
|
||||
|
||||
@@ -1427,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
|
||||
@@ -1456,8 +1450,7 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device, int want_scroll_axes)
|
||||
num_touches = pEvdev->mtdev->caps.slot.maximum -
|
||||
pEvdev->mtdev->caps.slot.minimum + 1;
|
||||
} else
|
||||
num_touches = pEvdev->absinfo[ABS_MT_SLOT].maximum -
|
||||
pEvdev->absinfo[ABS_MT_SLOT].minimum + 1;
|
||||
num_touches = num_slots(pEvdev);
|
||||
|
||||
if (!InitTouchClassDeviceStruct(device, num_touches, mode,
|
||||
num_mt_axes_total)) {
|
||||
@@ -1466,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],
|
||||
@@ -1481,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;
|
||||
@@ -1511,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)
|
||||
@@ -1523,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);
|
||||
}
|
||||
@@ -1539,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,
|
||||
@@ -1552,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,
|
||||
@@ -1565,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,
|
||||
@@ -1587,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);
|
||||
@@ -1636,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)
|
||||
@@ -1676,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
|
||||
@@ -1684,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);
|
||||
@@ -2013,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;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2105,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;
|
||||
@@ -2132,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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2160,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.
|
||||
@@ -2195,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)
|
||||
@@ -2203,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)
|
||||
{
|
||||
@@ -2215,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)
|
||||
@@ -2239,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");
|
||||
@@ -2252,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;
|
||||
}
|
||||
@@ -2260,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;
|
||||
}
|
||||
@@ -2278,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 {
|
||||
@@ -2290,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;
|
||||
@@ -2304,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 {
|
||||
@@ -2314,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;
|
||||
@@ -2323,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);
|
||||
}
|
||||
@@ -2334,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;
|
||||
@@ -2379,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;
|
||||
@@ -2442,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;
|
||||
}
|
||||
|
||||
@@ -2462,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");
|
||||
@@ -2530,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;
|
||||
|
||||
libevdev_change_fd(pEvdev->dev, pInfo->fd);
|
||||
/* re-sync libevdev's view of the device, but
|
||||
we don't care about the actual events here */
|
||||
libevdev_next_event(pEvdev->dev, LIBEVDEV_READ_FLAG_FORCE_SYNC, &ev);
|
||||
while (libevdev_next_event(pEvdev->dev, LIBEVDEV_READ_FLAG_SYNC, &ev) == LIBEVDEV_READ_STATUS_SYNC)
|
||||
;
|
||||
} 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. */
|
||||
@@ -2585,18 +2520,27 @@ EvdevUnInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags)
|
||||
|
||||
free(pEvdev->type_name);
|
||||
pEvdev->type_name = NULL;
|
||||
|
||||
libevdev_free(pEvdev->dev);
|
||||
}
|
||||
xf86DeleteInput(pInfo, 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.
|
||||
@@ -2627,7 +2571,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;
|
||||
@@ -2648,6 +2592,7 @@ 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. */
|
||||
|
||||
if (!EvdevGrabDevice(pInfo, 1, 1))
|
||||
{
|
||||
xf86IDrvMsg(pInfo, X_WARNING, "Device may already be configured.\n");
|
||||
@@ -2811,7 +2756,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);
|
||||
@@ -2851,8 +2796,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_id_vendor(pEvdev->dev);
|
||||
product[1] = libevdev_get_id_product(pEvdev->dev);
|
||||
rc = XIChangeDeviceProperty(dev, prop_product_id, XA_INTEGER, 32,
|
||||
PropModeReplace, 2, product, FALSE);
|
||||
if (rc != Success)
|
||||
|
||||
12
src/evdev.h
12
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,13 +235,6 @@ typedef struct {
|
||||
int reopen_left; /* number of attempts left to re-open the device */
|
||||
OsTimerPtr reopen_timer;
|
||||
|
||||
/* Cached info from device. */
|
||||
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)];
|
||||
struct input_absinfo absinfo[ABS_CNT];
|
||||
|
||||
/* minor/major number */
|
||||
dev_t min_maj;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user