[PATCH libinput] Add a libinput_device_get_udev_devices() call for merged devices

Peter Hutterer peter.hutterer at who-t.net
Mon Feb 2 22:35:21 PST 2015


On Tue, Feb 03, 2015 at 09:36:14AM +0800, Jonas Ådahl wrote:
> On Fri, Jan 30, 2015 at 03:48:15PM +1000, Peter Hutterer wrote:
> > Merged devices may comprise of multiple event nodes. To get those we need to
> > return all udev devices we have.
> > 
> > This patch still leaves the backend where it is (one evdev device per libinput
> > device) and merely introduces the new API.
> > 
> > Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
> 
> Reviewed-by: Jonas Ådahl <jadahl at gmail.com>
> 
> Now, what do we do about libinput_device_get_sysname,
> libinput_device_get_name, libinput_device_get_id_product and
> libinput_device_get_id_vendor?

that's a problem. I'm going to withdraw this patch for now, my idea
instead was to provide a separate struct that contains the various
sysinfo bits of a device. So you'd then have code like this:

struct libinput_device_info *infos = libinput_device_get_info(&ninfo);
foreach info in infos {
        udev = libinput_device_info_get_udev_device(info);
        pid = libinput_device_info_get_id_product(info);

        etc.

        libinput_device_info_unref(info);
}

The info struct could contain the name, pid, vid, sysname, udev_device, etc.
and a ref to the actual device plus the usual ref/unref pair so callers can
keep it around.

The problem with that now is that we don't have a good way of notifying
a caller when the info gets out of date. For the current tablet plan
that would be whenever a capability is added or removed - you then know
another device was added or removed here. It's not too hard to envision
cases where adding a kernel device extends the libinput device but doesn't
add/remove a capability.
To do that properly we'd need another event again (SUBDEVICE_ADDED/REMOVED
or so), but that doesn't strike me as particularly nice. I'll have to think
about this some more first.

Cheers,
   Peter


