Commit graph

125 commits

Author SHA1 Message Date
Peter Hutterer
1f9be0fd0a Add a new text interface for sending keysyms and utf8 text
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

Part-of: <https://gitlab.freedesktop.org/libinput/libei/-/merge_requests/355>
2026-04-02 05:09:37 +00:00
Peter Hutterer
c5494e9b1e Fix varius typos across the codebase
Co-Authored-by: Claude Code <noreply@anthropic.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libei/-/merge_requests/385>
2026-03-23 12:37:45 +10:00
Peter Hutterer
a6028a7b87 Format the code with clang-format
clang-format taken from libinput, except for
  ColumnLimit: 100
and some macro definitions (which don't all have an effect anyway...)

It's not perfect but good enough and at least consistent.

Part-of: <https://gitlab.freedesktop.org/libinput/libei/-/merge_requests/383>
2026-03-12 13:55:19 +10:00
Peter Hutterer
65c0b39c3e ei: match the EI_EVENT_DEVICE_PAUSED docs with the protocol
This is a behavior break if we're looking at the documentation only but
the protocol has required the logical reset of the device since libei
0.5 - this here is just stale documentation that didn't get updated.

And keeping the state across paused/resume is too hard to get right
anyway.

Part-of: <https://gitlab.freedesktop.org/libinput/libei/-/merge_requests/368>
2026-01-07 22:23:41 +00:00
Peter Hutterer
5f9e181073 proto: add support for requesting devices
Add support for a client to request the creation of a new device
from the EIS implementation. This is necessary in situations where the
devices created by the EIS implementation are not (or no longer)
suitable for the client to function correctly.

The primary use-case of this is the upcoming tablet tool support where a
client may need to create multiple tablet tools in response to a new
physical tool brought into proximity locally.

Other use-cases include a client closing a device but requiring that
device (or one with similar capabilities) later.

The implementation in libei is straightforward
- on the client side we have a new function to request the new device:
  ei_seat_request_device_with_capabilities()
- on the server side we have a new event EIS_EVENT_SEAT_DEVICE_REQUESTED
  that can make use of the existing eis_event_seat_has_capability() API

Part-of: <https://gitlab.freedesktop.org/libinput/libei/-/merge_requests/345>
2026-01-06 04:50:46 +00:00
Jonas Ådahl
5e57b1ed5f ei: Expose ei_event_ref()
As with eis, expose ei_event_ref() as well, for consistency.

Part-of: <https://gitlab.freedesktop.org/libinput/libei/-/merge_requests/340>
2025-08-21 17:08:53 +02:00
Peter Hutterer
55335b9030 libei: fix the docs for the various _unref functions
Copy/paste from ei_unref but none of the others will disconnect the
context.

Part-of: <https://gitlab.freedesktop.org/libinput/libei/-/merge_requests/349>
2025-07-24 00:54:06 +00:00
Jason Gerecke
6aa4dc0c7e doc: Correct spelling errors in the code documentation
Part-of: <https://gitlab.freedesktop.org/libinput/libei/-/merge_requests/343>
2025-07-02 14:03:34 -07:00
Erik Jensen
1152c038ee Specify MODIFIERS to be sent for any state change.
Updates protocol and API documentation to specify that the modifiers
event should be sent by the EIS implementation every time the modifier
or group state changes, including when the change is triggered by key
events on the emulated keyboard.

The previous approach of expecting the client to track modifier state
using xkb_state_update_key() for injected keys resulted in multiple
opportunities for the client and server to get out of sync (both due to
unavoidable race conditions and due the client not having access to the
complete state used by the server to calculate state changes), with no
way for the client to ensure it had a correct modifier map short of
unbinding and rebinding the seat.

The new approach allows the client to track state solely by applying
modifiers events with xkb_state_update_mask(), simplifying client
implementation. Because the event is sent for all changes, the client
can use ei_connection.sync / ei_ping() to ensure that it has received
the latest state incorporating all key requests sent prior to the sync
request (along with any externally-caused modifier state changes that
may have occured up to the time the sync message was received).

Part-of: <https://gitlab.freedesktop.org/libinput/libei/-/merge_requests/318>
2024-12-18 04:41:11 +00: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
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
91e0b8961b doc: specifically mention that unknown events must be unref'd
And document the event type enums as non-exhaustive.

Part-of: <https://gitlab.freedesktop.org/libinput/libei/-/merge_requests/322>
2024-12-17 16:00:59 +10:00
Peter Hutterer
9c35a57cfe doc: fix some linewrapping issues
Part-of: <https://gitlab.freedesktop.org/libinput/libei/-/merge_requests/322>
2024-12-17 15:59:02 +10: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
561cfd009e doc: unwinding state before stop_emulating is the caller's responsibility
Part-of: <https://gitlab.freedesktop.org/libinput/libei/-/merge_requests/308>
2024-12-11 10:09:34 +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
1f0cc83548 ei: declare struct ei_touch
Part-of: <https://gitlab.freedesktop.org/libinput/libei/-/merge_requests/313>
2024-12-02 10:28:19 +10:00
Peter Hutterer
37cc857a52 doc: demote the socket backend in the documentation
The socket backend is useful for debugging and testing but not for real
user-cases where the fd negotiation should be handled by the caller
(e.g. passing it down through the portal). Let's demote the socket
backend in favour of the fd backend.

Related https://gitlab.freedesktop.org/libinput/libei/-/issues/63
2024-09-03 04:00:33 +00: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
Jason Gerecke
0820e29bd5 Correct documentation for ei_touch_(get|set)_user_data 2023-09-06 21:16:08 +00: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
4096d100ee ei: more docs that data is in pixels or mm
This depends on the device type and was-already documented in some
functions but not others.
2023-06-06 10:54:48 +10:00
Peter Hutterer
35ec414215 Remove unimplemented ei_device_get_keymap()
This is ei_device_keyboard_get_keymap() instead
2023-05-30 19:11:44 +10:00
Peter Hutterer
708aed6402 Export the event names through helper functions
Approximately every user of libei(s) will want something like this for
easier debugging, converting the numeric event type into something that
can be printed into the debug logs.

Let's provide this here so this doesn't need to be duplicated.
2023-05-22 02:39:08 +00:00
Peter Hutterer
3e47f544c2 ei: drop ei_seat_bind_capability() and the unbind equivalent
This function is almost always wrong, very few clients will want to bind
to a single capability. Having this function means clients will use it to
bind caps one-by-one, causing the EIS implementation to create (an later
destroy) devices with capabilities that are about to be bound again anyway.
Better to have an API that encourages clients to bind all at once.

EIS implementation could avoid this by using a pingpong roundtrip in
response to a bind call, but removing this API is likely going to have
the same utility.
2023-05-10 12:25:40 +10:00
Peter Hutterer
333e98a191 doc/api: add some more high-level overview to the libei page 2023-05-10 11:36:51 +10:00
Peter Hutterer
8302b1ddac doc/api: add the unicode icons for a splash of color
Sometimes it's good to focus on the important issues in life.
2023-05-10 11:36:51 +10:00
Peter Hutterer
c076c48336 doc: split the libei doxygen API into multiple submodules
The API is quite long now, so let's split it up into multiple logical
groups. The main page is now roughly graspable, with seats, devices,
regions and keymaps in submodules.

The sender and receiver APIs are also grouped into two separate APIs -
anyone implementing either doesn't need the other, it just messes things
up.
2023-05-05 14:05:30 +10:00
Peter Hutterer
5bb6e80ded doc: some minor doxygen updates 2023-05-05 14:05:30 +10:00
Peter Hutterer
aa866c5a92 Add a few more doxygen comments 2023-05-05 14:05:30 +10:00
Peter Hutterer
da37da1308 ei: change the API to match the protocol interfaces closer
Now that the protocol interfaces are more fine-grained, let's match this
with the C API too.

This is just a rename of things so that in general
ei_pointer_*foo now becomes ei_foo*.

A few notable renames for better readability here:
- ei_device_scroll_delta (because scroll_scroll is awkward)
- ei_event_scroll_get_dx/dy and
  ei_event_scroll_get_discrete_dx/dy to indicate the delta-ness

Beyond that, clients must ensure to check/bind to the new
EI_DEVICE_CAP_BUTTON and EI_DEVICE_CAP_SCROLL capabilities to be able
to send button or scroll events.

Note that this API now allows for an EIS implementation to send a device
that only has a button or a scroll cap. Or a pointer cap without
buttons, etc. It's up to the clients how to handle such devices
(probably: ignore them).
2023-05-05 14:02:33 +10:00
Peter Hutterer
d21726965b doc: move the sentinel attribute to unconfuse doxygen
The compiler doesn't care, doxygen apprently does.
2023-04-27 14:42:25 +10:00
Peter Hutterer
97a7a3e360 doc: fix two obsolete API comments 2023-04-27 14:42:22 +10:00
Peter Hutterer
8ea6b81f40 Change the ei_device_capability values to match the protocol
In the protocol this is a bitmask, let's make it the same in the
interface to avoid confusion in the implementation.
2023-03-03 11:27:01 +10:00
Peter Hutterer
866a754223 ei: implement ei_device_get_width/height 2023-02-20 15:42:56 +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
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
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
Peter Hutterer
06469e737b doc: fix two references to function calls 2022-11-29 15:25:07 +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
9e7016e1fe Add a comment that reserved properties cannot be set by the API 2022-07-26 13:16:41 +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
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
8cff3cfd10 Remove an outdated comment
We must support virtual devices on receiver contexts - that's the only
way to handle relative pointer devices that move in pixel(-ish) units.
2022-05-09 17:46:40 +10:00
Jonas Ådahl
05438a17df libei: Clarify whether a context owns a passed fd
Signed-off-by: Jonas Ådahl <jadahl@gmail.com>
2022-04-21 23:39:22 +02: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