[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