> > ---
> > This is preparation work for the tablet support bits where we will end up
> > merging multiple devices into one struct libinput_device.
> > 
> >  src/libinput.c   | 10 ++++++++++
> >  src/libinput.h   | 43 ++++++++++++++++++++++++++++++++++++++++++-
> >  src/libinput.sym |  1 +
> >  test/device.c    | 31 +++++++++++++++++++++++++++++++
> >  4 files changed, 84 insertions(+), 1 deletion(-)
> > 
> > diff --git a/src/libinput.c b/src/libinput.c
> > index 39c4ef6..6185651 100644
> > --- a/src/libinput.c
> > +++ b/src/libinput.c
> > @@ -1414,6 +1414,16 @@ libinput_device_get_udev_device(struct libinput_device *device)
> >  	return evdev_device_get_udev_device((struct evdev_device *)device);
> >  }
> >  
> > +LIBINPUT_EXPORT size_t
> > +libinput_device_get_udev_devices(struct libinput_device *device,
> > +				 struct udev_device **udev_devices,
> > +				 size_t ndevices)
> > +{
> > +	if (ndevices > 0)
> > +		udev_devices[0] = evdev_device_get_udev_device((struct evdev_device *)device);
> > +	return 1;
> > +}
> > +
> >  LIBINPUT_EXPORT void
> >  libinput_device_led_update(struct libinput_device *device,
> >  			   enum libinput_led leds)
> > diff --git a/src/libinput.h b/src/libinput.h
> > index 59a841f..4cb8fe8 100644
> > --- a/src/libinput.h
> > +++ b/src/libinput.h
> > @@ -1561,6 +1561,9 @@ libinput_device_set_seat_logical_name(struct libinput_device *device,
> >  /**
> >   * @ingroup device
> >   *
> > + * @deprecated This function is deprecated and always returns the first udev
> > + * device. Use libinput_device_get_udev_devices() instead.
> > + *
> >   * 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.
> > @@ -1576,7 +1579,45 @@ libinput_device_set_seat_logical_name(struct libinput_device *device,
> >   * @retval NULL This device is not represented by a udev device
> >   */
> >  struct udev_device *
> > -libinput_device_get_udev_device(struct libinput_device *device);
> > +libinput_device_get_udev_device(struct libinput_device *device)
> > +	LIBINPUT_ATTRIBUTE_DEPRECATED;
> > +
> > +/**
> > + * @ingroup device
> > + *
> > + * Return the udev handles for the devices that make up this libinput
> > + * device, if any. The returned handles have a refcount of at least 1, the
> > + * caller must call udev_device_unref() once on each device to release the
> > + * associated resources.
> > + *
> > + * This function returns the number of available udev handles for this
> > + * device, but writes at most ndevices handles into the udev_devices array.
> > + *
> > + * Some devices may not have a udev device, or the udev device may be
> > + * unobtainable. This function returns 0 if no udev device was available.
> > + * Some libinput devices may be composed of multiple devices, not all of
> > + * which have a corresponding udev device. In this case, this function
> > + * returns all available udev devices.
> > + *
> > + * A device may be composed of multiple device nodes, these may appear or
> > + * disappear at any time. The list of udev devices can only be considered
> > + * static once all events have been processed until the next call to
> > + * libinput_dispatch().
> > + *
> > + * Calling this function multiple times for the same device may not
> > + * return the same udev handles each time.
> > + *
> > + * @param device A previously obtained device
> > + * @param udev_devices A pre-allocated array that will be filled with up to
> > + * ndevices udev handles.
> > + * @param ndevices Number of elements in udev_devices
> > + * @return The number of udev handles available for this device.
> > + * @retval 0 This device is not represented by a udev device
> > + */
> > +size_t
> > +libinput_device_get_udev_devices(struct libinput_device *device,
> > +				 struct udev_device **udev_devices,
> > +				 size_t ndevices);
> >  
> >  /**
> >   * @ingroup device
> > diff --git a/src/libinput.sym b/src/libinput.sym
> > index 671930e..32d39d5 100644
> > --- a/src/libinput.sym
> > +++ b/src/libinput.sym
> > @@ -127,5 +127,6 @@ global:
> >  	libinput_device_config_click_get_method;
> >  	libinput_device_config_click_get_methods;
> >  	libinput_device_config_click_set_method;
> > +	libinput_device_get_udev_devices;
> >  	libinput_event_get_device_capability_event;
> >  } LIBINPUT_0.8.0;
> > diff --git a/test/device.c b/test/device.c
> > index 76486f0..2e7a3bb 100644
> > --- a/test/device.c
> > +++ b/test/device.c
> > @@ -639,6 +639,8 @@ START_TEST(device_ids)
> >  }
> >  END_TEST
> >  
> > +#pragma GCC diagnostic push
> > +#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
> >  START_TEST(device_get_udev_handle)
> >  {
> >  	struct litest_device *dev = litest_current_device();
> > @@ -649,6 +651,34 @@ START_TEST(device_get_udev_handle)
> >  	udev_device_unref(udev_device);
> >  }
> >  END_TEST
> > +#pragma GCC diagnostic pop
> > +
> > +START_TEST(device_get_udev_handles)
> > +{
> > +	struct litest_device *dev = litest_current_device();
> > +	struct udev_device *udev_devices[3];
> > +	size_t ndevices;
> > +
> > +	udev_devices[1] = (struct udev_device *)0xab;
> > +	udev_devices[2] = (struct udev_device *)0xcd;
> > +
> > +	ndevices = libinput_device_get_udev_devices(dev->libinput_device,
> > +						    udev_devices,
> > +						    3);
> > +	ck_assert_int_eq(ndevices, 1);
> > +	ck_assert_notnull(udev_devices[0]);
> > +	udev_device_unref(udev_devices[0]);
> > +	ck_assert_ptr_eq(udev_devices[1], 0xab);
> > +	ck_assert_ptr_eq(udev_devices[2], 0xcd);
> > +
> > +	udev_devices[0] = (struct udev_device *)0xef;
> > +	ndevices = libinput_device_get_udev_devices(dev->libinput_device,
> > +						    udev_devices,
> > +						    0);
> > +	ck_assert_int_eq(ndevices, 1);
> > +	ck_assert_ptr_eq(udev_devices[0], 0xef);
> > +}
> > +END_TEST
> >  
> >  START_TEST(device_context)
> >  {
> > @@ -685,6 +715,7 @@ int main (int argc, char **argv)
> >  	litest_add_for_device("device:context", device_context, LITEST_SYNAPTICS_CLICKPAD);
> >  
> >  	litest_add("device:udev", device_get_udev_handle, LITEST_ANY, LITEST_ANY);
> > +	litest_add("device:udev", device_get_udev_handles, LITEST_ANY, LITEST_ANY);
> >  
> >  	return litest_run(argc, argv);
> >  }
> > -- 
> > 2.1.0
> > 
> > _______________________________________________
> > wayland-devel mailing list
> > wayland-devel at lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/wayland-devel


More information about the wayland-devel mailing list