Commit graph

424 commits

Author SHA1 Message Date
Peter Hutterer
01a2ff2d72 brei: pass the proto object through to send_message
Makes for easier debugging since we can print names instead of just
ids/opcodes.
2023-03-03 11:21:26 +10:00
Peter Hutterer
2a8661f7ad protocol: move the seat bind to the seat object
Needs documentation but we can do this when we're done with everything.
2023-03-03 11:21:26 +10:00
Peter Hutterer
c98a9fc7d7 eis: update libeis-client to use the declare macros 2023-03-03 11:21:24 +10:00
Peter Hutterer
bcece3d3c1 eis: make sure our connection setup has the right version too 2023-03-03 11:20:42 +10:00
Peter Hutterer
aaf72f9263 protocol: add a seat interface
Incomplete, only supports the initial seat setup but binding to a seat
is still outside this interface.
2023-03-03 11:20:42 +10:00
Peter Hutterer
d95236aa3e Add the ei_callback interface versions
We can now bump ei_callback to a higher version if the client supports
it.
2023-03-03 11:20:42 +10:00
Peter Hutterer
a778a22e26 protocol: add an interface version announcement to the connection setup
The idea here is that the client announces the interfaces it can support
and their version (including the core ei_connection). The server can
then send the various bits based on those versions, where applicable.
2023-03-03 11:20:42 +10:00
Peter Hutterer
09826b8bd3 eis: add a reason to the disconnect message
Allows for slightly easier debugging in the case where we get
disconnected after some protocol error.
2023-03-03 11:20:42 +10:00
Peter Hutterer
db786c7822 protocol: add a ei_connection_setup interface
This replaces the connect/connect_done and version/get_version requests.
Immediately after connecting, the server sends an ei_protocol_setup
event to the client with the ID of the object and the server's highest
supported version number (of this object).

This is a one-shot object that the client can use to configure its name
and whether it is a sender or receiver context. Once .done is sent, the
object is discarded.

The server version is sent along to the client to allow for requests to
be added to this object in the future.

As a fixme left: the client now assumes to be connected as soon as the
.done request is sent and the following sync event is received. The
EIS implementation will not have actually eis_client_connect()ed the
client yet, but it's good enough for now.

Arguably, the CONNECTED event is superfluous anyway since *any* event
other than DISCONNECTED indicates connected status. CONNECTED is a
leftover from when the client created devices and needed to know if it's
worth doing so.
2023-03-03 11:20:42 +10:00
Peter Hutterer
9cbce95326 protocol: add a sync request and the ei_callback interface
Directly copied from wayland. Note that while the wayland protocol
specifies the data is the last event serial in our case here it's just
0 since we don't have any event serials (yet).

The sync request is currently triggered after connection, merely to
ensure it works, it's not actually needed.
2023-03-03 11:20:42 +10:00
Peter Hutterer
d0e6c251b6 protocol: rename the ei core interface to ei_connection
In the protocol this is a simple rename but in the implementation we can
now separate the protocol object out from the ei/ei-client context
itself by having the ei_connection objects.
2023-03-03 11:20:42 +10:00
Peter Hutterer
b02b4f0901 Drop protobuf in favour of a custom protocol
This protocol is wayland-like though it uses a slightly different
message format. The XML file uses the same structure, except for the
"fixed" type which is "float" here.

The scanner uses a jinja template to generate source and header files
for ei and eis which are now used instead of the protobuf-generated
objects. Note that the scanner is a minimal working version, some
features like enum value checks are not yet implemented.

Unlike wayland we do not need to generate the libwayland-like library,
we only need the wire protocol parser - some shortcuts can thus be taken.

To keep the changes simple, the protocol currently is a flat protocol
with only one interface and all messages copied over from the previous
ei.proto file. In future commits, this will be moved to the respective
interfaces instead.
2023-03-03 11:20:42 +10:00
Peter Hutterer
49c329e0de util-io: add a few helper functions to iobuf
Currently unused, but will be in the future
2023-03-03 11:20:42 +10:00
Peter Hutterer
f5e3177f27 ei-device: use the setter declaration macros 2023-03-03 11:20:42 +10:00
Peter Hutterer
ba55bef917 Add ei/eis getters for the device id 2023-03-03 11:20:42 +10:00
Peter Hutterer
e3c34830db ei: rename ei_set_connection to ei_set_socket
Current plans are to use the "connection" term for the ei_connection
interface in the (future) protocol, so let's rename this to avoid
clashes.
2023-03-03 11:20:42 +10:00
Peter Hutterer
1ddf8058e6 util: mmap with MAP_PRIVATE instead of MAP_SHARED
Our only use-case where we use this utility is for keymaps. Those have
to be MAP_PRIVATE in wayland's wl_seat version 8 so let's do the same to make
make sure we're compatible.
2023-03-03 11:16:48 +10:00
Peter Hutterer
d95c1d30f8 util: add some mask helpers 2023-03-03 11:16:48 +10:00
Peter Hutterer
e74e0d1c18 eis: use eis_client_get_context instead of parent 2023-03-03 11:16:48 +10:00
Peter Hutterer
7509ee257f libeis: make eis_client_get_context() part of the public API
So we don't need to carry two pointers around in the caller.
2023-03-03 11:16:48 +10:00
Peter Hutterer
f300a4919a util: add msleep() 2023-03-03 11:16:48 +10:00
Peter Hutterer
1748ddaf3d eis: don't EINVAL if a coordinate is outside the region
From the documentation:
"The x/y coordinate must be within the device's regions or the event is
silently discarded."

