[PATCH v2 libinput 3/3] Deprecate libinput_device_has_capability

Peter Hutterer peter.hutterer at who-t.net
Tue Jan 27 15:47:28 PST 2015


With the introduction of capability events, this is theoretically racy.

In the current implementation that's fine as we add the capabilities before we
return the device, but in the future a capability event may be in the event
queue to add/remove a capability, so this call is unreliable.

Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
Changes to v1:
- check for TOUCH to not be in the capability events

 src/libinput.h |  9 +++++++--
 test/touch.c   | 29 +++++++++++++++++++++++------
 2 files changed, 30 insertions(+), 8 deletions(-)

diff --git a/src/libinput.h b/src/libinput.h
index 50bedc8..1029483 100644
--- a/src/libinput.h
+++ b/src/libinput.h
@@ -1593,13 +1593,18 @@ libinput_device_led_update(struct libinput_device *device,
 /**
  * @ingroup device
  *
- * Check if the given device has the specified capability
+ * Check if the given device has the specified capability.
+ *
+ * @note This function should not be used. It suffers from potential race
+ * conditions as it will give the capabilities of the device right now which
+ * may be different to the capabilities as seen in the event stream.
  *
  * @return 1 if the given device has the capability or 0 if not
  */
 int
 libinput_device_has_capability(struct libinput_device *device,
-			       enum libinput_device_capability capability);
+			       enum libinput_device_capability capability)
+	LIBINPUT_ATTRIBUTE_DEPRECATED;
 
 /**
  * @ingroup device
diff --git a/test/touch.c b/test/touch.c
index 29890a4..03dbe5f 100644
--- a/test/touch.c
+++ b/test/touch.c
@@ -427,19 +427,36 @@ START_TEST(fake_mt_exists)
 	struct litest_device *dev = litest_current_device();
 	struct libinput *li = dev->libinput;
 	struct libinput_event *event;
+	struct libinput_event_device_capability *cev;
 	struct libinput_device *device;
+	bool pointer_cap_found = false;
 
 	litest_wait_for_event_of_type(li, LIBINPUT_EVENT_DEVICE_ADDED, -1);
 	event = libinput_get_event(li);
 	device = libinput_event_get_device(event);
+	libinput_device_ref(device);
+	libinput_event_destroy(event);
 
-	ck_assert(!libinput_device_has_capability(device,
-						  LIBINPUT_DEVICE_CAP_TOUCH));
+	litest_wait_for_event_of_type(li,
+				      LIBINPUT_EVENT_DEVICE_CAPABILITY_ADDED,
+				      -1);
+	while ((event = libinput_get_event(li))) {
+		cev = libinput_event_get_device_capability_event(event);
 
-	/* This test may need fixing if we add other fake-mt devices that
-	 * have different capabilities */
-	ck_assert(libinput_device_has_capability(device,
-						 LIBINPUT_DEVICE_CAP_POINTER));
+		if (libinput_event_device_capability_get_capability(cev) ==
+		    LIBINPUT_DEVICE_CAP_POINTER)
+			pointer_cap_found = true;
+
+		/* This test may need fixing if we add other fake-mt devices that
+		 * have different capabilities */
+		ck_assert_int_ne(libinput_event_device_capability_get_capability(cev),
+				 LIBINPUT_DEVICE_CAP_TOUCH);
+	}
+
+	ck_assert(pointer_cap_found);
+
+	libinput_event_destroy(event);
+	libinput_device_unref(device);
 }
 END_TEST
 
-- 
2.1.0



More information about the wayland-devel mailing list