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.
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>
One macro that also defines the cleanup function, one macro that only
defines the unref. This is required for any place where we want to
use cleanup from multiple source files - like the test suite.
Looks pretty const to me but compiler authors presumably have a
different interpretation.
../src/libei-log.c:52:34: error: initializer element is not a compile-time constant
static const char *reset_code = ansi_colorcode[RESET];
^~~~~~~~~~~~~~~~~~~~~
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
If we get EPROTO or EINVAL on the connection, all we do is disconnect
(ourselves or the client). So let's drain the fd so there's no other
data to be parsed by accident and then continue with actually
disconnecting.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
We will need eis_device_foo() for the actual event API soon, so let's
move the internal handlers out of the way by namespacing them.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Previous sequence reproducible with the eis-demo-server and
ei-demo-client:
- ctrl+c the client
- eis client dispatch fails with an rc < 0 due to the socket being closed
- eis calls eis_client_disconnect() which calls eis_seat_removed()
- that triggers an event for `SEAT_UNBIND`
- seat is set to REMOVE
- eis-demo-server gets the `SEAT_UNBIND` event and (correctly) calls
eis_seat_remove() since it doesn't know the client is disconnected
yet. That is due to the library unwinding the state transparently.
Fix this by splitting out the calls: eis_drop_seat() is the internally
used one that sets it to a new state of REMOVED_INTERNALLY, and then
eis_seat_remove merely updates the state.
Fixes#10
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Prevents any ABI suprprises by the enums being expanded to long or
shortened to char on special targets.
Fixes#11
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
The latest version of the portal communication adds session capabilities
and wraps the calls a bit differently.
This now also includes a helper tool for the impl.portal part so we can
run xdg-desktop-portal against that without the need for a mutter
implementation.
Use:
- run the eis-demo-server
- run the eis-fake-impl-portal
- run the xdg-desktop-portal (it'll use the fake impl portal)
- run an ei client with the portal enabled
Note that the ei-fake-portal is a shortcut, it will open eis directly
without going through the impl.portal.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
In the case of a refused portal connection we get disconnected before we
had a chance to send the CONNECT message. This still needs to queue a
disconnect event and thus bubble back up to the caller.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
If we have libreis setting properties on the connection, this looks to
the server like they're coming from the ei connection. But libreis is a
different context than the libei context later, so when libei
initializes, it may set the same properties again. Since the libei
context doesn't know about the properties, it can't filter internally
and will send the properties to the server.
So we need to do all the permissions checks in the server to make sure
we don't overwrite values that we're not allowed to overwrite.
There are no real restrictions on changing properties from within the
eis implementation (other than not being able to set the reserved
namespaces).
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Pass the fd into the original context creation, then write any changes
to the wire immediately. For the capabilities that means we can't build
them up as before anymore, so change the API to have a vararg function
and require the allowed capabilities to be passed in.
There's likely little use for the previous allow-vs-deny policy etc, so
let's not make things more complicated an they have to be.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
There is data that libei and the EIS implementation will want to
exchange that is not covered by the immediate API.
To avoid having to add APIs for all of these, let's provide a generic
property API that both server and client can use to exchange this info.
The property API provides read/write/delete permissions but those only
apply to the client, not the server. The idea is that a server can
create (or restrict) properties that the client can read but not modify
and/or delete. A special-case are properties filled in automatically by
libei: ei.application.pid and ei.application.cmdline. These could be
used by e.g. the portal implementation to match permissions.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This allows us to transmit extra information about the client before the
server has to decide on whether it wants to connect us.
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>
This allows a client to trigger kinetic scrolling (or prevent it).
For compositors implementing EIS, the only realistic scroll source is
continuous which allows for scroll stop events. So let's give the client
the opportunity to trigger those on demand.
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>
Since the server controls the keymap, and that keymap is likely merged
with some other device let's add the events so we notify the client of
things like numlock-is-down etc.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>