Add a function to retrieve the udev_device handle from a libinput device
authorPeter Hutterer <peter.hutterer@who-t.net>
Fri, 31 Oct 2014 00:53:53 +0000 (10:53 +1000)
committerPeter Hutterer <peter.hutterer@who-t.net>
Tue, 2 Dec 2014 23:09:39 +0000 (09:09 +1000)
The libinput device abstracts a number of things but sometimes the underlying
device is important. The udev device provides the necessary handle to access
that underlying device and various sysfs properties that may be necessary.

A function returning the device node would've done the same thing but is more
prone to race conditions than the udev_device.

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

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
src/evdev.c
src/evdev.h
src/libinput.c
src/libinput.h
test/device.c

index 19b861f4a157efe7955d4f4fa5e1b11633df1c35..c2d10d7e885f76adf5d0e6592f00a5c2b604999f 100644 (file)
@@ -1632,6 +1632,12 @@ evdev_device_get_id_vendor(struct evdev_device *device)
        return libevdev_get_id_vendor(device->evdev);
 }
 
+struct udev_device *
+evdev_device_get_udev_device(struct evdev_device *device)
+{
+       return udev_device_ref(device->udev_device);
+}
+
 void
 evdev_device_set_default_calibration(struct evdev_device *device,
                                     const float calibration[6])
index e4144ecb66f457b00432eed88d569abab2f61655..033d4558e5771e4b852ad784ec37cc0ddd5fb5a3 100644 (file)
@@ -234,6 +234,9 @@ evdev_device_get_id_product(struct evdev_device *device);
 unsigned int
 evdev_device_get_id_vendor(struct evdev_device *device);
 
+struct udev_device *
+evdev_device_get_udev_device(struct evdev_device *device);
+
 void
 evdev_device_set_default_calibration(struct evdev_device *device,
                                     const float calibration[6]);
index c318eeeccbbd2a519f725171e4cc14521529109a..96b255a940801d8b5ecc13b626d0dd54dfc348f6 100644 (file)
@@ -1226,6 +1226,12 @@ libinput_device_set_seat_logical_name(struct libinput_device *device,
                                                               name);
 }
 
+LIBINPUT_EXPORT struct udev_device *
+libinput_device_get_udev_device(struct libinput_device *device)
+{
+       return evdev_device_get_udev_device((struct evdev_device *)device);
+}
+
 LIBINPUT_EXPORT void
 libinput_device_led_update(struct libinput_device *device,
                           enum libinput_led leds)
index 26d94ff4a37fe88f2febf409692a7c7b97492dfb..d567df440f44c7700591e7daddb3f1336829b0ad 100644 (file)
@@ -1396,6 +1396,24 @@ int
 libinput_device_set_seat_logical_name(struct libinput_device *device,
                                      const char *name);
 
+/**
+ * Return a udev handle to the device that is this libinput device, if any.
+ * The returned handle has a refcount of at least 1, the caller must call
+ * udev_device_unref() once to release the associated resources.
+ *
+ * Some devices may not have a udev device, or the udev device may be
+ * unobtainable. This function returns NULL if no udev device was available.
+ *
+ * Calling this function multiple times for the same device may not
+ * return the same udev handle each time.
+ *
+ * @param device A previously obtained device
+ * @return A udev handle to the device with a refcount of >= 1 or NULL.
+ * @retval NULL This device is not represented by a udev device
+ */
+struct udev_device *
+libinput_device_get_udev_device(struct libinput_device *device);
+
 /**
  * @ingroup device
  *
index 6843824a4da37d3398b06fa5c4faa5012dc94679..84984f4c6c1df3ca4ad26c57c618749277166b91 100644 (file)
@@ -618,6 +618,17 @@ START_TEST(device_ids)
 }
 END_TEST
 
+START_TEST(device_get_udev_handle)
+{
+       struct litest_device *dev = litest_current_device();
+       struct udev_device *udev_device;
+
+       udev_device = libinput_device_get_udev_device(dev->libinput_device);
+       ck_assert_notnull(udev_device);
+       udev_device_unref(udev_device);
+}
+END_TEST
+
 int main (int argc, char **argv)
 {
        litest_add("device:sendevents", device_sendevents_config, LITEST_ANY, LITEST_TOUCHPAD);
@@ -640,5 +651,7 @@ int main (int argc, char **argv)
        litest_add("device:sendevents", device_disable_topsoftbutton, LITEST_TOPBUTTONPAD, LITEST_ANY);
        litest_add("device:id", device_ids, LITEST_ANY, LITEST_ANY);
 
+       litest_add("device:udev", device_get_udev_handle, LITEST_ANY, LITEST_ANY);
+
        return litest_run(argc, argv);
 }