[PATCH libevdev 0/2] libevdev copy constructor

Peter Hutterer peter.hutterer at who-t.net
Tue Nov 12 23:44:57 PST 2013


On Wed, Nov 06, 2013 at 11:53:44AM +0100, David Herrmann wrote:
> Hi
> 
> On Tue, Nov 5, 2013 at 11:56 PM, Peter Hutterer
> <peter.hutterer at who-t.net> wrote:
> > On Tue, Nov 05, 2013 at 08:41:10AM +0100, David Herrmann wrote:
> >> But ok, lets talk about the other idea:
> >> I wasn't intending to set the "fd" field on the separate libevdev
> >> object. So anyone who gets access to the separate libevdev object
> >> would notice that immediately (get_fd() fails, or any other function
> >> that requires initialized libevdev objects). All they could do is
> >> query the state. No need to emulate libevdev_next_event() or something
> >> else. This object is "dead" and intended to be so.
> >> As I said, the "cleaner" way is probably a libevdev_cap object which
> >> just contains the capabilities. We would embed it in "struct libevdev"
> >> but allow separate access. However, "struct libevdev" itself doesn't
> >> have that much more information than the capabilities, so I thought
> >> this might be overengineering and we should just (mis-)use "struct
> >> libevdev" for it.
> >
> > what is the client supposed to do with the dead object?
> > if the client doesn't expect events from the object anyway, why even bother
> > unsetting the fd? or otherwise, if the client does expect events how will
> > it know that a failed libevdev_next_event() doesn't signal that the device
> > is dead and needs to be removed?
> >
> > also, what is the difference to
> >    libevdev_new_from_fd(fd);
> >    libevdev_enable_some_bits(fd);
> >    libevdev_disable_some_other_bits(fd);
> >    libevdev_change_fd(-1); /* deactivate the fd */
> >    pass_libevdev_to_recipient();
> 
> This is exactly what I need. I just thought
> libevdev_new_from_libevdev() or libevdev_copy() would be more
> convenient and avoid 50 syscalls.
> 
> > this way the new object is still "dead" and won't send events, but can be
> > used to create uinput devices. Since it's initialized you can't re-use it
> > with set_fd() but you could still hook it up to some random other fd but you
> > could do that with the copy constructor too afaict.
> 
> My use-case is:
> A lower layer handles the evdev device and libevdev object to read
> events and pass them to some upper layer. In between both layers is a
> remapper. Let's say it maps ABS_RX/RY/RZ to the new ABS_ACCEL_X/Y/Z
> because it's a mouse with builtin accelerometer. The mapper is device
> agnostic, though. It simply remaps the codes. The upper layer needs to
> detect the device type and know what to do with it. So we pass the
> libevdev object through and it can use libevdev_code_is_enabled() to
> test what kind of device it is.
> 
> Now, if we pass the unchanged libevdev object through, the upper layer
> will get ABS_RX instead of the remapped ABS_ACCEL_X. If we modify the
> original libevdev object, we will no longer get ABS_RX events, as it
> is disabled. So my idea was to have an object which just defines the
> capability set. A compositor can thus create the libevdev object, load
> any kind of remapper (which adjusts the capabilities) and then detect
> the device-type on top of the new capabilities.
> 
> If we don't do this, then either the mapper itself must do the device
> detection or the mapper must return to the compositor what kind of
> remapping it did. Both seem weird to me.

two options I can see here:
- have the remapping code in libevdev, so that the object taken by the upper
  layer is already doing what it is supposed to do.
- have the mapper as a separate entity and have the upper layer handle that
  as such.

I think the first one is relatively obvious, the second one would be
something along the lines of

upper_layer.c:

  dev = libevdev_new_from_fd();
  if (mapper_device_needs_remap(dev)) {
      struct mappings *maps = mapper_device_get_mappings(dev));
  }

  foreach event_in from libevdev:
        mapper_remap(event_in, event_out);

having said that, this means that the devices simply won't work properly
wherever the upper layer doesn't use the mapper and I suspect that for many
use cases libevdev is best situated to handle this.

Cheers,
   Peter


More information about the Input-tools mailing list