[ANNOUNCE] libevdev - a library to wrap the evdev kernel interface

Peter Hutterer peter.hutterer at who-t.net
Thu Jun 27 13:46:37 PDT 2013


On Thu, Jun 27, 2013 at 11:15:03AM -0300, Wander Lairson Costa wrote:
> 2013/6/27 Peter Hutterer <peter.hutterer at who-t.net>:
> > For the last month or so I've been spending some time on a helper library
> > for evdev devices. The motivation is two-fold:
> >
> > * users of evdev currently issue ioctls directly, checking bit masks
> >   manually. all this is a source for error, especially as there are some
> >   inconsistencies in the ioctl APIs. For example, EV_REP does not behave the
> >   same way as EV_KEY. this can be abstracted through a library.
> >
> > * SYN_DROPPED signals that the process is not reading events fast enough.
> >   The process must re-sync the device, calculating the delta and processing
> >   it accordingly. This is similar across all drivers, but needlessly
> >   complicated.
> >
> > libevdev provides API calls for the various bits, so a client can work this
> > way:
> >
> >   struct libevdev *dev;
> >
> >   fd = open("/dev/input/event0", O_RDONLY);
> >   rc = libevdev_new_from_fd(fd, &dev);
> >
> >   if (libevdev_has_event_code(dev, EV_REL, REL_X))
> >         /* do something */
> >
> > including the various checks that prevent OOM access for invalid types/codes.
> >
> > For event handling, libevdev provides one call that returns the next event
> > in the queue:
> >
> >   rc = libevdev_next_event(dev, flags, &ev);
> >
> > if a SYN_DROPPED is the next event in the queue, libevdev syncs the device
> > state and returns 1. The process can then handle the delta by simply parsing
> > events until the device is fully synced again:
> >
> >   while ((rc = libevdev_next_event(dev, LIBEVEV_READ_SYNC, &ev)) == 1)
> >      /* this is a synced event */
> >
> >   if (rc == -EAGAIN)
> >      /* we are now fully synced */
> >   else
> >      /* error */
> >
> > For a more complete example: evtest written with libevdev would look like
> > this:
> > https://github.com/whot/libevdev/blob/master/tools/libevdev-events.c
> >
> > The code is still in its early stages and some parts are incomplete, but I'm
> > at the point where I'd like some comments and eyeballs to help find any
> > issues with the lot. Ideally, I'd like all of the X drivers and wayland to
> > eventually use libevdev. Plans to switch evemu, mtdev, etc. are on the todo
> > list somewhere too.
> >
> > Repository sits here:
> >     https://github.com/whot/libevdev
> > The API documentation is published here:
> >     http://whot.github.io/libevdev/doc/html/modules.html
> >
> > Suggestions, comments, criticism, etc. welcome.
> >
> 
> Hi,
> 
> First of all, congratulations for the work!

thank.

> I just gave a raw look at the documentation, and I see that
> libevdev_new returns the struct as the function return value whereas
> libevdev_new_from_fd returns it as an out parameter. Is there any
> implementation detail that prohibited you from making them returning
> the struct in the same way? My suggestion would be to choose a
> consistent approach, either returns the struct as the return value or
> as an output parameter, but do the same on both functions, if
> possible.

this is intentional.

libevdev_new() merely allocates memory, and libevdev_set_fd() then
associates the device with the pre-allocated struct. that can fail for a
number of reasons, all expressed through an errno. libevdev_new() can only
fail on allocation error.

otoh, libevdev_new_from_fd() is a shortcut for both calls together. Since
associating the device fd can fail, we need to return the error code. so we
pretty much have a API choice of 
  int libevdev_new_from_fd(fd, struct libevdev**);
or 
  struct libevdev* libevdev_new_from_fd(fd, int *errno);

I chose the former because any client will have a struct libevdev variable
or field already anyway, passing in a pointer is easy. In simpler clients,
errno may be ignored (or just checked for == 0).
does that make sense?

Cheers,
   Peter



More information about the wayland-devel mailing list