libei/src/libei.h

581 lines
18 KiB
C
Raw Normal View History

/*
* 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
#include <stdbool.h>
#include <stdint.h>
struct ei;
struct ei_device;
struct ei_event;
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 {
EI_KEYMAP_TYPE_NONE = 0,
EI_KEYMAP_TYPE_XKB,
};
enum ei_keymap_source {
/**
* The keymap is the one provided by the client.
*/
EI_KEYMAP_SOURCE_CLIENT = 1,
/**
* The keymap is provided by the server.
*/
EI_KEYMAP_SOURCE_SERVER,
};
enum ei_event_type {
/**
* No event ever has this type, this type exists only as potential
* return value for ei_next_event_type().
*/
EI_EVENT_NONE = 0,
/**
* The server has approved the connection to this client. The client
* may now add devices with ei_device_add(). 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,
/**
* The server has disconnected this client - all resources left to
* reference this server are now obsolete. Once this event has been
* received, the @ref 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 recieved 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 device for this client. The capabilities
* of the device may not match the requested capabilities - it is up
* to the client to verify the minimum required capabilities are
* indeed set.
*
* Where the server refuses to add a specific device or the
* intersection of requested capabilities and allowed capabilities
* is zero, the server sends @ref EI_EVENT_DEVICE_REMOVED instead.
*
* 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 @ref struct ei_device and all its
* associated resources. Any events sent through a removed device
* are discarded.
*/
EI_EVENT_DEVICE_REMOVED,
/**
* Any events sent from this device will be discarded until the next
* resume.
*/
EI_EVENT_DEVICE_SUSPENDED,
/**
* The client may send events.
*/
EI_EVENT_DEVICE_RESUMED,
};
/**
* Create a new ei context.
*/
struct ei *
ei_new(void *user_data);
/**
* Set the name for this client. This is a suggestion to the
* server only and may not be honored.
*
* 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.
*/
int
ei_setup_backend_socket(struct ei *ei, const char *socketpath);
/**
* Initialize the ei context on the given socket
*/
int
ei_setup_backend_fd(struct ei *ei, int fd);
struct ei *
ei_ref(struct ei *ctx);
struct ei *
ei_unref(struct ei *ei);
void
ei_set_user_data(struct ei *ei, void *user_data);
void *
ei_get_user_data(struct ei *ei);
/**
* Connect to the libeis server via the org.freedesktop.portal
*
* @return 0 on success or a negative errno on failure
*/
int
ei_portal_connect(struct ei *ei);
/**
* Connect to the libeis server on the org.freedesktop.Ei bus name.
*
* @return 0 on success or a negative errno on failure
*/
int
ei_dbus_connect(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 dispatchment 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, i.e. 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().
*/
struct ei_event *
ei_peek_event(struct ei *ei);
/**
* Return the type of the next event in the event queue or @ref
* EI_EVENT_NONE if none are available. This function does not remove the
* event from the queue.
*
* This is a convenience function and effectively the same as:
* @code
* struct ei_event *event = ei_peek_event(ei);
* enum ei_event_type type = ei_event_get_type(event);
* ei_event_unref(event);
*
* ... now handle the type ...
*
* @endcode
*/
enum ei_event_type
ei_next_event_type(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);
struct ei_device *
ei_device_ref(struct ei_device *device);
struct ei_device *
ei_device_unref(struct ei_device *device);
/**
* Create a new device. This device is a proxy representing the server's
* device and should be used for initial device configuration. It does not
* represent the server-created device until the @ref EI_EVENT_DEVICE_ADDED
* for this device has been received.
*
* Use the configure API (e.g. ei_device_configure_capability()) to set up
* the device, then call ei_device_add() to request creation of the device
* by the server.
*
* The returned object must be released by the caller with ei_event_unref()
*/
struct ei_device *
ei_device_new(struct ei *ei);
/**
* Set the name for this device. This is a suggestion only, the server may
* the name and assign a different one (or none). Use ei_device_get_name()
* upon receiving @ref EI_EVENT_DEVICE_ADDED to get the server-assigned
* name.
*
* This function has no effect if called after ei_device_add()
*
* libei may quietly ignore names of unreasonable length. This is not
* something a normal caller ever needs to worry about.
*
* @param name A name suggestion for the device
*/
void
ei_device_configure_name(struct ei_device *device, const char *name);
/**
* Enable the given capability on this device. This is a suggestion only,
* the server may ignore this capability.
* Use ei_device_has_capability() upon receiving @ref EI_EVENT_DEVICE_ADDED
* to check for the actual capabilities of the device.
*
* This function has no effect if called after ei_device_add()
*
* @param cap The capability to enable
*/
bool
ei_device_configure_capability(struct ei_device *device,
enum ei_device_capability cap);
/**
* Set the range of the absolute pointer device in logical
* pixels. The allowable range for absolute pointer motion is
* [0, max) for each axis, i.e. zero inclusive, max exclusive. Coordinates
* outside this range may be discarded or clipped silently by the library.
*
* The pointer range is constant. Where the pointer range is no longer
* applicable, the client needs to remove the device and create and add a
* new device with the updated pointer range.
*
* The server may use this in mapping heuristics. For example, a pointer
* device with a pixel range of 1920x1200 **may** be automatically mapped by
* the server to the monitor with this range, or a pointer device with a
* ratio of R **may** be mapped to the monitor with the same ratio. This is
* not a guarantee, the mapping policy is a private implementation detail
* in the server. It is assumed that the client has other communication
* channels (e.g. Wayland) to obtain the pointer range it needs to emulate
* input on a device and channels to notify the server of desired mappings
* (e.g. gsettings).
*
* It is a client bug to send pointer values outside this range.
* It is a client bug to call this function on a device without the @ref
* EI_DEVICE_CAP_POINTER_ABSOLUTE capability.
*
* This function has no effect if called after ei_device_add()
*
* @param width The maximum (exclusive) x value in logical pixels
* @param heigth The maximum (exclusive) y value in logical pixels
*/
void
ei_device_configure_pointer_range(struct ei_device *device,
uint32_t width,
uint32_t height);
/**
* Set the range of the touch device in logical pixels. This
* function is identical to ei_device_configure_pointer_range() but
* configures the touch range instead.
*/
void
ei_device_configure_touch_range(struct ei_device *device,
uint32_t width,
uint32_t height);
/**
* Set the keymap for this device. The keymap for this device is a suggestion to
* the server, the actual keymap used by this device is provided with the
* @ref EI_EVENT_DEVICE_ADDED event. It is the responsibility of the client
* to handle the situation where a specific keymap is requested but the
* server does not allow its use on the device.
*
* Note that keymap handling for individual input devices is largely
* left to private implementation details in the server. For example,
* modifier state or group handling may differ between server
* implementations.
*
* The keymap is constant on the device. To change keymaps, disconnect the
* device and create a new one.
*
* This function has no effect if called after ei_device_add()
*
* @param type the type of the keymap
* @param fd a memmap-able file descriptor to the keymap
*/
void
ei_device_configure_keymap(struct ei_device *device,
enum ei_keymap_type type,
int fd);
/**
* Request that the device be added to the server.
* The server will respond with an @ref EI_EVENT_DEVICE_ADDED or @ref
* EI_EVENT_DEVICE_REMOVED event once the request has been processed.
*
* A client may not send events through this device until it has been added
* by the server.
*/
void
ei_device_add(struct ei_device *device);
/**
* Notify the server that the device is no longer required. The server will
* reply with a @ref EI_EVENT_DEVICE_REMOVED event once the device has been
* removed.
*
* This does not release any resources associated with this device, use
* ei_device_unref() for any references held by the client.
*/
void
ei_device_remove(struct ei_device *device);
/**
* Return the name of this device. The name of the device may change after
* ei_device_add() to the server-assigned name.
*
* The string pointed to 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 @ref EI_EVENT_DEVICE_ADDED.
*
* 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);
uint32_t
ei_device_get_pointer_width(struct ei_device *device);
uint32_t
ei_device_get_pointer_height(struct ei_device *device);
uint32_t
ei_device_get_touch_width(struct ei_device *device);
uint32_t
ei_device_get_touch_height(struct ei_device *device);
/**
* 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.
*
* If this function returns -1, this device does not have
* an individual keymap assigned.
*
* FIXME: the current API makes it impossible to know when the keymap has
* been consumed so the file stays open forever.
*/
int
ei_device_get_keymap(struct ei_device *device);
enum ei_keymap_type
ei_device_get_keymap_type(struct ei_device *device);
/**
* Returns the source for the keymap on this device, if any. This is a
* convenience function for the client to check if its keymap was accepted.
*
* Where ei_device_get_keymap() returns a value other than -1 and this
* function returns @ref EI_KEYMAP_SOURCE_CLIENT, the keymap is the one
* provided with ei_device_configure_keymap().
*
* Where ei_device_get_keymap() returns a value other than -1 and this
* function returns @ref EI_KEYMAP_SOURCE_SERVER, the keymap is one created
* by the server and **not** the one provided with
* ei_device_configure_keymap().
*
* Where ei_device_get_keymap() returns -1, the return value of this
* function is undefined.
*/
enum ei_keymap_source
ei_device_get_keymap_source(struct ei_device *device);
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 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
*
* @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 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.
*
* The server emulates discrete scrolling based on the pixel value,
* do not call ei_device_pointer_scroll_discrete() for the
* same input event.
*
* @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.
*
* The server emulates pixel-based scrolling based on the discrete value,
* do not call ei_device_pointer_scroll() for the
* same input event.
*
* @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 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);
enum ei_event_type
ei_event_get_type(struct ei_event *event);
/**
* Return the device from this event.
*
* 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);