libei: 🥚 EI - The client API

libei 1.3.0 A library for Emulated Input

Topics | Data Structures | Typedefs | Enumerations | Functions
🥚 EI - The client API

## Topics
| The logging API
| API for receiver clients
| API for sender clients
| The seat API
| The device API
| The region API
| The keymap API

## Data Structures
struct | ei
| The main context to interact with libei. More...
struct | ei_device
| A single device to generate input events from. More...
struct | ei_seat
| A logical seat for a group of devices. More...
struct | ei_event
| An event received from the EIS implementation. More...
struct | ei_keymap
| An keymap for a device with the EI_DEVICE_CAP_KEYBOARD capability. More...
struct | ei_region
| A rectangular region, defined by an x/y offset and a width and a height. More...

## Typedefs
typedef uint64_t(* | ei_clock_now_func) (struct ei *ei)
| Optional override function for ei_now().

## Enumerations
enum | ei_device_type { EI_DEVICE_TYPE_VIRTUAL , EI_DEVICE_TYPE_PHYSICAL }
| The device type determines what the device represents. More...
enum | ei_device_capability { EI_DEVICE_CAP_POINTER , EI_DEVICE_CAP_POINTER_ABSOLUTE , EI_DEVICE_CAP_KEYBOARD , EI_DEVICE_CAP_TOUCH , EI_DEVICE_CAP_SCROLL , EI_DEVICE_CAP_BUTTON }
| The set of supported capabilities. More...
enum | ei_keymap_type { EI_KEYMAP_TYPE_XKB }
| The set of supported keymap types for a struct ei_keymap. More...
enum | ei_event_type { EI_EVENT_CONNECT , EI_EVENT_DISCONNECT , EI_EVENT_SEAT_ADDED , EI_EVENT_SEAT_REMOVED , EI_EVENT_DEVICE_ADDED , EI_EVENT_DEVICE_REMOVED , EI_EVENT_DEVICE_PAUSED , EI_EVENT_DEVICE_RESUMED , EI_EVENT_KEYBOARD_MODIFIERS , EI_EVENT_FRAME , EI_EVENT_DEVICE_START_EMULATING , EI_EVENT_DEVICE_STOP_EMULATING , EI_EVENT_POINTER_MOTION , EI_EVENT_POINTER_MOTION_ABSOLUTE , EI_EVENT_BUTTON_BUTTON , EI_EVENT_SCROLL_DELTA , EI_EVENT_SCROLL_STOP , EI_EVENT_SCROLL_CANCEL , EI_EVENT_SCROLL_DISCRETE , EI_EVENT_KEYBOARD_KEY , EI_EVENT_TOUCH_DOWN , EI_EVENT_TOUCH_UP , EI_EVENT_TOUCH_MOTION }

## Functions
const char * | ei_event_type_to_string (enum ei_event_type)
| This is a debugging helper to return a string of the name of the event type, or NULL if the event type is invalid.
struct ei * | ei_new (void *user_data)
| This is an alias for ei_new_sender.
struct ei * | ei_new_sender (void *user_data)
| Create a new sender ei context.
struct ei * | ei_new_receiver (void *user_data)
| Create a new receiver ei context.
struct ei * | ei_ref (struct ei *ei)
| Increase the refcount of this struct by one.
struct ei * | ei_unref (struct ei *ei)
| Decrease the refcount of this struct by one.
void | ei_set_user_data (struct ei *ei, void *user_data)
| Set a custom data pointer for this context.
void * | ei_get_user_data (struct ei *ei)
| Return the custom data pointer for this context.
bool | ei_is_sender (struct ei *ei)
| Returns true if the context is was created with ei_new_sender() or false otherwise.
void | ei_clock_set_now_func (struct ei *, ei_clock_now_func func)
| Override the function that returns the current time ei_now().
void | ei_configure_name (struct ei *ei, const char *name)
| Set the name for this client.
int | ei_setup_backend_socket (struct ei *ei, const char *socketpath)
| Set this ei context to use the socket backend.
int | ei_setup_backend_fd (struct ei *ei, int fd)
| Initialize the ei context on the given socket.
int | ei_get_fd (struct ei *ei)
| libei keeps a single file descriptor for all events.
void | ei_dispatch (struct ei *ei)
| Main event dispatching function.
struct ei_event * | ei_get_event (struct ei *ei)
| Return the next event from the event queue, removing it from the queue.
struct ei_event * | ei_peek_event (struct ei *ei)
| Returns the next event in the internal event queue (or `NULL`) without removing that event from the queue; the next call to ei_get_event() will return that same event.
uint64_t | ei_now (struct ei *ei)
struct ei_event * | ei_event_unref (struct ei_event *event)
| Release resources associated with this event.
enum ei_event_type | ei_event_get_type (struct ei_event *event)
struct ei_device * | ei_event_get_device (struct ei_event *event)
| Return the device from this event.
uint64_t | ei_event_get_time (struct ei_event *event)
| Return the time for the event of type EI_EVENT_FRAME in microseconds.
struct ei_seat * | ei_event_get_seat (struct ei_event *event)
| Return the seat from this event.

