mirror of
https://gitlab.freedesktop.org/libevdev/libevdev.git
synced 2026-01-11 21:30:23 +01:00
Don't treat devices with (ABS_MT_SLOT - 1) as multitouch devices
Some devices (PS3 sixaxis controller) merely have a bunch of axes, without the semantic information that linux/input.h requires. For those, the ABS_MT range may be merely another axis, not the special range that we need to treat it with. Use a simple heuristic: if ABS_MT_SLOT - 1 is enabled, don't treat ABS_MT as multitouch axes. The ABS_MT_SLOT - 1 axis is not used for a real axis. Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> Reviewed-by: David Herrmann <dh.herrmann@gmail.com>
This commit is contained in:
parent
714c2ffa9e
commit
546efc783c
3 changed files with 49 additions and 2 deletions
|
|
@ -333,7 +333,12 @@ libevdev_set_fd(struct libevdev* dev, int fd)
|
|||
goto out;
|
||||
|
||||
dev->abs_info[i] = abs_info;
|
||||
if (i == ABS_MT_SLOT) {
|
||||
|
||||
/* devices with ABS_MT_SLOT - 1 aren't MT devices,
|
||||
see the documentation for multitouch-related
|
||||
functions for more details */
|
||||
if (i == ABS_MT_SLOT &&
|
||||
!libevdev_has_event_code(dev, EV_ABS, ABS_MT_SLOT - 1)) {
|
||||
dev->num_slots = abs_info.maximum + 1;
|
||||
dev->current_slot = abs_info.value;
|
||||
}
|
||||
|
|
@ -627,7 +632,7 @@ update_key_state(struct libevdev *dev, const struct input_event *e)
|
|||
static int
|
||||
update_mt_state(struct libevdev *dev, const struct input_event *e)
|
||||
{
|
||||
if (e->code == ABS_MT_SLOT) {
|
||||
if (e->code == ABS_MT_SLOT && dev->num_slots > -1) {
|
||||
int i;
|
||||
dev->current_slot = e->value;
|
||||
/* sync abs_info with the current slot values */
|
||||
|
|
|
|||
|
|
@ -361,6 +361,15 @@ extern "C" {
|
|||
*
|
||||
* As with @ref bits, the logical state of the device as seen by the library
|
||||
* depends on the caller using libevdev_next_event().
|
||||
*
|
||||
* The Linux kernel requires all axes on a device to have a semantic
|
||||
* meaning, matching the axis names in linux/input.h. Some devices merely
|
||||
* export a number of axes beyond the available axis list. For those
|
||||
* devices, the multitouch information is invalid. Specfically, if a device
|
||||
* provides the ABS_MT_SLOT axis AND also the (ABS_MT_SLOT - 1) axis, the
|
||||
* device is not treated as multitouch device. No slot information is
|
||||
* available and the ABS_MT axis range for these devices is treated as all
|
||||
* other EV_ABS axes.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -425,6 +425,38 @@ START_TEST(test_slot_number)
|
|||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_invalid_mt_device)
|
||||
{
|
||||
struct uinput_device* uidev;
|
||||
struct libevdev *dev;
|
||||
int rc;
|
||||
const int nslots = 4;
|
||||
int value;
|
||||
struct input_absinfo abs[] = { { ABS_X, 0, 2 },
|
||||
{ ABS_Y, 0, 2 },
|
||||
{ ABS_MT_POSITION_X, 0, 2 },
|
||||
{ ABS_MT_POSITION_Y, 0, 2 },
|
||||
{ ABS_MT_SLOT - 1, 0, 2 },
|
||||
{ ABS_MT_SLOT, 0, nslots - 1 }};
|
||||
|
||||
rc = test_create_abs_device(&uidev, &dev, 6, abs,
|
||||
-1);
|
||||
ck_assert_msg(rc == 0, "Failed to uinput device: %s", strerror(-rc));
|
||||
|
||||
ck_assert_int_eq(libevdev_get_num_slots(dev), -1);
|
||||
ck_assert_int_eq(libevdev_get_current_slot(dev), -1);
|
||||
ck_assert_int_eq(libevdev_set_slot_value(dev, 0, ABS_MT_POSITION_X, 0), -1);
|
||||
ck_assert_int_eq(libevdev_fetch_slot_value(dev, 0, ABS_MT_POSITION_X, &value), 0);
|
||||
|
||||
ck_assert(libevdev_has_event_code(dev, EV_ABS, ABS_MT_SLOT - 1));
|
||||
ck_assert(libevdev_has_event_code(dev, EV_ABS, ABS_MT_SLOT));
|
||||
|
||||
ck_assert_int_eq(libevdev_set_event_value(dev, EV_ABS, ABS_MT_SLOT, 1), 0);
|
||||
ck_assert(libevdev_get_event_value(dev, EV_ABS, ABS_MT_SLOT) == 1);
|
||||
|
||||
uinput_device_free(uidev);
|
||||
} END_TEST
|
||||
|
||||
|
||||
START_TEST(test_device_name)
|
||||
{
|
||||
|
|
@ -1129,6 +1161,7 @@ libevdev_has_event_test(void)
|
|||
tcase_add_test(tc, test_no_slots);
|
||||
tcase_add_test(tc, test_slot_number);
|
||||
tcase_add_test(tc, test_slot_init_value);
|
||||
tcase_add_test(tc, test_invalid_mt_device);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("device info");
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue