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>
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.
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>
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>
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
At least for event replaying it looks like we'll go through the
RemoteDesktop portal instead of creating another one that doesn't
provide any additional benefits.
See https://github.com/flatpak/xdg-desktop-portal/pull/762
When a device has multiple regions, ei_device_pointer_motion_absolute()
would walk all of the regions and bail out if the coordinates are
outside any region.
As a matter of facts, it means that an absolute event must fall within
all the device regions to succeed.
That doesn't seem right, it should be the opposite, the coordinates must
be within at least one region.
Fix the logic by reusing the existing ei_device_in_region() function.
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
This is primarily for namespacing: where a portal sets some properties
it needs to do so *before* the Connect event. By moving this out to a
different namespace we can separate this easier, avoiding a portal
accidentally sending a property event after it has already passed the fd
to the client.
Fixes#23
The same socket is used for pre-connection configuration by a portal and
for the actual client that then uses the data. The portal and the client
may need different protocol versions *and* there may be different REIS
intermediaries.
So let's allow version negotiation for the configuration through
transactions: a REIS intermediary must start/finish a transaction with a
given version number.
This is only partially implemented in libreis right now: each API call
is wrapped in a transaction. Since we support version 1 only anyway,
there's no need to do anything but send our version down the wire. In
the future where we actually need to negotiate, libreis will need a
reis_dispatch() so we can wait for the server version to arrive, parse
it, etc. before sending ConfigureVersion down the wire. It's likely this
will never be needed.
Let the client set the version number it wants on Connect. There is new
public API to query the client/server's version as set once the connect
finished (eis_client_get_version() and ei_get_version()) but there is
currently no public API for the client to select the version it actually
wants, other than whatever both support. IOW, it's not possible for the
client to say "I want version 8 but if that's not supported, use version
5".
Add a new protocol message "GetVersion" and the matching reply from the
server with "Version" that can be sent at any time. The server always
replies with the highest protocol version it supports, allowing the
client to choose the protocol version it wants.
These two messages also have a fixed string to make the protocol easy to
identify in hexdumps.
To avoid roundtrips on connection, libeis immediately sends the Version
message. Ideally and by the time the client actually starts, that
version is already available and we can continue without requiring a
full roundtrip.
This patch only adds the version exchange with the server, it does not
yet add the bits for the client to actually set the version.
Punt this job to the caller, any structured logging handler doesn't need
them anyway and it makes handling of messages more awkward.
For our default log handlers (fprintf) we can just append them
ourselves.
Fixes#19
For all but the simplest loggers, the current approach of "this is a
continuation of the previous message" doesn't work well. The caller
cannot know whether the *current* message is complete until it receives
the next message - but that message may never come.
Drop this approach, if we need to compile multiple messages into one,
we can handle this internally and then pass it all as one message to the
caller.
The demo client has an inner while loop for the events, followed by
the code to send events to the server. Skip that code if our while loop
indicated we'll stop.
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.
This silently ignores any bit higher than the target storage (e.g.
flag_set(some_uint32, 33)) but that's still better than silently writing
into random memory.
Add a c file for util-bits.h as well - only contains the tests but at
least that way those are picked up like all other util tests.
If a REIS implementation sends multiple ConfigureCapabilities messages,
the allowed capabilities would be whichever ones were sent last rather
than the intersection of all capablities.
Fallout from 7fc9498f1d.
There's a very limited use for configure messages after client
connection. The name is already static after connect anyway, and
the ability to drop capabilities after connect would just complicate the
EIS implementations unnecessary.