Commit graph

151 commits

Author SHA1 Message Date
Peter Hutterer
273eda39ca Move the C proto templates to the src directory
These are very specific to libei/libeis, so let's not leave them
somewhere where they look like official bindings or something.
2023-03-03 11:21:26 +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
e93ad6925c test: set the minimum bits for our test devices
size is required for phys devices and in the future libei will reject
devices with no useful capabilities.
2023-02-20 15:43:22 +10:00
Peter Hutterer
5db1085e09 test: drop a bunch of unused imports 2023-02-15 08:20:01 +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
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
674a7c6915 meson.build: alphabetical sort of the source files
And drop the header files, meson does not require those for dependency
tracking.
2023-02-13 13:46:00 +10:00
Peter Hutterer
c9b6898afd test: fix pytest loading liboeffis.so
Apparently this test doesn't run in the CI...
2023-02-09 13:04:59 +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
cb46522425 meson.build: move tests to test/meson.build
This requires that we add the top-level directory to includes so the
tests can find the config.h file.
2023-02-09 11:42:11 +10:00
Peter Hutterer
a8961420db test: fix compiler warning about possible loss of precision
Let's make this a float division then to keep the compiler happy
2023-02-07 13:34:29 +10:00
Peter Hutterer
8bdfc8cf18 test: fix a test case's behavior
The default behaviour of a peck context is to handle the CONNECT event.
Let's disable that.

No effect on the test, the client cannot receive the connect event until
it's been accepted, but it's better form anyway.
2023-02-02 15:17:09 +10:00
Peter Hutterer
642e258ecb Format python files with black
And set up a gitlab ci job to check that
2023-02-01 11:48:53 +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
bc78c24290 Fix some logging linebreak issues
One excessive linebreak, another one was missing.
2022-09-07 10:03:11 +10:00
Peter Hutterer
5535692ee0 proto: allow the client to set the protocol version
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".
2022-09-07 09:42:59 +10:00
Peter Hutterer
f7dc4af6e8 log: abstract the auxiliary information into a log message context
This makes the logger API both simpler and more future-proof since we
can easily shove extra information into the context now.
2022-08-11 10:09:34 +10:00
Peter Hutterer
876d722356 log: enforce single logical messages only
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.
2022-08-11 10:08:48 +10:00
Peter Hutterer
b3e4f8fc25 test: add a few tests for reis 2022-08-01 11:50:29 +10:00
Peter Hutterer
daddc355b2 eis: add eis_client_has_capability
The EIS implementation needs to know if a client can use a given
capability. No point setting up touch devices if the client isn't
allowed those.
2022-08-01 11:50:29 +10:00
Peter Hutterer
41a106fafc eis: send out the list of existing properties on connect
Any property that was set by the server or a libreis intermediary before
connect needs to be sent to the client.

Fixes #22
2022-08-01 11:31:59 +10:00
Peter Hutterer
b4efd0fa5f test: set up libreis support in eierpecken
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.
2022-08-01 11:31:59 +10:00
Peter Hutterer
223d65858d test: rename the ei AUTOCONNECT behavior to HANDLE_CONNECT
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.
2022-08-01 11:26:32 +10:00
Peter Hutterer
b4da6738d3 Retrofit event timestamps to all device events based on the frame
As we now buffer device frames we can apply the timestamp of the frame
event to all currently pending events.
2022-05-17 15:31:20 +10:00
Peter Hutterer
48bf74a5b9 Add a pending event queue for incoming device events
Incoming device events are now added to a device-internal queue. Once
the frame event comes in, that queue is shuffled over to the main event
queue. For libei/the EIS implementation this means that device events
are seen only once the frame event appears from the sender (or it is
emulated by other means).
2022-05-17 15:31:20 +10:00
Peter Hutterer
d99e42b808 Add timestamps to frame events
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.
2022-05-17 07:18:41 +10:00
Peter Hutterer
5b82cb4fe8 Flush the frame event before a stop_emulating 2022-05-04 13:42:27 +10:00
Peter Hutterer
425c7804d4 test: ensure we only get frame events after device events
Because we're doing this per dispatch call (rather than a device state)
we need to ensure that the various tests gobble up all pending frame
events - the assert_no_events helpers do this.

If we only check for specific events, a frame event may still be pending
from one interaction. This causing the assertion to fail on the
subsequent dispatch call.
2022-04-29 11:38:25 +10:00
Peter Hutterer
a4dde7c35f Filter empty frame events
We only need frame events after device events (pointer, touch,
keyboard). In some cases, the library prevents an event from being
written to the wire, e.g. if the coordinates are out of region, but the
client will still call ei_device_frame() for that now-filtered event.

