The text capability allows for two types of events on that interface:
- XKB keysym events, e.g. XK_ssharp (0x00df) with a press/release state
- UTF8 strings
Keysym events are useful for scenarious where the hardware keycode is
unsuitable due to potentially different key mappings on the client and
server side and/or the client just not wanting to worry about those
mappings. For example a client may want to send Ctrl+C instead of
what effectively is now keycodes for what may or may not be a C key.
UTF8 strings take this a step further and provide a full string (with
implementation-defined size limits to avoid OOM). Unlike e.g. the
wayland text input protocols the assumption is here that the
interaction required to generate that string has already been
performed before the final string is sent over the wire.
Closes#73
The protocol currently supports a ei_device.done event to notify
the ei client that the initial description of the device is complete.
For some future use-cases the client may need to futher negotiate
properties of the device. For example for tablet tools the client may
narrow down capabilities of the tool.
The sequence with the new request is thus e.g.
-> ei_seat.device
-> ei_device.name
-> ei_device.interface
-> ei_device.interface
-> ei_device.done
<- ei_device.ready
-> ei_device.resumed
In libei the request is sent automatically on unref of
the DEVICE_ADDED event. This makes clients immediately compatible
and for the typical (future) use-case of device configuration. Said
configuration will likely be handled in response to the DEVICE_ADDED
event anyway.
In libeis, a new EIS_EVENT_DEVICE_READY event that is sent when the client
sends that same event on the protocol, informing the EIS implementation
that this device is ready. For clients that do not support that version
the event is emulated immediately after sending ei_device.done.
This requires a flag bit to be long-term maintainable. The typical
EIS implementation currently calls eis_device_add() immediately
followed by eis_device_resume(). This doesn't leave any room to
wait for the client's ei_device.ready request.
One backwards-compatible solution could be to buffer the
eis_device_resume() until the ei_device.ready has been received but this
is fraught with hairy corner cases, e.g. if the client is a receiver
context we would also have to buffer all events immediately sent to the
client.
So instead, we have a flag in the context and if set by the caller, we
change the internal behavior to match ei_device interface version 3.
Part-of: <https://gitlab.freedesktop.org/libinput/libei/-/merge_requests/346>
The peck_disable_eis_behavior and peck_disable_ei_behavior functions
would incorectly *enable* behaviors when called with certain arguments
that cover multiple behaviors (e.g. PECK_EIS_BEHAVIOR_ACCEPT_ALL).
This commit modifies the logic to instead disable the behaviors.
Part-of: <https://gitlab.freedesktop.org/libinput/libei/-/merge_requests/359>
Historically the preference for testing was to enable a bunch of
specific behaviors and then leave that as-is for the test. This can be
painful for some events, in particular sync/ping that are used
internally by libei's implementation.
Testing those events requires us to match the implementation-defined
internal setup which is a pain. Much easier to add a function
to allow disabling a specific behavior at some point during the test
Part-of: <https://gitlab.freedesktop.org/libinput/libei/-/merge_requests/340>
This test was checking for the capabilities for `EI_SCROLL` and
`EI_BUTTON`, but not advertising those interfaces initially. Presumably
this was unintentional, given there's no comment that it's intentionally
advertising some protocols but not others.
Also, should the test have failed to find the capabilities when it
didn't advertise the protocol to to start with? This change just fixes
the test, anyway.
This was causing the test to fail for `reis` CI in a proposed change in
https://github.com/ids1024/reis/pull/11.
Part-of: <https://gitlab.freedesktop.org/libinput/libei/-/merge_requests/352>
This makes peck_new_context() take variable arguments in the style
key, v1, v2... where each value is defined by the free-form key.
What we need right now is the mode of the context, so let's add that.
In the future we will add more configurable bits here.
Part-of: <https://gitlab.freedesktop.org/libinput/libei/-/merge_requests/351>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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.
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
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
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.