libei discards it but if it somehow makes it through anyway, let's
discard it again.
2023-02-23 16:01:47 +10:00
Peter Hutterer
866a754223 ei: implement ei_device_get_width/height 2023-02-20 15:42:56 +10:00
Peter Hutterer
17dfb4580d util: rename xvasprintf to xvaprintf
This doesn't printf into a buffer, so let's rename it
2023-02-16 15:29:18 +10:00
Peter Hutterer
0541668443 eis: don't send stop_emulating for a sender device
The check is currently missing from a number of libeis APIs but in most
cases we can blame the EIS implementation and say "don't do this".
Device removal is an exception since that is still required.
2023-02-13 16:18:08 +10:00
Peter Hutterer
b6a901e690 eis: divide the headers up across multiple files
libeis-private.h was getting unwieldly, so let's split this up so
(most) anything eis_foo goes into libeis-foo.h.
2023-02-13 14:01:08 +10:00
Peter Hutterer
8973101313 ei: divide the headers up across multiple files
libei-private.h was getting unwieldly, so let's split this up so
(most) anything ei_foo goes into libei-foo.h.
2023-02-13 14:01:08 +10:00
Peter Hutterer
d1282b3681 Add some extra getters for the context and the eis_client
These are all noops but this way we can ensure that get_context() and
get_client works on all objects - useful for (upcoming) generated code.
2023-02-13 14:00:19 +10:00
Peter Hutterer
56c992f4c6 Remove the public API to query the client version number
With the planned switch to a protocol supporting multiple interfaces
(a la wayland), a single version number is no longer useful. Remove this
API, we can add something more specific later if we need to.
2023-02-13 13:55:44 +10:00
Peter Hutterer
aea4138da5 util: undo accidental rename from source->is_active to is_sender
Runaway sed in f35be22d "Rename ei active/passive to sender/receive"
2023-02-13 13:28:31 +10:00
Peter Hutterer
e5b0dfc1a9 util: add macros to declare getters and setters
Reduces the amount of boilerplate that needs to get written.
2023-02-13 13:27:57 +10:00
Peter Hutterer
34ebddf528 util: add a object getter helper for fields as refs
Same as the existing macro, but returns &field instead of field.
2023-02-13 13:27:39 +10:00
Peter Hutterer
ff9830c122 Add a sequence number to START_EMULATING
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".
2023-02-09 11:48:29 +10:00
Peter Hutterer
a5cc87c837 Purge the properties from the protocol
The primary use-case for these properties in libei itself was to send
some fixed information (pid, cmdline and conection type). In the portal
case, these can be obtained out-of-band via the portal. In the
non-portal case these can be obtained from the socket itself (fetch pid,
look up /proc/pid/cmdline) which is just as reliable as trusting
whatever libei sends.

The only other use-case for the properties was the activation id in the
InputCapture::Activated portal signal. This can be achieved with a
serial in the START_EMULATING event.
2023-02-09 11:48:29 +10:00
Peter Hutterer
479bda259a Purge libreis from the repo
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.
2023-02-09 11:48:28 +10:00
Peter Hutterer
8d7d6ca8b7 proto: drop the Packet message, replace with 4 byte prefix
We need some sort of length field to be able to know how long the next
message is. But for simplicity, we might as well just write that
explicitly on the wire instead of wrapping our messages into yet another
message. This makes the wire format slightly simpler since the first 4
bytes are now always the length, without the previous 0x0d prefix
caused by the protobuf encoding.

