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 <[email protected]>
---
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

_______________________________________________
wayland-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to