Commit graph

261 commits

Author SHA1 Message Date
Peter Hutterer
edc8ea045a eis: don't warn about EPIPE, just debug-log it
While it's not the friendliest way of a client to exit, we do need to
expect clients to disconnect any time and that shouldn't trigger
warnings, it's somewhat expected behavior.

Part-of: <https://gitlab.freedesktop.org/libinput/libei/-/merge_requests/337>
2025-06-16 11:20:21 +10:00
Peter Hutterer
8cd2b01bfa test: expose the ei socket fd to tests
Part-of: <https://gitlab.freedesktop.org/libinput/libei/-/merge_requests/337>
2025-06-16 11:20:21 +10:00
Peter Hutterer
98e445ebdb test: add ability to capture logs
Part-of: <https://gitlab.freedesktop.org/libinput/libei/-/merge_requests/337>
2025-06-16 11:20:21 +10:00
Peter Hutterer
efdc58e094 test: remove an unused function
Obsolete since 479bda259a ("Purge libreis from the repo")

Part-of: <https://gitlab.freedesktop.org/libinput/libei/-/merge_requests/338>
2025-06-13 16:49:03 +10:00
Peter Hutterer
daba46a2ae eis: if a client is slow, queue up messages for future delivery
If a receiver client stops calling ei_dispatch for a while eventually
we fill up the send buffer, causing messages to be quietly dropped.
When the client resumes the message stream resumes with whatever we send
next but that can leave the client in an inconsistent state.

deskflow hit this in the server-side where our event sequence of pointer
motion+frames eventually filled up the buffer, causing
eis_device_stop_emulating() to be silently dropped. On the next
InputCapture sequence eis_device_start_emulating() was sent to an
already emulating client (as seen by the client).

This patch adds a secondary queue, if we fail to send a message with
EAGAIN queue it up and flush that queue whenever the next message is
sent. Meanwhile any newly added messages go straight into that queue.

The caveat here: a nonresponding client will eventually trigger OOM,
there is no upper limit on the messages yet

This is the libeis version of
commit 69e973e6b3 ("ei: queue unsent messages for later delivery if our buffer is full")

Closes: #79
Part-of: <https://gitlab.freedesktop.org/libinput/libei/-/merge_requests/331>
2025-05-02 15:40:47 +10:00
Peter Hutterer
daf0b24665 test: add a test for multiple start/stop emulating events
Part-of: <https://gitlab.freedesktop.org/libinput/libei/-/merge_requests/331>
2025-05-02 15:40:47 +10:00
Eric Long
e147d4311f test: increase protocol-test-valgrind timeout
Currently libei's valgrind test setup has 100x timeout (3000s), but the
standalone protocol-test-valgrind still has 30s timeout, which is not enough
for RISC-V hardware. On Milk-V Pioneer (SG2042) it takes ~70s to complete. In
addition, `kill_gently` sends SIGKILL before the process terminates and fails
the test.

Bump protocol-test-valgrind timeout to 300s and increase timeout between kill
signals to 3s to solve the issue.

Part-of: <https://gitlab.freedesktop.org/libinput/libei/-/merge_requests/329>
2025-04-11 15:32:20 +08:00
Peter Hutterer
76845ecdfe Reformat for ruff 0.9
New formatting rules, apparently.

Part-of: <https://gitlab.freedesktop.org/libinput/libei/-/merge_requests/325>
2025-02-03 13:17:34 +10:00
Peter Hutterer
564f14a739 ei: add EI_EVENT_SYNC as opaque event to correctly schedule callbacks
See the corresponding eis commit for details.

Part-of: <https://gitlab.freedesktop.org/libinput/libei/-/merge_requests/316>
2024-12-18 04:30:01 +00:00
Peter Hutterer
73e0e8d339 eis: add EI_EVENT_SYNC as opaque event to correctly schedule callbacks
This event is required to fix an issue with the current
ei_callback.done handling in libeis: previously we would imediately send
the ei_callback.done upon receiving ei_connection.sync from the client.
This results in incorrect behavior as we may have events in the queue
(and/or pending a frame) that the EIS implementation hasn't seen yet.
For example a client sending:
- ei_pointer.motion
- ei_connection.sync
- ei_device.frame
- ei_connection.sync

Will queue a motion + frame event on the EIS side during eis_dispatch()
but immediately receive done events for both sync requests.

This could be handled purely internally by keeping the sync event in the
queue but hidden to the caller - and automatically calling done when
it's that events turn, i.e. something like:

```
  struct eis_event *eis_get_event(struct eis) {
      struct eis_event *e = first_event(eis);
      if (e == EIS_EVENT_SYNC) {
           eis_callback_send_done(e);
           eis_event_unref(e);
           e = next_event(eis);
      }
      return e;
  }
```

but that opens us up to a set of potential bugs detailed in
https://gitlab.freedesktop.org/libinput/libei/-/issues/71#note_2694603

So let's go the easy route by having a new event type that does nothing
other than eis_event_unref() in the EIS implementation. This way we can
queue the event and have everything behave in-order and as expected.

Closes #71

Part-of: <https://gitlab.freedesktop.org/libinput/libei/-/merge_requests/316>
2024-12-18 04:30:01 +00:00
Peter Hutterer
971013429d test: add a test for sync events during frames
Part-of: <https://gitlab.freedesktop.org/libinput/libei/-/merge_requests/316>
2024-12-18 04:30:01 +00:00
Peter Hutterer
e40796402b eis: add eis_ping() and the matching EIS_EVENT_PONG
Identical to "ei: add ei_ping() and the matching EI_EVENT_PONG" but for
libeis.

This wraps around ei_connection.ping to allow a C API user to add
synchronization points.

Closes #69

Part-of: <https://gitlab.freedesktop.org/libinput/libei/-/merge_requests/316>
2024-12-18 04:30:01 +00:00
Peter Hutterer
a278c7b371 ei: add ei_ping() and the matching EI_EVENT_PONG
This wraps around ei_connection.sync to allow a C API user to add
synchronization points.

Closes #69

Part-of: <https://gitlab.freedesktop.org/libinput/libei/-/merge_requests/316>
2024-12-18 04:30:01 +00:00
Peter Hutterer
b1c1c5d579 Add the ei_touchscreen.cancel event and ei_touch_cancel()
In the protocol it's a new request/event that is sent instead of the
touch up event.

In the library this is implemented as ei_touch_cancel() which
transparently sends cancel() or up depending on the EIS implementation
support. This is mirrored for the EIS implementation.