## Detailed Description

libei is the client-side module. This API should be used by processes that need to emulate devices or capture logical events from existing devices.

For an example client see the `tools/` directory in the libei repository. At its core, a libei client will

- create a context with ei_new_sender() or ei_new_receiver()
- set up a backend with ei_setup_backend_fd() or ei_setup_backend_socket()
- register the ei_get_fd() with its own event loop
- call ei_dispatch() whenever the fd triggers
- call ei_get_event() and process incoming events

Those events are typically a sequence of

- EI_EVENT_CONNECT - notification that the client was connected
- EI_EVENT_SEAT_ADDED - notification that a ei_seat is available. The client should respond with ei_seat_bind_capabilities()
- EI_EVENT_DEVICE_ADDED - notification that a ei_device is available in a seat.
- EI_EVENT_DEVICE_RESUMED - notification that the ei_device is ready to emulate events. The client should respond with ei_device_start_emulating() and the required events to emulate input

libei clients come in sender and receiver modes, depending on whether the client sends or receives events from the EIS implementation. See API for sender clients and API for receiver clients for API calls specific to either mode.

Note
  A libei context is restricted to either sender or receiver mode, not both. The EIS implementation however may accept both sender and receiver clients, and will work as corresponding receiver or sender for this client. It is up to the implementation to disconnect clients that it does not want to allow. See eis_client_is_sender() for details.

## Typedef Documentation

## ◆ ei_clock_now_func

typedef uint64_t(* ei_clock_now_func) (struct ei *ei)

Optional override function for ei_now().

By default ei_now() returns the current timestamp in CLOCK_MONOTONIC. This may be overridden by a caller to provide a different timestamp.

There is rarely a need to override this function. It exists for the libei-internal test suite.

## Enumeration Type Documentation

## ◆ ei_device_capability

enum ei_device_capability

The set of supported capabilities.

A device may have zero or more capabilities, a device with perceived zero capabilities is typically a device with capabilities unsupported by the client - such a device should be closed immediately by the client.

The EIS implementation decides which capabilities may exist on a seat and which capabilities exist on any individual seat. However, a device may only have capabilities the client has bound to, see ei_seat_bind_capabilities().

For example, a client may bind to a seat with the pointer and keyboard capability but a given device only has the pointer capability. Keyboard events sent through that device will be treated as client bug.

If a client calls ei_seat_unbind_capabilities() for a capability, the EIS implementation may remove any or all devices that have that capability.

See ei_device_has_capability().

Enumerator
EI_DEVICE_CAP_POINTER | The device can send relative motion events.
EI_DEVICE_CAP_POINTER_ABSOLUTE | The device can send absolute motion events.
EI_DEVICE_CAP_KEYBOARD | The device can send keyboard events.
EI_DEVICE_CAP_TOUCH | The device can send touch events.
EI_DEVICE_CAP_SCROLL | The device can send scroll events.
EI_DEVICE_CAP_BUTTON | The device can send button events.

## ◆ ei_device_type

enum ei_device_type

The device type determines what the device represents.

If the device type is EI_DEVICE_TYPE_VIRTUAL, the device is a virtual device representing input as applied on the EIS implementation's screen. A relative virtual device generates input events in logical pixels, an absolute virtual device generates input events in logical pixels on one of the device's regions. Virtual devices do not have a size.

If the device type is EI_DEVICE_TYPE_PHYSICAL, the device is a representation of a physical device as if connected to the EIS implementation's host computer. A relative physical device generates input events in mm, an absolute physical device generates input events in mm within the device's specified physical size. Physical devices do not have regions.

See also
  ei_device_get_width
  ei_device_get_height

Enumerator
EI_DEVICE_TYPE_VIRTUAL |
EI_DEVICE_TYPE_PHYSICAL |

## ◆ ei_event_type

enum ei_event_type

