|
|
|
|
@ -1167,6 +1167,39 @@ is_blacklisted_axis(int axis) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int |
|
|
|
|
EvdevAddFakeSingleTouchAxes(InputInfoPtr pInfo) |
|
|
|
|
{ |
|
|
|
|
EvdevPtr pEvdev = pInfo->private; |
|
|
|
|
int num_axes = 0; |
|
|
|
|
int i; |
|
|
|
|
|
|
|
|
|
/* 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)); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
xf86IDrvMsg(pInfo, X_INFO, "Faking axis %s.\n", |
|
|
|
|
libevdev_event_code_get_name(EV_ABS, code)); |
|
|
|
|
num_axes++; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return num_axes; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int |
|
|
|
|
EvdevAddAbsValuatorClass(DeviceIntPtr device, int num_scroll_axes) |
|
|
|
|
@ -1178,6 +1211,7 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device, int num_scroll_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 */ |
|
|
|
|
int num_faked_axes; |
|
|
|
|
Atom *atoms; |
|
|
|
|
int mapping = 0; |
|
|
|
|
|
|
|
|
|
@ -1195,28 +1229,11 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device, int num_scroll_axes) |
|
|
|
|
if (num_axes < 1) |
|
|
|
|
goto out; |
|
|
|
|
|
|
|
|
|
/* 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++; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
num_faked_axes = EvdevAddFakeSingleTouchAxes(pInfo); |
|
|
|
|
if (num_faked_axes < 0) |
|
|
|
|
goto out; |
|
|
|
|
|
|
|
|
|
num_axes += num_faked_axes; |
|
|
|
|
|
|
|
|
|
/* Absolute multitouch axes: adjust mapping and axes counts. */ |
|
|
|
|
for (axis = ABS_MT_SLOT; axis < ABS_MAX; axis++) |
|
|
|
|
|