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).
This makes it easier to correlate a particular input transaction
(whether there are events or not) with out-of-band information like the
planned portal InputCapture::Activated signal's "activation-id".
libreis was intended for an intermediary to set some information that
the libei client cannot be entrusted with. In particular this was the
application name, the allowed capabilities, and some properties that -
once set - the client could no longer change (appid as probably the only
really useful one). The price for this was a rather complicated version
negotiation dance before the initial CONNECT request.
Now that we have a clear view of what's going to happen -
RemoteDesktop.ConnectToEIS and the InputCapture portal - there is no
longer any need for libreis. The extra information that libreis would've
sent is communicated out-of-band in both portals and are known to the
compositor at the time the connection is being established.
So we can simply drop this, it's no longer required and dropping it
makes the protocol significantly simpler anyway.
The basic set of functions and macros to have access to a libreis
context for our to-be-client.
Since we connect the ei context to a backend during peck_new(), we need
a new function for the case where we do want to have libreis in the
mix.
All we do here is decide whether the connect event gets handled, clients
are always effectively connected (i.e. the client does send the connect
request) since we set up the backend during init.
Currently only implemented for frame events, the vague plan for the
future is to merely queue the device events internally and "release"
them once a frame event was received, retrofitting the timestamp to the
C event struct (i.e. making ei_event_get_time() available on all device
events).
Meanwhile, the frame event it is.
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.
A libei context can be initialized as active or passive context -
an "active" context sends events, a "passive" context receives events.
The EIS context supports both simultaneously, it is up to the
implementation to disconnect libei clients that it does not want to
suppport.
For example, the xdotool use-case creates an active libei context. The
EIS implementation controls and sets up the devices, but libei
sends the events.
In an input-capturing use-case, the EIS implementation controls
and sets up the devices **and** sends the events. libei is merely the
receiver for any event, it cannot send events. Thus this use-case
requires a passive libei context.
Most of this code is copy/paste with minor modifications - libei already
had the code to send events, libeis had the code to receive events, so
the vast majority of this patch is copying the code into the respective
other library, swap "ei" and "eis" and then apply the various minor
modifications needed to hook into the existing library.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
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>
Already present in e.g. libinput and wayland, this event allows us to
group several events together to denote them as a logical group.
Required for multi-touch but as we've learned with Wayland it's also
required to group other events (scroll events in the case of Wayland).
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 is required for supporting synergy/barrier and similar clients.
Replacing the touch and pointer range we now have server-defined
rectangular regions that specify the active zones for this device.
For example, a dual-monitor EIS server would create two touch devices
with one region each for the respective monitors - libei-generated
touches would thus fall on the right area of the monitor. Or just one
device with one region if the second screen should be inaccessible.
A relative device may have multiple regions since it can reach all
screens in the layout.
This leaks the screen layout to libei but that is necessary for the
functionality to work. A libei client may need to control devices
through absolute coordinates and it needs to know where screen
transitions from one to the next screen happen:
+-----------++----------------+
| || |
| B||Q |
| |+----------------+
| |
| A|P
+-----------+
In the above example, position P is unreachable and a client that
controls input on both screens must know that it cannot transition from
A to P but it can transition from B to Q.
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>
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>
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>
Client-side the approach is a managed touch object rather than passing the
touchid around. This is intentional, it allows for a stackable API in the
future if we need to add things like pressure or major/minor to it.
On the server side the touches are managed through the event object anyway, so
we don't need the same abstraction there.
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>