If our client binds to a seat and then disconnects, insert an unbind
event in the EIS queue to unwind correctly.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Once a device is removed, it is moved to the seat's devices_removed
list and the seat's ref is dropped - meaning the seat no longer keeps
the device alive. Once the caller's refcounts drop, the device can be
destroyed.
The device still keeps the seat alive though through a ref.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
device IDs are combined with the seat ID, let's make sure the lower bits
are never 0 to be able to distinquish between a pure seat ID and a
device ID.
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>
The uinput path ended up diverged from the printf codepath and does not
create any seats and we can't process events.
Signed-off-by: David Edmundson <davidedmundson@kde.org>
Once the SEAT_REMOVED event has been processed, adding new devices is
pointless. But we do promise a DEVICE_REMOVED event for any device added with
ei_device_add(), so let's immediately queue an event and mark the device as
dead.
Since the SEAT_REMOVED event may still be pending in the queue (i.e. not yet
read by the client), we need to prepend the event to the queue. Note that
client that immediately add a device when a device is removed will cause
an infinite loop.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This simplifies the handling of devices that were never added a bit, including
handling the refs between seat and device. And for legitimate use-cases
there's no reason why a caller would create a device but never add it.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Previously we didn't always clean up properly, especially where unexpected
removals happened. So the new approach is:
- the device always has a ref to the seat, we must not remove the seat until
even not-yet-added devices are released
- the seat has a ref to the device *after* it was added. this is a circular
ref so we need to make sure the device is manually removed from the seat
so we can actually reach a refcount 1
This is made slightly more complicated by us calling ei_disconnect() whenever
we fail to write on the fd. The result is re-entrant functions that we need to
protect against inadvertent changes. The best option here is probably to mark
the context as degraded and clean up once we finished whatever we were really
doing - that's a larger rework though.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
xdotool sends the events and disconnects immediately, Xwayland queues up those
events until it has a seat but then also disconnects immediately. Let's
emulate this behavior so we can catch breakages before Xwayland sees them.
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>
Add a debug marker to show any changes done during the final event processing,
and print the event name for wrong event types.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Where the demo server is run with a --layout, set that in our local struct so
the printed messages use the correct keysyms.
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>
This fits better with the rest of the API and also fits much nicer into the
most common use-case of "device doesn't have a keymap".
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This is always a bug - where the device doesn't have recognized capabilities,
it should be rejected. libeis does the right thing and converts the
eis_device_connect() to a _disconnect() call but it's still useful to warn the
caller.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>