The API is quite long now, so let's split it up into multiple logical
groups. The main page is now roughly graspable, with seats, devices,
regions and keymaps in submodules.
The sender and receiver APIs are also grouped into two separate APIs -
anyone implementing either doesn't need the other, it just messes things
up.
Same as the corresponding ei change a few commits ago, this one does all
the EIS renaming in the same manner.
As with the libei changes, an EIS implementation must now handle the
EIS_DEVICE_CAP_BUTTON and EI_DEVICE_CAP_SCROLL capabilities. In
virtually all cases, clients will likely expect that a device with the
pointer or absolute pointer capabilities will also have button and
scroll capabilities.
Now that the protocol interfaces are more fine-grained, let's match this
with the C API too.
This is just a rename of things so that in general
ei_pointer_*foo now becomes ei_foo*.
A few notable renames for better readability here:
- ei_device_scroll_delta (because scroll_scroll is awkward)
- ei_event_scroll_get_dx/dy and
ei_event_scroll_get_discrete_dx/dy to indicate the delta-ness
Beyond that, clients must ensure to check/bind to the new
EI_DEVICE_CAP_BUTTON and EI_DEVICE_CAP_SCROLL capabilities to be able
to send button or scroll events.
Note that this API now allows for an EIS implementation to send a device
that only has a button or a scroll cap. Or a pointer cap without
buttons, etc. It's up to the clients how to handle such devices
(probably: ignore them).
Previously we had ei_seat.capabilities and ei_device.capabilities,
both referring to the same enum. The seat caps were used to bind,
the device caps were used to announce capabilities.
The device caps were already mostly superfluous as the information
they carried was implicitly available by the set of interfaces
the device announced - if the device has a keyboard interface
it must also have the keyboard capability.
So let's drop the separate enum and make the capabilities
the set of supported interfaces. In the device we can drop the
event directly and just send the interface list. In the seat
we have a capability event that sends each *possible* interface
with a custom-assigned mask. The client can then use that mask
to bind to the capability as before.
For example:
<- ei_seat.capability(0x1, "ei_pointer")
<- ei_seat.capability(0x4, "ei_keyboard")
<- ei_seat.capability(0x8, "ei_touchscreen")
<- ei_seat.done()
-> ei_seat.bind(0x4 | 0x8) # bind to keyboard and touchscreen
<- ei_seat.device()
-> ei_device.interface("ei_keyboard")
-> ei_device.interface("ei_touchscreen")
<- ei_device.done()
In the generated bindings we simply use the interface index
to generate the masks, but the protocol at least states that
the mask may not be constant.
Because the button/scroll interfaces are not exposed by the C API, some
of the handling is a bit awkward since we need to use both depending
whether we have pointer/pointer_absolute selected.
Fixes#28
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Split the ei_pointer protocol interface into ei_pointer,
ei_pointer_absolute, ei_scroll and ei_button.
This gets rid of the slightly awkward pointer vs pointer absolute
handling. Those were two different capabilities but tied to the same
interface.
Plus it paves the way for devices that are keyboards with scroll
buttons, etc.
The protocol name on an interface is a fixed string that is part of
the ABI since it's used in a few messages (e.g.
ei_handshake.interface_version). To avoid typos, let's expose that
string in the scanner and #define it in the generated sources.
Since these events are merely notifications of a single object, we can make
this more generic. This allows us to introduce future capabilities without
having to bump the seat.
`memfd_create` doesn't seem to be supported on
all platforms (e.g. ubuntu 18 has trouble with it).
Even though, I was able to substitute `memfd_create`
with a direct system call, I was not able to get
the `MFD_CLOXEC` flag (from fcntl.h) working cleanly
(there were redefinitions/conflicts for other
structures when trying to use <linux/*> headers).
Making it optional for time being till we have
figured out how to make it work broadly.
This is the recommendation from meson documentation. The default
option is still to create a shared library but doing it this
way gives users an opportunity to create either a shared, static
or both type of libraries by setting up the meson build appropriately.
Here is the result with the default setup:
$ meson setup . _build
$ meson compile -C _build
$ find _build | egrep "(\.so|\.a)$"
_build/subprojects/munit/libmunit.so
_build/test/libunittest.a
_build/test/libeierpecken.a
_build/src/libei.so
_build/src/liboeffis.so
_build/src/libutil.a
_build/src/libeis.so
And here it is with the overridden flag:
_build/subprojects/munit/libmunit.a
_build/test/libunittest.a
_build/test/libeierpecken.a
_build/src/libei.a
_build/src/libeis.a
_build/src/liboeffis.a
_build/src/libutil.a
$ meson setup . _build --default-library=static
$ meson compile -C _build
$ find _build | egrep "(\.so|\.a)$"
Moving my local hooks into a pre-commit hook set that others can find
useful too:
- remove trailing whitespaces and newlines
- don't allow commits to the "main" branch
- python black and python ruff (same args as in the CI)