Enumerator
EI_EVENT_CONNECT | The server has approved the connection to this client. Where the server does not approve the connection, EI_EVENT_DISCONNECT is sent instead. This event is only sent once after the initial connection request.
EI_EVENT_DISCONNECT | The server has disconnected this client - all resources left to reference this server are now obsolete. Once this event has been received, the struct ei and all its associated resources should be released. This event may occur at any time after the connection has been made and is the last event to be received by this ei instance. libei guarantees that a EI_EVENT_DISCONNECT is provided to the caller even where the server does not send one.
EI_EVENT_SEAT_ADDED | The server has added a seat available to this client. libei guarantees that any seat added has a corresponding EI_EVENT_SEAT_REMOVED event before EI_EVENT_DISCONNECT. libei guarantees that any device in this seat generates a EI_EVENT_DEVICE_REMOVED event before the EI_EVENT_SEAT_REMOVED event.
EI_EVENT_SEAT_REMOVED | The server has removed a seat previously available to this client. The caller should release the struct ei_seat and all its associated resources. No devices will be added to this seat anymore. libei guarantees that any device in this seat generates a EI_EVENT_DEVICE_REMOVED event before the EI_EVENT_SEAT_REMOVED event.
EI_EVENT_DEVICE_ADDED | The server has added a device for this client. The capabilities of the device may be a subset of the seat capabilities - it is up to the client to verify the minimum required capabilities are indeed set. libei guarantees that any device added has a corresponding EI_EVENT_DEVICE_REMOVED event before EI_EVENT_DISCONNECT.
EI_EVENT_DEVICE_REMOVED | The server has removed a device belonging to this client. The caller should release the struct ei_device and all its associated resources. Any events sent through a removed device are discarded. When this event is received, the device is already removed. A caller does not need to call ei_device_close() event on this device.
EI_EVENT_DEVICE_PAUSED | Any events sent from this device will be discarded until the next resume. The state of a device is not expected to change between pause/resume - for any significant state changes the server is expected to remove the device instead.
EI_EVENT_DEVICE_RESUMED | The client may send events.
EI_EVENT_KEYBOARD_MODIFIERS | The server has changed the modifier state on the device's keymap. See ei_event_keyboard_get_xkb_mods_depressed(), ei_event_keyboard_get_xkb_mods_latched(), ei_event_keyboard_get_xkb_mods_locked(), and ei_event_keyboard_get_xkb_group(). This event is sent in response to an external modifier state change. Where the client triggers a modifier state change in response to ei_device_keyboard_key(), no such event is sent. This event may arrive while a device is paused.
EI_EVENT_FRAME | "Hardware" frame event. This event must be sent by the server and notifies the client that the previous set of events belong to the same logical hardware event. Note These events are only generated on a receiver ei context. See ei_device_frame() for the sender context API.
EI_EVENT_DEVICE_START_EMULATING | The server is about to send events for a device. This event should be used by the client to clear the logical state of the emulated devices and/or provide UI to the user. Note These events are only generated on a receiver ei context. See ei_device_start_emulating() for the sender context API. Note that a server start multiple emulating sequences simultaneously, depending on the devices available. For example, in a synergy-like situation, the server may start sending pointer and keyboard once the remote device logically entered the screen.
EI_EVENT_DEVICE_STOP_EMULATING | The server stopped emulating events on this device, see EIS_EVENT_DEVICE_START_EMULATING. Note These events are only generated on a receiver ei context. See ei_device_stop_emulating() for the sender context API.
EI_EVENT_POINTER_MOTION | A relative motion event with delta coordinates in logical pixels or mm, depending on the device type. Note This event is only generated on a receiver ei context. See ei_device_pointer_motion() for the sender context API.
EI_EVENT_POINTER_MOTION_ABSOLUTE | An absolute motion event with absolute position within the device's regions or size, depending on the device type. Note This event is only generated on a receiver ei context. See ei_device_pointer_motion_absolute() for the sender context API.
EI_EVENT_BUTTON_BUTTON | A button press or release event. Note This event is only generated on a receiver ei context. See ei_device_button_button() for the sender context API.
EI_EVENT_SCROLL_DELTA | A vertical and/or horizontal scroll event with logical-pixels or mm precision, depending on the device type. Note This event is only generated on a receiver ei context. See ei_device_scroll_delta() for the sender context API.
EI_EVENT_SCROLL_STOP | An ongoing scroll sequence stopped. Note This event is only generated on a receiver ei context. See ei_device_scroll_stop() for the sender context API.
EI_EVENT_SCROLL_CANCEL | An ongoing scroll sequence was cancelled. Note This event is only generated on a receiver ei context. See ei_device_scroll_cancel() for the sender context API.
EI_EVENT_SCROLL_DISCRETE | A vertical and/or horizontal scroll event with a discrete range in logical scroll steps, like a scroll wheel. Note This event is only generated on a receiver ei context. See ei_device_scroll_discrete() for the sender context API.
EI_EVENT_KEYBOARD_KEY | A key press or release event. Note This event is only generated on a receiver ei context. See ei_device_keyboard_key() for the sender context API.
EI_EVENT_TOUCH_DOWN | Event for a single touch set down on the device's logical surface. A touch sequence is always down/up with an optional motion event in between. On multitouch capable devices, several touchs eqeuences may be active at any time. Note This event is only generated on a receiver ei context. See ei_device_touch_new() and ei_touch_down() for the sender context API.
EI_EVENT_TOUCH_UP | Event for a single touch released from the device's logical surface. Note This event is only generated on a receiver ei context. See ei_device_touch_new() and ei_touch_up() for the sender context API.
EI_EVENT_TOUCH_MOTION | Event for a single currently-down touch changing position (or other properties). Note This event is only generated on a receiver ei context. See ei_device_touch_new() and ei_touch_motion() for the sender context API.

