Previously, a client could only bind to a capability immediately after
SEAT_ADDED and with a rather awkward API to confirm the capabilities.
Change this to allow for dynamic binding of capabilities, i.e. a client
calls ei_bind_capability() or ei_unbind_capability() whenever it feels
like, causing the respective devices of this capabilty to be added or
removed.
This allows for clients that are temporarily disinterested in a
capability but may require said capability later.
The default function takes one capability, a helper for enable/disable
multiple capabilities in one go is provided as well. On the protocol,
only the "bind" request exists which always represents the currently
wanted set of capabilities.
Note that the helper functions for multiple capabilities require NULL
(not zero) as sentinel, thanks to gcc.
This way eis_seat_has_capability() returns the effective capabilities
the server can actually use - no point creating touch devices when the
client has not confirmed that.
In theory we should have a eis_seat_get_effective_capabilities() to
differ between configured and effective capabilities, but I'm having a
hard time thinking of a use-case where the implementation forgets
which caps it enabled.
The side-effect of this patch is that adding a device without
capabilities requested by the client now produces warning.
Our API requires a client to know which capability to pass into the
drop_capabilities function. This doesn't work for capabilities newer
than the client's version so they do not get disabled. The client will
thus receive devices it didn't ask for and doesn't know how to handle.
Let's invert the requirement and require the caller to confirm the
capabilities it wants - all others are dropped.
This is an API break but also requires updates of all clients, the
previous simple case of just calling ei_seat_bind() will now result in
zero capabilities.
This effectively provides the EIS implementation with a notification
that the client will actually send events in the near future. To be used
by e.g. synergy-like clients when the pointer enters the logical screen
so that the EIS implementation can flash a warning or something.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
There's nothing in the protocol to modify the client device state from
the server, so a pause/resume cycle must leave the client with the
same(-ish) state. Pause is really just that, a short "no event now
please". Anything that would require e.g. modifying the device state by
releasing keys or buttons should result in the device being removed and
re-added.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This changes the protocol so that it is the EIS implementation that
creates devices within a seat.
A client now "binds" to a seat and the EIS implementation creates
devices matching the requested capabilities. A client can close a device
if it no longer wants those but otherwise everything (including pointer
ranges) is handled by the server.
This is one giant patch because changes at the protocol level cannot
easily be broken out into smaller patches. Some FIXMEs are left which
will be handled in follow-up patches, e.g. the keymap handling is
basically broken right now.
Fixes#7
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Removing a seat could cause two device remove events to happen. Fix this by
splitting the removal up into two bits: removed by server and removed by
client. Only once both bits are set, remove the device.
This needs to happen in libei and libeis.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
To cut down on the boilerplate, an unref-able struct variable can now be
declared as
_unref_(type) *name = NULL;
which is the equivalent of
_cleanup_(type_unrefp) struct type *name = NULL;
Let's see how that style ends up reading.
This means we can get rid of the custom _cleanup_foo_ functions everywhere, no
need for all the extra #defines etc. A somewhat special case is systemd which
defines the various unrefp functions for us in the headers, so we can use them
directly.
OBJECT_IMPLEMENT_UNREF now also creates the unrefp function for this object -
this of course conflicts where DECLARE_UNREF_CLEANUP_FUNC is in scope. Not a
problem so far, let's see how we go.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
After CONNECT, the EIS implementation needs to add one or more seats. The
libei client can only create devices within those seats. This mirrors the
wayland hierarchy as well as the X.Org one.
The seat has a set of allowed capabilities, so the client knows ahead of time
when it may not be possible to create a specific device.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Because events may be in-transit when a client removes the device, we need to
make this a full roundtrip to the server. Otherwise the client may assume a
device is removed, releases all references and then gets the original device
added event for that device. Better to have this as a round-trip instead.
This requires the server to call eis_device_disconnect() on the removed
notifications but we do so during eis_event_unref() anyway in case the server
forgets.
And it changes some of the API behaviors, so adjust the tests for that.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
The previous approach would implicitly allow any capability not known to the
server. Switch instead to requiring an explicit 'ok' for any capability the
server wants to support.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Naming scheme is now: ei_device_<capability>_get/set_<what>. So far the
range is the only one where we had to deal with the same thing for two
different capabilities and it's unlikely we'll have to have different keymaps
for different capabilities. But still, let's do this now while it's still
easy.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Naming scheme is now: ei_device_<capability>_configure_<what>. So far the
range is the only one where we had to deal with the same thing for two
different capabilities and it's unlikely we'll have to have different keymaps
for different capabilities. But still, let's do this now while it's still
easy.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
In case the RESUMED isn't written on the wire yet (or it's written with
sendmsg and thus a separate message on its own) we don't have the RESUMED
ready for us yet. Let's call another dispatch to make sure it's processed.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Where the server connects a device after the client has already removed it, we
need to ignore that message silently.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This was already spelled out in the documentation but just not yet
implemented. New starting state for any device added by EIS is "suspended",
the server needs to explicitly resume it before events are accepted.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This function dispatches until a stable state is reached - that could be no
event waiting or some event waiting to be processed.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>