This morning I wish to describe the userspace drivers for input devices like mice, keyboards, touchscreens, etc as implemented in libevdev. Starting with the `evdev_device_create` constructor called by libinput when libudev discovers a new supported device.


First it checks with libudev to do some final filtering (including a libinput-specific flag) and opens the device file via a Weston-provided callback from it's launcher backend.


From there libevdev checks it got the device file it expected, allocs/inits memory for it (as part of which it calls the real libevdev library, I thought it was embedded in libinput but no) reading necessary information from libudev's parsing & linear scanning a libinput-specific flatfile database for "device quirks" to apply to libevdev, discards all currently-pending events, calls the IOCtl to set the clock ID, integrates libinput's logging into libevdev, ...

Next it consults the "tags" libudev looked up (based on the configuration files provided by libinput) to determine which specific constructor & "pointer accelerator" it should call. I'll have to push those off to the rest of the week.

Then it adds it to the mainloop & UDev-specified "group" & "seat", & notifies any callers that a new device has been added.

When event(s) come in on that device file, libevdev first tries reading events from a ringbuffer, normalizing them & tracking device state.

Show thread

Once that ringbuffer is emptied it'll read in more to that ringbuffer from the device file, returning the first event it read in live to be dispatched to libinput's userspace driver.

So it appears that libinput's "evdev" wrapper provides the userspace wrappers, and it's underlying "libevdev" knows how to read input from the kernel drivers.


Show thread
Sign in to participate in the conversation

For people who care about, support, or build Free, Libre, and Open Source Software (FLOSS).