mirror of
https://gitlab.freedesktop.org/libinput/libei.git
synced 2026-04-05 12:40:37 +02:00
There's nothing in the protocol to modify the client device state from the server, so a pause/resume cycle must leave the client with the same(-ish) state. Pause is really just that, a short "no event now please". Anything that would require e.g. modifying the device state by releasing keys or buttons should result in the device being removed and re-added. Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
1065 lines
32 KiB
C
1065 lines
32 KiB
C
/*
|
|
* Copyright © 2020 Red Hat, Inc.
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
* copy of this software and associated documentation files (the "Software"),
|
|
* to deal in the Software without restriction, including without limitation
|
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
* and/or sell copies of the Software, and to permit persons to whom the
|
|
* Software is furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice (including the next
|
|
* paragraph) shall be included in all copies or substantial portions of the
|
|
* Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
* DEALINGS IN THE SOFTWARE.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
#include <stddef.h>
|
|
|
|
/**
|
|
* @addtogroup libei EI - The client API
|
|
*
|
|
* libei is the client-side module. This API should be used by processes
|
|
* that need to emulate devices.
|
|
*
|
|
* @{
|
|
*/
|
|
|
|
/**
|
|
* @struct ei
|
|
*
|
|
* The main context to interact with libei. A libei context is a single
|
|
* connection to an EIS implementation and may contain multiple devices, see
|
|
* @ref ei_device.
|
|
*
|
|
* An @ref ei context is refcounted, see ei_unref().
|
|
*/
|
|
struct ei;
|
|
|
|
/**
|
|
* @struct ei_device
|
|
*
|
|
* A single device to generate input events from. A device may have multiple
|
|
* capabilities. For example, a single device may be a pointer and a keyboard
|
|
* and a touch device. It is up to the EIS implementation on how to handle
|
|
* this case, some implementations may split a single device up into
|
|
* multiple virtual devices, others may not.
|
|
*
|
|
* An @ref ei_device is refcounted, see ei_device_unref().
|
|
*/
|
|
struct ei_device;
|
|
|
|
/**
|
|
* @struct ei_seat
|
|
*
|
|
* A logical seat for a group of devices. Seats are provided by the EIS
|
|
* implementation, devices may be added to a seat. The hierarchy of objects
|
|
* looks like this:
|
|
* <pre>
|
|
* ei ---- ei_seat one ---- ei_device 1
|
|
* \ \
|
|
* \ --- ei device 2
|
|
* --- ei_seat two --- ei device 3
|
|
* </pre>
|
|
*/
|
|
struct ei_seat;
|
|
|
|
/**
|
|
* @struct ei_event
|
|
*
|
|
* An event received from the EIS implementation. See @ref ei_event_type
|
|
* for the list of possible event types.
|
|
*
|
|
* An @ref ei_event is refcounted, see ei_event_unref().
|
|
*/
|
|
struct ei_event;
|
|
|
|
/**
|
|
* @struct ei_keymap
|
|
*
|
|
* An keymap for a device with the @ref EI_DEVICE_CAP_KEYBOARD capability.
|
|
*
|
|
* An @ref ei_keymap is refcounted, see ei_keymap_unref().
|
|
*/
|
|
struct ei_keymap;
|
|
|
|
/**
|
|
* @struct ei_region
|
|
*
|
|
* A rectangular region, defined by an x/y offset and a width and a height.
|
|
* A region defines the area on an EIS desktop layout that is accessible by
|
|
* this device - this region may not be the full area of the desktop.
|
|
* Input events may only be sent for points within the regions.
|
|
*
|
|
* The use of regions is private to the EIS compositor and coordinates may not
|
|
* match the size of the actual desktop. For example, a compositor may set a
|
|
* 1920x1080 region to represent a 4K monitor and transparently map input
|
|
* events into the respective true pixels.
|
|
*
|
|
* Absolute devices may have different regions, it is up to the libei client
|
|
* to send events through the correct device to target the right pixel. For
|
|
* example, a dual-head setup my have two absolute devices, the first with a
|
|
* zero offset region spanning the first screen, the second with a nonzero
|
|
* offset spanning the second screen.
|
|
*/
|
|
struct ei_region;
|
|
|
|
/**
|
|
* @enum ei_device_capability
|
|
*
|
|
* The set of supported capabilities. A device may have one or more
|
|
* capabilities but never zero - a EIS implementation must reject any
|
|
* device with zero capabilities.
|
|
*
|
|
* Capabilities are requested by the client but the EIS
|
|
* implementation may further reduce the capabilities. For example, a client
|
|
* may request the pointer and keyboard capability but only the former is
|
|
* permitted by the server. Any keyboard events sent by such a device events
|
|
* will be treated as client bug and discarded.
|
|
*
|
|
* See eis_device_has_capability().
|
|
*
|
|
*/
|
|
enum ei_device_capability {
|
|
EI_DEVICE_CAP_POINTER = 1,
|
|
EI_DEVICE_CAP_POINTER_ABSOLUTE,
|
|
EI_DEVICE_CAP_KEYBOARD,
|
|
EI_DEVICE_CAP_TOUCH,
|
|
};
|
|
|
|
/**
|
|
* @enum ei_keymap_type
|
|
*
|
|
* The set of supported keymap types for a struct @ref ei_keymap.
|
|
*/
|
|
enum ei_keymap_type {
|
|
/**
|
|
* A libxkbcommon-compatible XKB keymap.
|
|
*/
|
|
EI_KEYMAP_TYPE_XKB = 1,
|
|
};
|
|
|
|
enum ei_event_type {
|
|
/**
|
|
* The server has approved the connection to this client. Where the
|
|
* server does not approve the connection, @ref EI_EVENT_DISCONNECT is
|
|
* sent instead.
|
|
*
|
|
* This event is only sent once after the initial connection
|
|
* request.
|
|
*/
|
|
EI_EVENT_CONNECT = 1,
|
|
|
|
/**
|
|
* The server has disconnected this client - all resources left to
|
|
* reference this server are now obsolete. Once this event has been
|
|
* received, the struct @ref 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 @ref EI_EVENT_DISCONNECT is provided to
|
|
* the caller even where the server does not send one.
|
|
*/
|
|
EI_EVENT_DISCONNECT,
|
|
|
|
/**
|
|
* The server has added a seat available to this client.
|
|
*
|
|
* libei guarantees that any seat added has a corresponding @ref
|
|
* EI_EVENT_SEAT_REMOVED event before @ref EI_EVENT_DISCONNECT.
|
|
* libei guarantees that any device in this seat generates a @ref
|
|
* EI_EVENT_DEVICE_REMOVED event before the @ref
|
|
* EI_EVENT_SEAT_REMOVED event.
|
|
*/
|
|
EI_EVENT_SEAT_ADDED,
|
|
|
|
/**
|
|
* The server has removed a seat previously available to this
|
|
* client. The caller should release the struct @ref 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 @ref
|
|
* EI_EVENT_DEVICE_REMOVED event before the @ref
|
|
* EI_EVENT_SEAT_REMOVED event.
|
|
*/
|
|
EI_EVENT_SEAT_REMOVED,
|
|
|
|
/**
|
|
* 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 @ref
|
|
* EI_EVENT_DEVICE_REMOVED event before @ref EI_EVENT_DISCONNECT.
|
|
*/
|
|
EI_EVENT_DEVICE_ADDED,
|
|
|
|
/**
|
|
* The server has removed a device belonging to this client. The
|
|
* caller should release the struct @ref 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_remove() event on this
|
|
* device.
|
|
*/
|
|
EI_EVENT_DEVICE_REMOVED,
|
|
|
|
/**
|
|
* 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_PAUSED,
|
|
/**
|
|
* The client may send events.
|
|
*/
|
|
EI_EVENT_DEVICE_RESUMED,
|
|
};
|
|
|
|
/**
|
|
* Create a new ei context. The context is refcounted and must be released
|
|
* with ei_unref().
|
|
*
|
|
* A context supports exactly one backend, set up with one of
|
|
* ei_setup_backend_socket() or ei_setup_backend_fd().
|
|
*
|
|
* @param user_data An opaque pointer to be returned with ei_get_user_data()
|
|
*
|
|
* @see ei_set_user_data
|
|
* @see ei_get_user_data
|
|
* @see ei_setup_backend_fd
|
|
* @see ei_setup_backend_socket
|
|
*/
|
|
struct ei *
|
|
ei_new(void *user_data);
|
|
|
|
enum ei_log_priority {
|
|
EI_LOG_PRIORITY_DEBUG = 10,
|
|
EI_LOG_PRIORITY_INFO = 20,
|
|
EI_LOG_PRIORITY_WARNING = 30,
|
|
EI_LOG_PRIORITY_ERROR = 40,
|
|
};
|
|
|
|
/**
|
|
* The log handler for library logging. This handler is only called for
|
|
* messages with a log level equal or greater than than the one set in
|
|
* ei_log_set_priority().
|
|
*
|
|
* @param ei The EI context
|
|
* @param priority The log priority
|
|
* @param file The filename where this log message was triggered
|
|
* @param lineno The line number in @a file where this log message was triggered
|
|
* @param func The function name where this log message was triggered
|
|
* @param message The log message as a null-terminated string
|
|
* @param is_continuation The message is a continuation of the previous
|
|
* message. The caller should skip any per-line-based prefixes.
|
|
*/
|
|
typedef void (*ei_log_handler)(struct ei *ei,
|
|
enum ei_log_priority priority,
|
|
const char *file, int lineno, const char *func,
|
|
const char *message,
|
|
bool is_continuation);
|
|
/**
|
|
* Change the log handler for this context. If the log handler is NULL, the
|
|
* built-in default log function is used.
|
|
*
|
|
* @param ei The EI context
|
|
* @param log_handler The log handler or NULL to use the default log
|
|
* handler.
|
|
*/
|
|
void
|
|
ei_log_set_handler(struct ei *ei, ei_log_handler log_handler);
|
|
|
|
void
|
|
ei_log_set_priority(struct ei *ei, enum ei_log_priority priority);
|
|
|
|
enum ei_log_priority
|
|
ei_log_get_priority(const struct ei *ei);
|
|
|
|
/**
|
|
* 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().
|
|
*/
|
|
void
|
|
ei_configure_name(struct ei * ei, const char *name);
|
|
|
|
/**
|
|
* 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 @a socketpath is `NULL`, the value of the environment variable
|
|
* `LIBEI_SOCKET` is used. If @a 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 @ref EI_EVENT_CONNECT
|
|
* or @ref 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.
|
|
*
|
|
* @return zero on success or a negative errno on failure
|
|
*/
|
|
int
|
|
ei_setup_backend_socket(struct ei *ei, const char *socketpath);
|
|
|
|
/**
|
|
* 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 @ref EI_EVENT_CONNECT
|
|
* or @ref 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.
|
|
*
|
|
* @return zero on success or a negative errno on failure
|
|
*/
|
|
int
|
|
ei_setup_backend_fd(struct ei *ei, int fd);
|
|
|
|
/**
|
|
* Connect to the `org.freedesktop.portal.Desktop` portal.
|
|
*
|
|
* @return 0 on success or a negative errno on failure
|
|
*/
|
|
int
|
|
ei_setup_backend_portal(struct ei *ei);
|
|
|
|
/**
|
|
* Connect to an `org.freedesktop.portal.Desktop` implementation on the
|
|
* given busname.
|
|
*
|
|
* Outside of testing environments, there is usually no reason to use
|
|
* this function, use ei_setup_backend_portal() instead.
|
|
*
|
|
* @return 0 on success or a negative errno on failure
|
|
*/
|
|
int
|
|
ei_setup_backend_portal_busname(struct ei *ei, const char *busname);
|
|
|
|
/**
|
|
* Increase the refcount of this struct by one. Use ei_unref() to decrease
|
|
* the refcount.
|
|
*
|
|
* @return the argument passed into the function
|
|
*/
|
|
struct ei *
|
|
ei_ref(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.
|
|
*
|
|
* @return always NULL
|
|
*/
|
|
struct ei *
|
|
ei_unref(struct ei *ei);
|
|
|
|
/**
|
|
* 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.
|
|
*/
|
|
void
|
|
ei_set_user_data(struct ei *ei, void *user_data);
|
|
|
|
/**
|
|
* 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.
|
|
*/
|
|
void *
|
|
ei_get_user_data(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 libei_dispatch() immediately to
|
|
* process.
|
|
*/
|
|
int
|
|
ei_get_fd(struct ei *ei);
|
|
|
|
/**
|
|
* Main event dispatching function. Reads events of the file descriptors
|
|
* and processes them internally. Use libei_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().
|
|
*/
|
|
void
|
|
ei_dispatch(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()
|
|
*/
|
|
struct ei_event *
|
|
ei_get_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.
|
|
*/
|
|
struct ei_event *
|
|
ei_peek_event(struct ei *ei);
|
|
|
|
/**
|
|
* 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()).
|
|
*/
|
|
struct ei_event *
|
|
ei_event_unref(struct ei_event *event);
|
|
|
|
const char *
|
|
ei_seat_get_name(struct ei_seat *seat);
|
|
|
|
bool
|
|
ei_seat_has_capability(struct ei_seat *seat,
|
|
enum ei_device_capability cap);
|
|
|
|
/**
|
|
* Remove a capability from this seat before calling ei_seat_bind().
|
|
* Devices with only the dropped capability will never be added to this
|
|
* client, devices with multiple capabilities will not show the dropped
|
|
* capabilities.
|
|
*
|
|
* This function has no effect if called after ei_seat_bind().
|
|
*/
|
|
void
|
|
ei_seat_drop_capability(struct ei_seat *seat,
|
|
enum ei_device_capability cap);
|
|
|
|
/**
|
|
* Bind this client to the given seat for the seat's capabilities.
|
|
* This function can only be called once per seat. Once bound, the server will
|
|
* create devices for the seat's capabillities and send the respective @ref
|
|
* EI_EVENT_DEVICE_ADDED events.
|
|
*
|
|
* Devices may be added and removed at any time.
|
|
*/
|
|
void
|
|
ei_seat_bind(struct ei_seat *seat);
|
|
|
|
/**
|
|
* Unbind a seat and remove it from the server.
|
|
*
|
|
* If called on a seat immediately after @ref EI_EVENT_SEAT_ADDED, this
|
|
* function indicates that the client is not interested in this seat.
|
|
* If called on a seat after ei_seat_bind(), this function implicitly calls
|
|
* ei_device_close() on all devices for this seat.
|
|
*
|
|
* The server responds with an @ref EI_EVENT_SEAT_REMOVED event.
|
|
*/
|
|
void
|
|
ei_seat_unbind(struct ei_seat *seat);
|
|
|
|
struct ei_seat *
|
|
ei_seat_ref(struct ei_seat *seat);
|
|
|
|
struct ei_seat *
|
|
ei_seat_unref(struct ei_seat *seat);
|
|
|
|
/**
|
|
* Return the struct @ref ei context this seat is associated with.
|
|
*/
|
|
struct ei *
|
|
ei_seat_get_context(struct ei_seat *seat);
|
|
|
|
/**
|
|
* @return the type of this event
|
|
*/
|
|
enum ei_event_type
|
|
ei_event_get_type(struct ei_event *event);
|
|
|
|
/**
|
|
* Return the device from this event.
|
|
*
|
|
* For events of type @ref EI_EVENT_CONNECT and @ref 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.
|
|
*/
|
|
struct ei_device *
|
|
ei_event_get_device(struct ei_event *event);
|
|
|
|
/**
|
|
* @return the event time in microseconds
|
|
*/
|
|
uint64_t
|
|
ei_event_get_time(struct ei_event *event);
|
|
|
|
/**
|
|
* Increase the refcount of this struct by one. Use ei_device_unref() to
|
|
* decrease the refcount.
|
|
*
|
|
* @return the argument passed into the function
|
|
*/
|
|
struct ei_device *
|
|
ei_device_ref(struct ei_device *device);
|
|
|
|
/**
|
|
* 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.
|
|
*
|
|
* @return always NULL
|
|
*/
|
|
struct ei_device *
|
|
ei_device_unref(struct ei_device *device);
|
|
|
|
struct ei_seat *
|
|
ei_device_get_seat(struct ei_device *device);
|
|
|
|
/**
|
|
* Set a custom data pointer for this context. libei will not look at or
|
|
* modify the pointer. Use ei_seat_get_user_data() to retrieve a
|
|
* previously set user data.
|
|
*/
|
|
void
|
|
ei_seat_set_user_data(struct ei_seat *seat, void *user_data);
|
|
|
|
/**
|
|
* Return the custom data pointer for this context. libei will not look at or
|
|
* modify the pointer. Use ei_seat_get_user_data() to change the user data.
|
|
*/
|
|
void *
|
|
ei_seat_get_user_data(struct ei_seat *seat);
|
|
|
|
/**
|
|
* Set a custom data pointer for this context. libei will not look at or
|
|
* modify the pointer. Use ei_device_get_user_data() to retrieve a
|
|
* previously set user data.
|
|
*/
|
|
void
|
|
ei_device_set_user_data(struct ei_device *device, void *user_data);
|
|
|
|
/**
|
|
* Return the custom data pointer for this context. libei will not look at or
|
|
* modify the pointer. Use ei_device_get_user_data() to change the user data.
|
|
*/
|
|
void *
|
|
ei_device_get_user_data(struct ei_device *device);
|
|
|
|
|
|
struct ei_keymap *
|
|
ei_device_get_keymap(struct ei_device *device);
|
|
|
|
/**
|
|
* @return the size of the keymap in bytes
|
|
*/
|
|
size_t
|
|
ei_keymap_get_size(struct ei_keymap *keymap);
|
|
|
|
/**
|
|
* Returns the type for this keymap. The type specifies how to interpret the
|
|
* data at the file descriptor returned by ei_keymap_get_fd().
|
|
*/
|
|
enum ei_keymap_type
|
|
ei_keymap_get_type(struct ei_keymap *keymap);
|
|
|
|
/**
|
|
* Return a memmap-able file descriptor pointing to the keymap used by the
|
|
* device. The keymap is constant for the lifetime of the device and
|
|
* assigned to this device individually.
|
|
*/
|
|
int
|
|
ei_keymap_get_fd(struct ei_keymap *keymap);
|
|
|
|
/**
|
|
* Return the device this keymap belongs to, or `NULL` if it has not yet
|
|
* been assigned to a device.
|
|
*
|
|
* Between ei_device_keyboard_configure_keymap() and libei processing an
|
|
* @ref EI_EVENT_DEVICE_ADDED event, the returned device is the one provided
|
|
* in ei_device_keyboard_configure_keymap().
|
|
*
|
|
* After processing and if the server changed the keymap or set the keymap
|
|
* to NULL, this keymap may no longer be in use by the device and future
|
|
* calls to this function return `NULL`.
|
|
*/
|
|
struct ei_device *
|
|
ei_keymap_get_device(struct ei_keymap *keymap);
|
|
|
|
/**
|
|
* Increase the refcount of this struct by one. Use ei_keymap_unref() to
|
|
* decrease the refcount.
|
|
*
|
|
* @return the argument passed into the function
|
|
*/
|
|
struct ei_keymap *
|
|
ei_keymap_ref(struct ei_keymap *keymap);
|
|
|
|
/**
|
|
* 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.
|
|
*
|
|
* @return always NULL
|
|
*/
|
|
struct ei_keymap *
|
|
ei_keymap_unref(struct ei_keymap *keymap);
|
|
|
|
void
|
|
ei_keymap_set_user_data(struct ei_keymap *keymap, void *user_data);
|
|
|
|
void *
|
|
ei_keymap_get_user_data(struct ei_keymap *keymap);
|
|
|
|
/**
|
|
* Notify the server that the client is no longer listening to events
|
|
* from this device.
|
|
*
|
|
* Due to the asynchronous nature of the client-server interaction,
|
|
* events for this device may still be in transit. The server will send an
|
|
* @ref EI_EVENT_DEVICE_REMOVED event for this device. After that event,
|
|
* device is considered removed by the server.
|
|
*
|
|
* A client can assume that an @ref EI_EVENT_DEVICE_REMOVED event is sent
|
|
* for any device for which ei_device_close() was called before the @ref
|
|
* EI_EVENT_DISCONNECT. Where a client gets
|
|
* disconnected libei will emulate that event.
|
|
*
|
|
* This does not release any resources associated with this device, use
|
|
* ei_device_unref() for any references held by the client.
|
|
*/
|
|
void
|
|
ei_device_close(struct ei_device *device);
|
|
|
|
/**
|
|
* Return the name of this device.
|
|
*
|
|
* The return value of this function is constant after receiving the @ref
|
|
* EI_EVENT_DEVICE_ADDED event. Before then, the returned string may be
|
|
* freed at any time, callers must strdup() the returned value if they need
|
|
* to keep the name around.
|
|
*
|
|
* @return the name of the device (if any) or NULL
|
|
*/
|
|
const char *
|
|
ei_device_get_name(struct ei_device *device);
|
|
|
|
/**
|
|
* Return true if the device has the requested capability. Device
|
|
* capabilities are constant after the @ref EI_EVENT_DEVICE_ADDED event.
|
|
*
|
|
* To change a device's capability, the device must be removed and a new
|
|
* device with the different capabilities must be added.
|
|
*/
|
|
bool
|
|
ei_device_has_capability(struct ei_device *device,
|
|
enum ei_device_capability cap);
|
|
|
|
|
|
/**
|
|
* Obtain a region from the device. The number of regions is constant for a
|
|
* device and the indices of any region remains the same for the lifetime of
|
|
* the device.
|
|
*
|
|
* Regions are shared between all capabilities. Where two capabilities need
|
|
* different region, the EIS implementation must create multiple devices with
|
|
* individual capabilities and regions.
|
|
*
|
|
* This function returns the given region or NULL if the index is larger than
|
|
* the number of regions available.
|
|
*
|
|
* This does not increase the refcount of the region. Use ei_region_ref() to
|
|
* keep a reference beyond the immediate scope.
|
|
*/
|
|
struct ei_region *
|
|
ei_device_get_region(struct ei_device *device, size_t index);
|
|
|
|
struct ei_region *
|
|
ei_region_ref(struct ei_region *region);
|
|
|
|
struct ei_region *
|
|
ei_region_unref(struct ei_region *region);
|
|
|
|
void
|
|
ei_region_set_user_data(struct ei_region *region, void *user_data);
|
|
|
|
void *
|
|
ei_region_get_user_data(struct ei_region *region);
|
|
|
|
uint32_t
|
|
ei_region_get_x(struct ei_region *region);
|
|
|
|
uint32_t
|
|
ei_region_get_y(struct ei_region *region);
|
|
|
|
uint32_t
|
|
ei_region_get_width(struct ei_region *region);
|
|
|
|
uint32_t
|
|
ei_region_get_height(struct ei_region *region);
|
|
|
|
/**
|
|
* Return true if the point x/y (in desktop-wide coordinates) is within @a
|
|
* region.
|
|
*/
|
|
bool
|
|
ei_region_contains(struct ei_region *region, double x, double y);
|
|
|
|
/**
|
|
* Convert the point x/y in a desktop-wide coordinate system into the
|
|
* corresponding point relative to the offset of the given region.
|
|
* If the point is inside the region, this function returns true and @a x and @a
|
|
* y are set to the points with region offset subtracted.
|
|
* If the point is outside the region, this function returns false and @a x
|
|
* and @a y are left unmodified.
|
|
*/
|
|
bool
|
|
ei_region_convert_point(struct ei_region *region, double *x, double *y);
|
|
|
|
/**
|
|
* Return the physical scale for this region. The default scale is 1.0.
|
|
*
|
|
* The regions' coordinate space is in logical pixels in the EIS range. The
|
|
* logical pixels may or may not match the physical pixels on the output
|
|
* range but the mapping from logical pixels to physical pixels is performed
|
|
* by the EIS implementation.
|
|
*
|
|
* In some use-cases though, relative data from a remote input source needs
|
|
* to be converted by the libei client into an absolute movement on an EIS
|
|
* region. In that case, the physical scale provides the factor to multiply
|
|
* the relative logical input to provide the expected physical relative
|
|
* movement.
|
|
*
|
|
* For example consider the following dual-monitor setup comprising a 2k and
|
|
* a 4k monitor **of the same physical size**:
|
|
* The physical layout of the monitors appears like this:
|
|
* @code
|
|
* 2k 4k
|
|
* +-------------++-------------+
|
|
* | || |
|
|
* | a b || c d |
|
|
* | || |
|
|
* +-------------++-------------+
|
|
* @endcode
|
|
*
|
|
* The physical distance `ab` is the same as the physical distance `cd`.
|
|
* Where the EIS implementation supports high-dpi screens, the logical
|
|
* distance (in pixels) are identical too.
|
|
*
|
|
* Where the EIS implementation does not support high-dpi screens, the
|
|
* logical layout of these two monitors appears like this:
|
|
*
|
|
* @code
|
|
* 2k 4k
|
|
* +-------------++--------------------------+
|
|
* | || |
|
|
* | a b || |
|
|
* | || |
|
|
* +-------------+| c d |
|
|
* | |
|
|
* | |
|
|
* | |
|
|
* +--------------------------+
|
|
* @endcode
|
|
*
|
|
* While the two physical distances `ab` and `cd` are still identical, the
|
|
* logical distance `cd` (in pixels) is twice that of `ab`.
|
|
* Where a libei client receives relative deltas from an input source and
|
|
* converts that relative input into an absolute position on the screen, it
|
|
* needs to take this into account.
|
|
*
|
|
* For example, if a remote input source moves by relative 100 logical
|
|
* pixels, the libei client would convert this as `a + 100 = b` on the
|
|
* region for the 2k screen and send the absolute events to logically change
|
|
* the position from `a` to `b`. If the same remote input source moves by
|
|
* relative 100 logical pixels, the libei client would convert this as
|
|
* `c + 100 * scale = d` on the region for the 4k screen to logically
|
|
* change the position from `c` to `d`. While the pixel movement differs,
|
|
* the physical movement as seen by the user is thus identical.
|
|
*
|
|
* A second possible use-case for the physical scale is to match pixels from
|
|
* one region to their respective counterpart on a different region.
|
|
* For example, if the bottom-right corner of the 2k screen in the
|
|
* illustration above has a coordinate of x/y, the neighbouring pixel on the
|
|
* **physical** 4k screen is (0/y * scale).
|
|
*/
|
|
double
|
|
ei_region_get_physical_scale(struct ei_region *region);
|
|
|
|
/**
|
|
* Return the keymap for this device or `NULL`. The keymap is constant for
|
|
* the lifetime of the device after the @ref EI_EVENT_DEVICE_ADDED was
|
|
* received and applies to this device individually.
|
|
*
|
|
* If this function returns `NULL`, this device does not have
|
|
* an individual keymap assigned. What keymap applies to the device in this
|
|
* case is a server implementation detail.
|
|
*
|
|
* This does not increase the refcount of the keymap. Use ei_keymap_ref() to
|
|
* keep a reference beyond the immediate scope.
|
|
*
|
|
* FIXME: the current API makes it impossible to know when the keymap has
|
|
* been consumed so the file stays open forever.
|
|
*/
|
|
struct ei_keymap *
|
|
ei_device_keyboard_get_keymap(struct ei_device *device);
|
|
|
|
/**
|
|
* Return the struct @ref ei_device this keymap is associated with.
|
|
*/
|
|
struct ei_device *
|
|
ei_keymap_get_context(struct ei_keymap *keymap);
|
|
|
|
/**
|
|
* Return the struct @ref ei context this device is associated with.
|
|
*/
|
|
struct ei *
|
|
ei_device_get_context(struct ei_device *device);
|
|
|
|
/**
|
|
* Generate a relative motion event on a device with
|
|
* the @ref EI_DEVICE_CAP_POINTER capability.
|
|
*
|
|
* @param device The EI device
|
|
* @param x The x movement in logical pixels
|
|
* @param y The y movement in logical pixels
|
|
*/
|
|
void
|
|
ei_device_pointer_motion(struct ei_device *device, double x, double y);
|
|
|
|
/**
|
|
* Generate an absolute motion event on a device with
|
|
* the @ref EI_DEVICE_CAP_POINTER_ABSOLUTE capability.
|
|
*
|
|
* The required conditions are:
|
|
* - 0 <= x < width
|
|
* - 0 <= y < height
|
|
* If these conditions are not met, the event is silently discarded.
|
|
*
|
|
* @param device The EI device
|
|
* @param x The x position in logical pixels
|
|
* @param y The y position in logical pixels
|
|
*/
|
|
void
|
|
ei_device_pointer_motion_absolute(struct ei_device *device,
|
|
double x, double y);
|
|
|
|
/**
|
|
* Generate a button event on a device with
|
|
* the @ref EI_DEVICE_CAP_POINTER_ABSOLUTE or
|
|
* @ref EI_DEVICE_CAP_POINTER capability.
|
|
*
|
|
* Button codes must match the defines in linux/input-event-codes.h
|
|
*
|
|
* @param device The EI device
|
|
* @param button The button code
|
|
* @param is_press true for button press, false for button release
|
|
*/
|
|
void
|
|
ei_device_pointer_button(struct ei_device *device,
|
|
uint32_t button, bool is_press);
|
|
|
|
/**
|
|
* Generate a scroll event on a device with
|
|
* the @ref EI_DEVICE_CAP_POINTER_ABSOLUTE or
|
|
* @ref EI_DEVICE_CAP_POINTER capability.
|
|
*
|
|
* @note The server is responsible for emulating discrete scrolling based
|
|
* on the pixel value, do not call ei_device_pointer_scroll_discrete() for
|
|
* the same input event.
|
|
*
|
|
* @param device The EI device
|
|
* @param x The x scroll distance in logical pixels
|
|
* @param y The y scroll distance in logical pixels
|
|
*
|
|
* @see ei_device_pointer_scroll_discrete
|
|
*/
|
|
void
|
|
ei_device_pointer_scroll(struct ei_device *device, double x, double y);
|
|
|
|
/**
|
|
* Generate a discrete scroll event on a device with
|
|
* the @ref EI_DEVICE_CAP_POINTER_ABSOLUTE or
|
|
* @ref EI_DEVICE_CAP_POINTER capability.
|
|
*
|
|
* A discrete scroll event is based logical scroll units (equivalent to one
|
|
* mouse wheel click). The value for one scroll unit is 120, a fraction or
|
|
* multiple thereof represents a fraction or multiple of a wheel click.
|
|
*
|
|
* @note The server is responsible for emulating pixel-based scrolling based
|
|
* on the discrete value, do not call ei_device_pointer_scroll() for the
|
|
* same input event.
|
|
*
|
|
* @param device The EI device
|
|
* @param x The x scroll distance in fractions or multiples of 120
|
|
* @param y The y scroll distance in fractions or multiples of 120
|
|
*
|
|
* @see ei_device_pointer_scroll
|
|
*/
|
|
void
|
|
ei_device_pointer_scroll_discrete(struct ei_device *device, int32_t x, int32_t y);
|
|
|
|
/**
|
|
* Generate a key event on a device with
|
|
* the @ref EI_DEVICE_CAP_KEYBOARD capability.
|
|
*
|
|
* Keys use the evdev scan codes as defined in
|
|
* linux/input-event-codes.h
|
|
*
|
|
* @param device The EI device
|
|
* @param keycode The key code
|
|
* @param is_press true for key down, false for key up
|
|
*/
|
|
void
|
|
ei_device_keyboard_key(struct ei_device *device, uint32_t keycode, bool is_press);
|
|
|
|
/**
|
|
* Initiate a new touch on a device with the @ref EI_DEVICE_CAP_TOUCH
|
|
* capability. This touch does not immediately send events, use
|
|
* ei_touch_down(), ei_touch_motion(), and ei_touch_up().
|
|
*
|
|
* The returned touch has a refcount of at least 1, use ei_touch_unref() to
|
|
* release resources associated with this touch
|
|
*/
|
|
struct ei_touch *
|
|
ei_device_touch_new(struct ei_device *device);
|
|
|
|
/**
|
|
* This function can only be called once on an ei_touch object. Further
|
|
* calls to ei_touch_down() on the same object are silently ignored.
|
|
*
|
|
* The required conditions are:
|
|
* - 0 <= x < width
|
|
* - 0 <= y < height
|
|
*
|
|
* @param touch A newly created touch
|
|
* @param x The x position in logical pixels
|
|
* @param y The y position in logical pixels
|
|
*/
|
|
void
|
|
ei_touch_down(struct ei_touch *touch, double x, double y);
|
|
|
|
/**
|
|
* Move this touch to the new coordinates.
|
|
*/
|
|
void
|
|
ei_touch_motion(struct ei_touch *touch, double x, double y);
|
|
|
|
/**
|
|
* Release this touch. After this call, the touch event becomes inert and
|
|
* no longer responds to either ei_touch_down(), ei_touch_motion() or
|
|
* ei_touch_up() and the caller should call ei_touch_unref().
|
|
*/
|
|
void
|
|
ei_touch_up(struct ei_touch *touch);
|
|
|
|
/**
|
|
* Increase the refcount of this struct by one. Use ei_touch_unref() to
|
|
* decrease the refcount.
|
|
*
|
|
* @return the argument passed into the function
|
|
*/
|
|
struct ei_touch *
|
|
ei_touch_ref(struct ei_touch *touch);
|
|
|
|
/**
|
|
* 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.
|
|
*
|
|
* @return always NULL
|
|
*/
|
|
struct ei_touch *
|
|
ei_touch_unref(struct ei_touch *touch);
|
|
|
|
/**
|
|
* Return the custom data pointer for this context. libei will not look at or
|
|
* modify the pointer. Use ei_touch_set_user_data() to change the user data.
|
|
*/
|
|
void
|
|
ei_touch_set_user_data(struct ei_touch *touch, void *user_data);
|
|
|
|
/**
|
|
* Set a custom data pointer for this context. libei will not look at or
|
|
* modify the pointer. Use ei_touch_get_user_data() to retrieve a previously
|
|
* set user data.
|
|
*/
|
|
void *
|
|
ei_touch_get_user_data(struct ei_touch *touch);
|
|
|
|
/**
|
|
* @return the device this touch originates on
|
|
*/
|
|
struct ei_device *
|
|
ei_touch_get_device(struct ei_touch *touch);
|
|
|
|
/**
|
|
* Return the seat from this event.
|
|
*
|
|
* For events of type @ref EI_EVENT_CONNECT and @ref 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.
|
|
*/
|
|
struct ei_seat *
|
|
ei_event_get_seat(struct ei_event *event);
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|