## ◆ ei_keymap_type

enum ei_keymap_type

The set of supported keymap types for a struct ei_keymap.

Enumerator
EI_KEYMAP_TYPE_XKB | A libxkbcommon-compatible XKB keymap.

## Function Documentation

## ◆ ei_clock_set_now_func()

void ei_clock_set_now_func | ( | struct ei * | ,
|  | ei_clock_now_func | func )

Override the function that returns the current time ei_now().

There is rarely a need to override this function. It exists for the libei-internal test suite.

## ◆ ei_configure_name()

void ei_configure_name | ( | struct ei * | ei,
|  | const char * | name )

Set the name for this client.

This is a suggestion to the server only and may not be honored.

The client name may be used for display to the user, for example in an authorization dialog that requires the user to approve a connection to the EIS implementation.

This function must be called immediately after ei_new() and before setting up a backend with ei_setup_backend_socket() or ei_setup_backend_fd().

## ◆ ei_dispatch()

void ei_dispatch | ( | struct ei * | ei | ) |

Main event dispatching function.

Reads events of the file descriptors and processes them internally. Use ei_get_event() to retrieve the events.

Dispatching does not necessarily queue events. This function should be called immediately once data is available on the file descriptor returned by libei_get_fd().

## ◆ ei_event_get_device()

struct ei_device * ei_event_get_device | ( | struct ei_event * | event | ) |

Return the device from this event.

For events of type EI_EVENT_CONNECT and EI_EVENT_DISCONNECT, this function returns NULL.

This does not increase the refcount of the device. Use eis_device_ref() to keep a reference beyond the immediate scope.

## ◆ ei_event_get_seat()

struct ei_seat * ei_event_get_seat | ( | struct ei_event * | event | ) |

Return the seat from this event.

For events of type EI_EVENT_CONNECT and EI_EVENT_DISCONNECT, this function returns NULL.

This does not increase the refcount of the seat. Use eis_seat_ref() to keep a reference beyond the immediate scope.

## ◆ ei_event_get_time()

uint64_t ei_event_get_time | ( | struct ei_event * | event | ) |

Return the time for the event of type EI_EVENT_FRAME in microseconds.

Note
  Only events of type EI_EVENT_FRAME carry a timestamp. For convenience, the timestamp for other device events is retrofitted by this library.

Returns
  the event time in microseconds

## ◆ ei_event_get_type()

enum ei_event_type ei_event_get_type | ( | struct ei_event * | event | ) |

Returns
  the type of this event

## ◆ ei_event_type_to_string()

const char * ei_event_type_to_string | ( | enum | ei_event_type | ) |

This is a debugging helper to return a string of the name of the event type, or NULL if the event type is invalid.

For example, for EI_EVENT_TOUCH_UP this function returns the string "EI_EVENT_TOUCH_UP".

## ◆ ei_event_unref()

struct ei_event * ei_event_unref | ( | struct ei_event * | event | ) |

Release resources associated with this event.

This function always returns NULL.

The caller cannot increase the refcount of an event. Events should be considered transient data and not be held longer than required. ei_event_unref() is provided for consistency (as opposed to, say, ei_event_free()).

## ◆ ei_get_event()

struct ei_event * ei_get_event | ( | struct ei * | ei | ) |

Return the next event from the event queue, removing it from the queue.

The returned object must be released by the caller with ei_event_unref()

## ◆ ei_get_fd()

int ei_get_fd | ( | struct ei * | ei | ) |

libei keeps a single file descriptor for all events.

This fd should be monitored for events by the caller's mainloop, e.g. using select(). When events are available on this fd, call ei_dispatch() immediately to process.

