Add libinput_device_touch_get_touch_count()

This makes it possible for callers to detect whether a touch device is
single or multitouch (or even check for things like dual-touch vs real
multi-touch) and adjust the interface accordingly.

Note that this is for touch devices only, not touchpads that are just pointer
devices.

https://bugs.freedesktop.org/show_bug.cgi?id=104867

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
Peter Hutterer 2018-01-31 16:04:09 +10:00
parent 59eb10e593
commit 63e5372190
6 changed files with 92 additions and 0 deletions

View file

@ -2300,6 +2300,28 @@ evdev_device_has_key(struct evdev_device *device, uint32_t code)
return libevdev_has_event_code(device->evdev, EV_KEY, code);
}
int
evdev_device_get_touch_count(struct evdev_device *device)
{
int ntouches;
if (!(device->seat_caps & EVDEV_DEVICE_TOUCH))
return -1;
ntouches = libevdev_get_num_slots(device->evdev);
if (ntouches == -1) {
/* mtdev devices have multitouch but we don't know
* how many. Otherwise, any touch device with num_slots of
* -1 is a single-touch device */
if (device->mtdev)
ntouches = 0;
else
ntouches = 1;
}
return ntouches;
}
int
evdev_device_has_switch(struct evdev_device *device,
enum libinput_switch sw)

View file

@ -467,6 +467,9 @@ evdev_device_has_button(struct evdev_device *device, uint32_t code);
int
evdev_device_has_key(struct evdev_device *device, uint32_t code);
int
evdev_device_get_touch_count(struct evdev_device *device);
int
evdev_device_has_switch(struct evdev_device *device,
enum libinput_switch sw);

View file

@ -2941,6 +2941,12 @@ libinput_device_keyboard_has_key(struct libinput_device *device, uint32_t code)
return evdev_device_has_key((struct evdev_device *)device, code);
}
LIBINPUT_EXPORT int
libinput_device_touch_get_touch_count(struct libinput_device *device)
{
return evdev_device_get_touch_count((struct evdev_device *)device);
}
LIBINPUT_EXPORT int
libinput_device_switch_has_switch(struct libinput_device *device,
enum libinput_switch sw)

View file

@ -3713,6 +3713,20 @@ int
libinput_device_keyboard_has_key(struct libinput_device *device,
uint32_t code);
/**
* @ingroup device
*
* Check how many touches a @ref LIBINPUT_DEVICE_CAP_TOUCH device supports
* simultaneously.
*
* @param device A current input device
*
* @return The number of simultaneous touches or 0 if unknown, -1
* on error.
*/
int
libinput_device_touch_get_touch_count(struct libinput_device *device);
/**
* @ingroup device
*

View file

@ -293,3 +293,7 @@ LIBINPUT_1.7 {
LIBINPUT_1.9 {
libinput_device_switch_has_switch;
} LIBINPUT_1.7;
LIBINPUT_1.11 {
libinput_device_touch_get_touch_count;
} LIBINPUT_1.9;

View file

@ -1023,6 +1023,44 @@ START_TEST(touch_invalid_range_under)
}
END_TEST
START_TEST(touch_count_st)
{
struct litest_device *dev = litest_current_device();
struct libinput_device *device = dev->libinput_device;
ck_assert_int_eq(libinput_device_touch_get_touch_count(device), 1);
}
END_TEST
START_TEST(touch_count_mt)
{
struct litest_device *dev = litest_current_device();
struct libinput_device *device = dev->libinput_device;
struct libevdev *evdev = dev->evdev;
ck_assert_int_eq(libinput_device_touch_get_touch_count(device),
libevdev_get_num_slots(evdev));
}
END_TEST
START_TEST(touch_count_unknown)
{
struct litest_device *dev = litest_current_device();
struct libinput_device *device = dev->libinput_device;
ck_assert_int_eq(libinput_device_touch_get_touch_count(device), 0);
}
END_TEST
START_TEST(touch_count_invalid)
{
struct litest_device *dev = litest_current_device();
struct libinput_device *device = dev->libinput_device;
ck_assert_int_eq(libinput_device_touch_get_touch_count(device), -1);
}
END_TEST
TEST_COLLECTION(touch)
{
struct range axes = { ABS_X, ABS_Y + 1};
@ -1060,4 +1098,9 @@ TEST_COLLECTION(touch)
litest_add_for_device("touch:range", touch_invalid_range_over, LITEST_TOUCHSCREEN_INVALID_RANGE);
litest_add_for_device("touch:range", touch_invalid_range_under, LITEST_TOUCHSCREEN_INVALID_RANGE);
litest_add("touch:count", touch_count_st, LITEST_SINGLE_TOUCH, LITEST_TOUCHPAD);
litest_add("touch:count", touch_count_mt, LITEST_TOUCH, LITEST_SINGLE_TOUCH|LITEST_PROTOCOL_A);
litest_add("touch:count", touch_count_unknown, LITEST_PROTOCOL_A, LITEST_ANY);
litest_add("touch:count", touch_count_invalid, LITEST_ANY, LITEST_TOUCH|LITEST_SINGLE_TOUCH|LITEST_PROTOCOL_A);
}