Where touch cancel is received as an event it is presented
as EI_EVENT_TOUCH_UP with an ei_event_touch_is_cancel() flag to
check if it was a cancel. This is required for backwards compatbility,
we cannot replace the TOUCH_UP event with a TOUCH_CANCEL event without
breaking existing callers. To add a new event type we would need clients
announcing support for those event types but that's an effort that's
better postponed until we have a stronger need for it (see #68).

Closes #60

Part-of: <https://gitlab.freedesktop.org/libinput/libei/-/merge_requests/308>
2024-12-17 15:12:56 +10:00
Peter Hutterer
d4b60a7d0d test: rename a variable to shut up ruff with default args
We disable that warning in the CI and pre-commit but it's a simple
fix here that makes sense.

        test/test_oeffis.py:185:9: E741 Ambiguous variable name: `l`

Part-of: <https://gitlab.freedesktop.org/libinput/libei/-/merge_requests/319>
2024-12-10 05:06:49 +00:00
Peter Hutterer
504afdea4a test: drop the use of attr
All our uses can be done with dataclasses so we don't need an external
package.

Part-of: <https://gitlab.freedesktop.org/libinput/libei/-/merge_requests/319>
2024-12-10 05:06:49 +00:00
Peter Hutterer
9ee33b019f test: fix a spuriously failing timeout
When running repeated tests in parallel, this one eventually fails
because the ei.send() doesn't trigger the expected BrokenPipeError.
Use ei.dispatch() instaed and check whether the connection still exists.

Part-of: <https://gitlab.freedesktop.org/libinput/libei/-/merge_requests/317>
2024-12-06 16:48:48 +10:00
Peter Hutterer
60bc264e75 test: ignore a failure to send a pong
Our automatic pong handler unconditionally sends a Pong back to the EIS
implementation. For some tests and depending on timing we may have
been disconnected already, resulting in a BrokenPipeError that fails
us the test. Ignore that error.

Part-of: <https://gitlab.freedesktop.org/libinput/libei/-/merge_requests/317>
2024-12-06 16:48:48 +10:00
Peter Hutterer
96f20ae333 test: ignore a ConnectionResetError during our dispatch
If our server disconnects us with data still in the pipe we never picked
up on that data causing heisenbugs depending on whether we read things
(esp. the "disconnected" event) fast enough or not.

Part-of: <https://gitlab.freedesktop.org/libinput/libei/-/merge_requests/317>
2024-12-06 16:48:48 +10:00
Peter Hutterer
7619bfa9ad test: switch a bool([...]) to any()
Part-of: <https://gitlab.freedesktop.org/libinput/libei/-/merge_requests/317>
2024-12-06 16:48:48 +10:00
Peter Hutterer
c169ac63b8 test: keep the announced interface as local variable
This will be more prominent as we add new interface versions and hooking
it up via the right signals is better than analyzing the calllog.

Part-of: <https://gitlab.freedesktop.org/libinput/libei/-/merge_requests/317>
2024-12-06 16:48:48 +10:00
Peter Hutterer
62ae6f5edf ei: make ei_disconnect() public
Previously the only way to disconnect from the EIS implementation was
to call ei_unref() and release all resources. This makes it more
difficult for shared cleanup code - clients already have code in place
to deal with DEVICE_REMOVED, SEAT_REMOVED, etc. but that code has to
be triggered manually before ei_unref() is called.

OTOH where the server disconnects us, libei already unwound the state
so we would artificially generate these removed events, allowing the
client to clean up.

Make life easier for client by allowing them to ei_disconnect() and
get the benefits of our state unwinding. ei_disconnect() was already
used internally to disconnect on any error so this merely makes this
function public.

Closes #67

Part-of: <https://gitlab.freedesktop.org/libinput/libei/-/merge_requests/311>
2024-12-05 02:44:56 +00:00
Peter Hutterer
327dd4f8b1 test: fix string encoding in the python test bindings
The protocol encoding is the string including the null byte. The test
wrappers sent the right string length but only encoded strlen() bytes so
where we had a string that's a multiple of 4 long we ended up claiming
it's a byte longer than was on the wire.

Part-of: <https://gitlab.freedesktop.org/libinput/libei/-/merge_requests/314>
2024-12-03 13:18:54 +10:00
Peter Hutterer
247b6acd3c meson.build: allow disabling libei and libeis
This is primarily a development feature because it makes it easier to
develop a new feature for just one library without having to worry
about build errors in the other library (e.g. when new protocol parts
are added).

Part-of: <https://gitlab.freedesktop.org/libinput/libei/-/merge_requests/310>
2024-12-02 00:23:14 +00:00
Peter Hutterer
b3a4243924 test: make the c++ build test mirror the c build test
Part-of: <https://gitlab.freedesktop.org/libinput/libei/-/merge_requests/310>
2024-12-02 00:23:14 +00:00
Peter Hutterer
a491580fc0 test: improve debugging for failed event type comparisons 2024-11-27 02:13:53 +00:00
Peter Hutterer
37ea216424 test: print the line no for peck_ei(s)_assert_no_events 2024-11-27 02:13:53 +00:00
Peter Hutterer
0770fec433 Drop black, switch to ruff format 2024-10-17 16:18:51 +10:00
Peter Hutterer
9f82bbf344 test: add tests for multiple regions
Adds the test for
commit 0f81114544 ("Fix region check for devices with multiple regions")
2024-08-07 10:51:12 +10:00
Peter Hutterer
6ea468c823 util/memfile: use MAP_SHARED to create the map
Using MAP_PRIVATE means copy-on-write so our data written into the map
immediately disappears again. This leads to a empty string when sending
a keymap to a client.
2024-07-29 14:48:34 +10:00
Peter Hutterer
eb1d5a7e1a test: drop a custom cleanup func in favor of _unref_ 2024-07-29 14:32:40 +10:00
Peter Hutterer
da1fa204d5 meson.build: bump the meson version by one
This allows us to drop one version check
2024-07-24 12:29:48 +10:00
Matt Turner
33b4a61995 test: Raise SIGALRM interval to 50µs
On some platforms, an interval of 5µs is short enough that the test
spends its time almost exclusively processing SIGALRMs and never
progresses otherwise. Raising the interval to 50µs allows the test to
pass in a fraction of a second.

Bug: https://bugs.gentoo.org/916777
Closes: https://gitlab.freedesktop.org/libinput/libei/-/issues/50
2024-04-08 12:21:09 -04:00
Peter Hutterer
d29778658a oeffis: OEFFIS_DEVICE_ALL_DEVICES should translate to "all"
As the portal documentation [1] says:
  Bitmask of what device types to request remote controlling of. Default is all.

The default is only triggered if we do not submit the types at all, the
current behavior of sending a value of 0 means "none". Fix this by
skipping the "types" key if we try to select for all devices.

[1] https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.impl.portal.RemoteDesktop.html
2023-12-14 00:58:18 +00:00
Peter Hutterer
6ce695db3b test: yield the proxy, not the subprocess for the liboeffis fixtures
There's virtually no use for the process, so let's yield the proxy
object instead because we can make use of that.
2023-12-14 00:58:18 +00:00
Peter Hutterer
924341e174 ei: keep a cache of defunct objects to avoid spamming the log
Because of the asynchronous protocol, we may get this interaction

   server sends A->destroyed()
       client sends A->foo()
       client receives A->destroyed()
   server receives A->foo()
   server sends invalid_object_id(A)
       client receives invalid_object_id(A)

Previously we dropped the object after destroyed() and were thus
guaranteed to warn about the invalid object id for that same object
later.

Fix this by keeping a cache of defunct object IDs that we know about and
ignoring errors for recently dropped objects.

Every 20 ei_dispatch() calls we drop any defunct objects that were
unregistered more than 5 seconds ago.

Fixes #49
2023-11-09 12:47:06 +10:00
Peter Hutterer
4e634aa76c test: add the ability to add offsets to ei_now()
Build a separate libei-eierpecken.so that is identical to libei.so but
allows adding an offset to ei_now() for the eierpecken tests. That
offset is added to the return value of ei_now(), removing the real-time
dependency of the tests.

In other words, we can call peck_ei_add_time_offset(peck, s2us(5)) to
add 5 seconds to the time and continue the test as if that time has
elapsed.
2023-11-09 12:47:06 +10:00
Peter Hutterer
7999483a34 test: make bug logs fatal by default
We don't want to paper over bugs in the implementation, so let's make
any ei/eis error message with a bug in it fatal by default.

This needs to be disabled where we test for known-buggy client/EIS
behavior.
2023-11-09 10:15:38 +10:00
Peter Hutterer
fae41aac08 test: hack a peck_debug() function
To make it easier to print something debuggy from a test.

This is the MVP, it always requires an argument after the format string
but it'll do for now.
2023-11-08 23:24:45 +00:00
Peter Hutterer
44e7f2cbc4 test: fix a test missing frame events 2023-11-08 23:24:45 +00:00
Peter Hutterer
35832d9fe1 test: make peck_dispatch_until_stable() print more useful debug info 2023-11-08 23:24:45 +00:00
Peter Hutterer
f9c83ed9a6 test: expand log messages to accommodate for 4-digit line numbers 2023-11-08 23:24:45 +00:00
Peter Hutterer
05d79f6e58 test: set up a timer to trigger SIGALRM
Xwayland uses a timer for the scheduler which means any of our syscalls
can trigger EINTR. Let's make sure we may catch bugs related to that by
setting up our test suite to hammer us with timers.

Can't guarantee this will trigger all bugs but over time it may help or
at least ensure that the low-hanging fruit are all fixed.
2023-10-24 18:25:25 +10:00
Peter Hutterer
69e973e6b3 ei: queue unsent messages for later delivery if our buffer is full
If our write buffer is full, enqueue the events instead and try to flush
them out later when we can write again.

Fixes #46
2023-10-11 00:41:13 +00:00
Peter Hutterer
f235052f81 test: ensure munit debug messages are visible on failure 2023-08-31 12:41:13 +10:00
Peter Hutterer
7115e9c4c8 test: rework the oeffis dbus tests to be pytest-compatible
DBusMock is unittest based and the documentation points users to that
approach. That approach is limiting however because we can't use all
pytest features (see [1]). Luckily, the parent class in dbusmock doesn't
really do much so we can emulate the functionality ourselves - all we
need to do is call the same setUp/tearDowns and be done with it.

This means we can move the dbus-monitor and mainloop handling into
fixtures too which makes the code a fair bit nicer to read.

[1] https://docs.pytest.org/en/7.1.x/how-to/unittest.html#pytest-features-in-unittest-testcase-subclasses
2023-08-30 09:46:36 +10:00
Peter Hutterer
76652350cc Add a mapping_id to the regions
This allows a caller to match up a region with other data, e.g. in the
remote desktop case the same mapping_id can be assigned to the pipewire
stream that represents that output.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2023-08-30 09:18:26 +10:00
Peter Hutterer
7ddd70e9d8 Add ei_device_get_region_at() to obtain a region for a point
Helper function so clients don't need to loop through the regions to
find the matching one.
2023-08-29 11:39:20 +10:00
Peter Hutterer
39e6c93c8b test: ensure all returned interface versions are 1
Even where our client pretends to have higher interface versions, we
always send back version 1 from the EIS implementation.

This test probably won't really trigger anything useful until we switch to
version 2 somewhere, so let's hope the code works...
2023-06-07 23:08:16 +00:00
Peter Hutterer
97a5538258 test: add test for correct ei_device_close behavior 2023-06-07 23:08:16 +00:00