libei/src/libei.h
Peter Hutterer 2e4ce7008b libei: implement ei_peek_event()
At least for the test suite, I'll need something that allows me to look at an
event without removing it from the event queue. Just the event type isn't
enough, I need things like "what are the caps on the device". Simplest way to
allow this is a peek function that doesn't remove the event from the queue.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2020-08-06 15:19:03 +10:00

539 lines
16 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
#include <stdbool.h>
#include <stdint.h>
struct ei;
struct ei_device;
struct ei_event;
struct ei_event_client;
struct ei_event_pointer;
struct ei_event_keyboard;
struct ei_event_touch;
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.
*/
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.
*/
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.
*/
EI_EVENT_DEVICE_ADDED,
/**
* The server has removed a device belonging to this client.
*/
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,
};
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.
*/
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. Cal
* libei_dispatch() if any events become available on this fd.
*/
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.
*/
enum ei_event_type
ei_next_event_type(struct ei *ei);
/**
* Release resources associated with this event. This function always
* returns NULL.
*
* Events can only be unref'd by the caller. They should be considered
* transient data and not be held longer than required.
*/
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 1/1000th of a logical
* pixel. 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 values are in 1/1000th of logical pixels, i.e. the value 100 000
* refers to 100 pixels.
*
* 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 1/1000th of a pixel
* @param heigth The maximum (exclusive) y value in 1/1000th of a pixel
*/
void
ei_device_configure_pointer_range(struct ei_device *device,
uint32_t width,
uint32_t height);
/**
* Set the range of the touch device in 1/1000th of a 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.
*/
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 the device (if any) or NULL
*/
const char *
ei_device_get_name(struct ei_device *device);
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 1/1000th of a logical pixel
* @param y The y movement in 1/1000th of a logical pixel
*/
void
ei_device_pointer_motion(struct ei_device *device, int32_t x, int32_t 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 1/1000th of a logical pixel
* @param y The y position in 1/1000th of a logical pixel
*/
void
ei_device_pointer_motion_absolute(struct ei_device *device,
uint32_t x, uint32_t 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 1/1000th of a logical pixel
* @param y The y scroll distance in 1/1000th of a logical pixel
*
* @see ei_device_pointer_scroll_discrete
*/
void
ei_device_pointer_scroll(struct ei_device *device, int32_t x, int32_t 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_pointer_get_time(struct ei_event_pointer *event);
/**
* @return the event time in microseconds
*/
uint64_t
ei_event_keyboard_get_time(struct ei_event_keyboard *event);
/**
* @return the event time in microseconds
*/
uint64_t
ei_event_touch_get_time(struct ei_event_touch *event);