aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin B. Macdonald <macdonald@maths.ox.ac.uk>2014-06-26 12:17:59 +0100
committerPeter Hutterer <peter.hutterer@who-t.net>2015-03-24 14:59:39 +1000
commit05f7057ad5716ccf643b80f2f5fbfff34783a950 (patch)
treee578f47a7f52a2e8f6147597243ea65dff55784e
parentevdev 2.9.1 (diff)
downloadxf86-input-evdev-05f7057ad5716ccf643b80f2f5fbfff34783a950.tar.gz
xf86-input-evdev-05f7057ad5716ccf643b80f2f5fbfff34783a950.tar.bz2
xf86-input-evdev-05f7057ad5716ccf643b80f2f5fbfff34783a950.zip
Workaround lack of ABS_X on MT devices (#80470)
Often on Android, we have ABS_MT_POSITION_X without ABS_X (which is contrary to spec). We add fake ABS_X axis in that case. X.Org Bug 80470 <http://bugs.freedesktop.org/show_bug.cgi?id=80470> Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> (cherry picked from commit b370ccdff8f721de75d3d91486cc4807668d040c)
-rw-r--r--src/evdev.c32
1 files changed, 29 insertions, 3 deletions
diff --git a/src/evdev.c b/src/evdev.c
index 9cfc982..1a385c9 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -1211,7 +1211,8 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device, int num_scroll_axes)
{
InputInfoPtr pInfo;
EvdevPtr pEvdev;
- int num_axes = 0, axis, i = 0;
+ int axis, i = 0;
+ int num_axes = 0; /* number of non-MT axes */
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 */
@@ -1224,6 +1225,7 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device, int num_scroll_axes)
if (!libevdev_has_event_type(pEvdev->dev, EV_ABS))
goto out;
+ /* Find number of absolute axis, including MT ones, will decrease later. */
for (i = 0; i < ABS_MAX; i++)
if (libevdev_has_event_code(pEvdev->dev, EV_ABS, i))
num_axes++;
@@ -1232,6 +1234,30 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device, int num_scroll_axes)
goto out;
#ifdef MULTITOUCH
+ /* Android drivers often have ABS_MT_POSITION_X but not ABS_X.
+ Loop over the MT->legacy axis table and add fake axes. */
+ for (i = 0; i < ArrayLength(mt_axis_mappings); i++)
+ {
+ int mt_code = mt_axis_mappings[i].mt_code;
+ int code = mt_axis_mappings[i].code;
+ if (libevdev_has_event_code(pEvdev->dev, EV_ABS, mt_code) &&
+ !libevdev_has_event_code(pEvdev->dev, EV_ABS, code))
+ {
+ const struct input_absinfo* abs;
+ abs = libevdev_get_abs_info(pEvdev->dev, mt_code);
+ if (libevdev_enable_event_code(pEvdev->dev, EV_ABS, code, abs))
+ {
+ xf86IDrvMsg(pInfo, X_ERROR, "Failed to fake axis %s.\n",
+ libevdev_event_code_get_name(EV_ABS, code));
+ goto out;
+ }
+ xf86IDrvMsg(pInfo, X_INFO, "Faking axis %s.\n",
+ libevdev_event_code_get_name(EV_ABS, code));
+ num_axes++;
+ }
+ }
+
+ /* Absolute multitouch axes: adjust mapping and axes counts. */
for (axis = ABS_MT_SLOT; axis < ABS_MAX; axis++)
{
if (libevdev_has_event_code(pEvdev->dev, EV_ABS, axis))
@@ -1239,6 +1265,7 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device, int num_scroll_axes)
int j;
Bool skip = FALSE;
+ /* Setup mapping if axis is in MT->legacy axis table. */
for (j = 0; j < ArrayLength(mt_axis_mappings); j++)
{
if (mt_axis_mappings[j].mt_code == axis &&
@@ -1259,8 +1286,7 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device, int num_scroll_axes)
}
}
- /* device only has mt-axes. the kernel should give us ABS_X etc for
- backwards compat but some devices don't have it. */
+ /* Panic if, after faking ABS_X etc, we still only have mt-axes. */
if (num_axes == 0 && num_mt_axes > 0) {
xf86IDrvMsg(pInfo, X_ERROR,
"found only multitouch-axes. That shouldn't happen.\n");