## ◆ ei_get_user_data()

void * ei_get_user_data | ( | struct ei * | ei | ) |

Return the custom data pointer for this context.

libei will not look at or modify the pointer. Use ei_set_user_data() to change the user data.

## ◆ ei_is_sender()

bool ei_is_sender | ( | struct ei * | ei | ) |

Returns true if the context is was created with ei_new_sender() or false otherwise.

## ◆ ei_new()

struct ei * ei_new | ( | void * | user_data | ) |

This is an alias for ei_new_sender.

## ◆ ei_new_receiver()

struct ei * ei_new_receiver | ( | void * | user_data | ) |

Create a new receiver ei context.

The context is refcounted and must be released with ei_unref().

A receiver ei context receives events from the EIS implementation but cannot send events.

A context supports exactly one backend, set up with one of ei_setup_backend_socket() or ei_setup_backend_fd().

Parameters

  user_data | An opaque pointer to be returned with ei_get_user_data()

See also
  ei_set_user_data
  ei_get_user_data
  ei_setup_backend_fd
  ei_setup_backend_socket

## ◆ ei_new_sender()

struct ei * ei_new_sender | ( | void * | user_data | ) |

Create a new sender ei context.

The context is refcounted and must be released with ei_unref().

A sender ei context sends events to the EIS implementation but cannot receive events.

A context supports exactly one backend, set up with one of ei_setup_backend_socket() or ei_setup_backend_fd().

Parameters

  user_data | An opaque pointer to be returned with ei_get_user_data()

See also
  ei_set_user_data
  ei_get_user_data
  ei_setup_backend_fd
  ei_setup_backend_socket

## ◆ ei_now()

uint64_t ei_now | ( | struct ei * | ei | ) |

Returns
  a timestamp in microseconds for the current time to pass into ei_device_frame().

By default, the returned timestamp is CLOCK_MONOTONIC for compatibility with evdev and libinput. This can be overridden with ei_clock_set_now_func().

## ◆ ei_peek_event()

struct ei_event * ei_peek_event | ( | struct ei * | ei | ) |

Returns the next event in the internal event queue (or `NULL`) without removing that event from the queue; the next call to ei_get_event() will return that same event.

This call is useful for checking whether there is an event and/or what type of event it is.

Repeated calls to ei_peek_event() return the same event.

The returned event is refcounted, use ei_event_unref() to drop the reference.

A caller must not call ei_get_event() while holding a ref to an event returned by ei_peek_event(). Doing so is undefined behavior.

## ◆ ei_ref()

struct ei * ei_ref | ( | struct ei * | ei | ) |

Increase the refcount of this struct by one.

Use ei_unref() to decrease the refcount.

Returns
  the argument passed into the function

## ◆ ei_set_user_data()

void ei_set_user_data | ( | struct ei * | ei,
|  | void * | user_data )

Set a custom data pointer for this context.

libei will not look at or modify the pointer. Use ei_get_user_data() to retrieve a previously set user data.

## ◆ ei_setup_backend_fd()

int ei_setup_backend_fd | ( | struct ei * | ei,
|  | int | fd )

Initialize the ei context on the given socket.

The ei context will initiate the conversation with the EIS server listening on the other end of this socket.

If the connection was successful, an event of type EI_EVENT_CONNECT or EI_EVENT_DISCONNECT will become available after a future call to ei_dispatch().

If the connection failed, use ei_unref() to release the data allocated for this context.

This function takes ownership of the file descriptor, and will close it when tearing down.

Returns
  zero on success or a negative errno on failure

## ◆ ei_setup_backend_socket()

int ei_setup_backend_socket | ( | struct ei * | ei,
|  | const char * | socketpath )

Set this ei context to use the socket backend.

The ei context will connect to the socket at the given path and initiate the conversation with the EIS server listening on that socket.

If socketpath is `NULL`, the value of the environment variable `LIBEI_SOCKET` is used. If socketpath does not start with '/', it is relative to `$XDG_RUNTIME_DIR`. If `XDG_RUNTIME_DIR` is not set, this function fails.

If the connection was successful, an event of type EI_EVENT_CONNECT or EI_EVENT_DISCONNECT will become available after a future call to ei_dispatch().

If the connection failed, use ei_unref() to release the data allocated for this context.

Returns
  zero on success or a negative errno on failure

## ◆ ei_unref()

struct ei * ei_unref | ( | struct ei * | ei | ) |

Decrease the refcount of this struct by one.

When the refcount reaches zero, the context disconnects from the server and all allocated resources are released.

Returns
  always NULL