The only invocations we have right now of these callbacks ignore the
argument or force it to zero. But in the future we may have an interface
that requires a callback and that interface may need to store a
timestamp or object ID in this argument - so let's make sure we have
enough space for that.
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.
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.
Regardless of the ei_seat version, ei_seat.bind will support all
capablities of the negotiated ei_device interface. This means we don't need
to bump ei_seat just to add a new capability to ei_device.
Now that we have 64 bit integers on the wire and 64 bit object IDs,
we're already different to the Wayland protocol. So we might as well get
the full length and split message length and opcode again to make header
parsing and composing simpler.
This effectively reverts commit bf45a7182cb2f4c13f11e141fc846244d3ac6212.
Previously, we'd send one interface_version event for "ei_handshake"
immediately but all others after the client requests handshake.finish.
This was too confusing to document and not clear how it would work, so
let's make this simpler by splitting it up.
There is now a handshake_version event from the server, sent immediately
on connection that denotes the maximum version number for the interface.
And a handshake_version request from the client which must be the first
one by the client.
These were previously (1 << cap) for convenience but that results in the
capability mask on the wire starting at 2 - which is a bit awkward.
Lets shift them down by one so we start the mask at 1.
No real functional changes, this just changes the message header to be
header = [object_id, msglen << 16 | opcode].
The only difference to the wayland protocol is now the fixed vs float
but otherwise tools that can print/debug/mangle the wayland protocol
should be easily adjustable for this protocol too..
For most interfaces, the client announcing its supported version is
sufficient - the objects are all created server-side. For some
interfaces (ei_connection_setup and ei_callback right now) the client
needs to know the server-supported version.
So let's switch the current ei_connection_setup.version event (used to
negotiate ei_connection_setup's version) to a generic
`interface_version` event. This way our EIS implementation can
eventually send a version for ei_callback as well.
Leave the ei_callback as-is and instead add ei_pingpong for the same
thing initiated by the server. The interface is otherwise identical but
for the direction it is supposed to flow.
This reduces the possibility of a client accidentally sending a
request when it is supposed to handle an event or vice versa.
This is effectively the same as connection.sync, but goes the other way.
This adds the ei_callback.done request.
In libeis this is (currently) enforced immediately after sending the
connection object. Not required there and makes the code a bit messier
but this way we can ensure that any client library handles that part of
the code.
This event is to notify the client that an object used in a request was
unknown. This allows the client to work around race conditions like
binding to a seat that was removed.
This is currently the server-side only which is probably enough for now.
The only client-side created objects we have are the callbacks.