[PATCH libinput] Add libinput_device_touch_get_touch_count()

Peter Hutterer peter.hutterer at who-t.net
Fri Mar 2 08:16:34 UTC 2018


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 at who-t.net>
---
 src/evdev.c       | 22 ++++++++++++++++++++++
 src/evdev.h       |  3 +++
 src/libinput.c    |  6 ++++++
 src/libinput.h    | 14 ++++++++++++++
 src/libinput.sym  |  4 ++++
 test/test-touch.c | 23 +++++++++++++++++++++++
 6 files changed, 72 insertions(+)

diff --git a/src/evdev.c b/src/evdev.c
index 257824aa..629d4e2f 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -2224,6 +2224,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 device 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)
diff --git a/src/evdev.h b/src/evdev.h
index 162adecb..e732e693 100644
--- a/src/evdev.h
+++ b/src/evdev.h
@@ -459,6 +459,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);
diff --git a/src/libinput.c b/src/libinput.c
index 8fb0ba92..5e675dd9 100644
--- a/src/libinput.c
+++ b/src/libinput.c
@@ -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)
diff --git a/src/libinput.h b/src/libinput.h
index 759bce91..d9f74d2f 100644
--- a/src/libinput.h
+++ b/src/libinput.h
@@ -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
  *
diff --git a/src/libinput.sym b/src/libinput.sym
index bb283407..aa2794e9 100644
--- a/src/libinput.sym
+++ b/src/libinput.sym
@@ -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;
diff --git a/test/test-touch.c b/test/test-touch.c
index b3a6d0a0..a14bcf4b 100644
--- a/test/test-touch.c
+++ b/test/test-touch.c
@@ -945,6 +945,26 @@ START_TEST(touch_release_on_unplug)
 }
 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
+
 void
 litest_setup_tests_touch(void)
 {
@@ -980,4 +1000,7 @@ litest_setup_tests_touch(void)
 	litest_add_for_device("touch:fuzz", touch_fuzz, LITEST_MULTITOUCH_FUZZ_SCREEN);
 
 	litest_add_no_device("touch:release", touch_release_on_unplug);
+
+	litest_add("touch:count", touch_count_st, LITEST_SINGLE_TOUCH, LITEST_TOUCHPAD);
+	litest_add("touch:count", touch_count_mt, LITEST_TOUCH, LITEST_SINGLE_TOUCH);
 }
-- 
2.14.3



More information about the wayland-devel mailing list