0x0d == (field number << 3) | wire_type == 1 << 3 | 5
(see https://protobuf.dev/programming-guides/encoding/#structure)
2023-02-09 11:47:45 +10:00
Peter Hutterer
dd32adb319 brei: drop the explicit src in a #include statement 2023-02-09 11:42:03 +10:00
Peter Hutterer
520c20904e meson.build: use proper include handling for the proto dir 2023-02-09 11:42:03 +10:00
Peter Hutterer
f9d691e98b eis: don't allow connecting a disconnected client 2023-02-02 15:17:24 +10:00
Peter Hutterer
19c85e7ee1 ei: fix a typo 2023-02-02 15:16:56 +10:00
Peter Hutterer
e515edafa5 ei: re-order a few arguments to match the order in the protocol
No functional changes
2023-02-01 12:52:34 +10:00
Peter Hutterer
affc464caa util-time: fix the us2ms function
Turns out this was converting in the wrong direction and the only call
site we had didn't notice/care.
2023-02-01 12:52:34 +10:00
Olivier Fourdan
39f3ec007b liboeffis: protect from interrupted system calls
In various places, including the DBUS calls which can take some time, if
a SIGALRM triggers, the call will fail.

To prevent this from happening, use the wrappers when possible and make
sure to block the SIGALRM signal when issuing DBUS calls.

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
2022-12-08 12:37:46 +10:00
Olivier Fourdan
8bcbc53c0f ei: Use the signal protected wrappers
To prevent against unexpected interrupted system calls.

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
2022-12-08 12:37:46 +10:00
Peter Hutterer
1991b8f52d util: change the signal handler to a context-manager like macro
Change the signal-blocking helper to take a vararg list of signals to
block and provide a magic macro that works like python's context
manager, using  attribute(cleanup).

In our for loop we create a new struct with the old sigmask and a
boolean that's always true. We enter the body of the loop once and
set that boolean to false on the second run, i.e. we never do more than
one run. On loop exit, the destroy function for our struct restores the
previous signal mask.
2022-12-08 12:37:46 +10:00
Olivier Fourdan
0d3a398fee util: Add a wrapper for dup() and pipe2()
The wrappers take care of blocking the SIGALRM signal.

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
2022-12-08 12:37:46 +10:00
Olivier Fourdan
0ac9b1b02d util: Protect system calls against signals
Most system calls will fail if interrupted by a SIGALRM. Make sure we
block SIGALRM prior to do the syscall, and restore the set of signals
afterwards.

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
2022-12-08 12:37:46 +10:00
Olivier Fourdan
085f96c3bb util: Add block/release signals API
Add a couple of simple helper functions to block and releaset he SIGALRM
signal.

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
2022-12-08 12:37:46 +10:00
Peter Hutterer
eeefb3dc00 liboeffis is a wrapper library for the RemoteDesktop communication
libei used to have direct portal support code (see the git history) but:
- that code was a custom proposed portal that never went anywhere
- libei has slowly changed to be more an input event transport layer since
  it is now also used sending events *to* a libei context
- a number of libei users will never need the DBus code, either because they
  don't want it or because they talk Dbus themselves na ddon't need this
  abstraction.

Luckily, it's quite easy to move this into a separate library with a
simple API that does, effectively, the same trick as the old portal backend.
This API is aiming to be as simple as possible because the tools that
require anything more complex should talk to DBus directly.

An example tool that uses the API to retrieve an EIS fd over the
RemoteDesktop portal is included in this patch.

"Öffis" is a German word meaning public transport. It also sounds like the
French Œuf, the word for egg.

Co-authored-by: Olivier Fourdan <ofourdan@redhat.com>
2022-12-08 11:22:50 +10:00
Peter Hutterer
8fc654bfb0 Purge the portal code
The original idea here was that we would have an EmulatedInput portal
that allows the application to connect directly to the EIS
implementation to exchange input events - instead of ping-ponging DBus
events through the xdg-desktop-portal as the RemoteDesktop portal
requires.

This is no longer accurate, there are suggested PRs open to add
RemoteDesktop.ConnectToEIS to achieve the same through the existing
RemoteDesktop interface [1] and to add a new InputCapture portal
to allow for events to be sent to a libei receiver context [2].

The example EmulatedInput portal is thus superfluous and can be removed
from here.

We could switch the ei_setup_backend_portal() code to use RemoteDesktop
or InputCapture, depending on the context type, the utility of this is
questionable. Interaction with portals is complex, one needs to
implement the Session/Request interfaces correctly and in the case of
InputCapture also handle the complex zones/pointer barrier setup.
libportal does some of this (or it will, anyway) so it's more useful for
an application to use libportal and then just pass the received fd to
libei.

If there is a future need for this to be handled as part of libei, we
can (re)implement this, but for now it's best to just purge all of this.

[1] https://github.com/flatpak/xdg-desktop-portal/pull/762
[2] https://github.com/flatpak/xdg-desktop-portal/pull/714
2022-12-08 10:45:47 +10:00