Keep a boolean to remember if we have sent something that requires a
frame event and filter accordingly.

Note that this currently filters the *sender* side only, not the
receiver side. A sender that gets an empty frame event onto the wire
will still get that into the other side.

This also doesn't handle the flushing of frame events before other
events, ideally we should enforce a frame event before e.g. stop
emulating.
2022-04-29 11:38:07 +10:00
Peter Hutterer
35aca1a387 Enforce a frame after ei_touch_destroy()
Destroying a touch causes ei_touch_up if the touch is still down. But
for the event sequence to be correct we also need to add a frame event
here, otherwise the touch up may be "pending" on the remote until the
next actual event happens and a frame is added.

A client that doesn't want this should just call ei_touch_up()
2022-04-29 11:38:07 +10:00
Peter Hutterer
ea6a348399 test: add a few missing frame events 2022-04-29 11:38:07 +10:00
Peter Hutterer
e25586a96c test: handle frame events in passive ei contexts by default
This is a copy of the EIS handling of frame events where we largely skip
over them to make the tests more sensible.
2022-04-29 11:37:35 +10:00
Peter Hutterer
9831b4c98b test: use the helper functions to enable the default behaviors
Some of the behaviors we enable trigger others (none that we use here
though), so let's use the helper function to get the same behavior sets
as if we set those in the tests.
2022-04-29 11:16:41 +10:00
Peter Hutterer
ab55d6646b test: make the dispatch looping easier to understand in the debug logs 2022-04-29 11:16:41 +10:00
Jonas Ådahl
1ec6d3dbea eirpecken: Use the new eis_backend_fd_add_client()
This also acts as the test for eis_backend_fd_add_client().

Signed-off-by: Jonas Ådahl <jadahl@gmail.com>
2022-04-27 02:00:07 +00:00
Peter Hutterer
f35be22d2c Rename ei active/passive to sender/receiver
This is more explicit in what it actually does, making it easier to
immediately understand the code.
2022-04-04 15:42:27 +10:00
Peter Hutterer
fa091d7ac4 Differentiate between physical and virtual devices
With passive libei contexts receiving events sent by the EIS
implementation, the type of device changes significantly. While a
relative input device could still send data in logical pixels,
absolute devices may not have that luxury.

Best example here is an external tablet (think: Wacom Intuos): that
tablet has no built-in mapping to a screen and thus cannot capture input
events in logical pixels.

Address this by adding a device type, either virtual or physical.
In terms of functionality, the device's type decides:
- only virtual devices have regions
- only physical devices have a size

The event API remains as-is but the event data not represents either
logical pixels (virtual devices) or mm (physical device).

An EIS implementation connected to a passive libei context would likely
create:
- a virtual relative device (sending deltas in logical pixels)
- one or more physical absolute devices (sending deltas in mm)
2022-04-04 05:28:36 +00:00
Peter Hutterer
9d85b1289d Change to allow dynamic binding of capabilities
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.
2022-04-04 05:24:16 +00:00
Peter Hutterer
7b760e5950 eis: the EIS context does not have a is_active setting
This is a leftover from an earlier implementation that didn't get
removed in time. This extends to a macro that was using the context flag
(rather than the client flag) and in turn caused a bunch of false
positives on the tests.
2022-03-28 16:53:11 +10:00
Peter Hutterer
a5e6af5bff eis: after the client binds the seat, drop the capabilities
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.
2022-03-07 11:21:36 +10:00
Peter Hutterer
541dcb415d ei: require the client to confirm capabilities rather than drop them
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.
2022-03-07 11:02:35 +10:00
Peter Hutterer
8474d03e03 test: add test cases for eis -> ei events
Copy/paste from the normal test-cases, with the appropriate switching of
server vs client and s/eis/ei/
2022-03-04 14:04:33 +10:00
Peter Hutterer
faa9500afe Add concept of active/passive libei contexts
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>
2022-03-04 14:04:33 +10:00
Peter Hutterer
19ae05b33b test: define peck_unrefp in the header file
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2022-03-03 05:41:15 +00:00
Peter Hutterer
b6f477fb96 util-object: split macro to generate unref into one two
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.
2022-03-03 05:41:15 +00:00
Peter Hutterer
cc28d90a82 test: aded a test for key events 2022-03-03 05:41:15 +00:00
Peter Hutterer
81d6fb335d test: add a helper function to mark test progress
Makes debugging easier: just insert a few peck_mark() calls and see
them correctly mixed into the output.
2022-03-03 05:41:15 +00:00
Peter Hutterer
e9e67449d5 test: localize a coordinate set a bit better 2022-03-03 05:41:15 +00:00