/* * 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 #include struct eis; struct eis_client; struct eis_device; struct eis_event; enum eis_device_capability { EIS_DEVICE_CAP_POINTER = 1, EIS_DEVICE_CAP_POINTER_ABSOLUTE, EIS_DEVICE_CAP_KEYBOARD, EIS_DEVICE_CAP_TOUCH, }; enum eis_keymap_type { EIS_KEYMAP_TYPE_NONE = 0, EIS_KEYMAP_TYPE_XKB, }; enum eis_event_type { /** * A client has connected. This is the first event from any new * client. * The server is expected to either call eis_event_client_allow() or * eis_event_client_deny(). */ EIS_EVENT_CLIENT_CONNECT = 1, /** * The client has disconnected, any pending requests for this client * should be discarded. */ EIS_EVENT_CLIENT_DISCONNECT, /** * The client requests creation of a device with a given set of * capabilities. A client may create more than one device and more * than one device with the same capabilities. The server may filter * the capabilities or deny them altogether. * */ EIS_EVENT_DEVICE_ADDED, /** * The device created by the client was removed. * * libeis guarantees this event is generated before * @ref EIS_EVENT_CLIENT_DISCONNECT. */ EIS_EVENT_DEVICE_REMOVED, /** * The client requests monitoring of a capability. */ EIS_EVENT_REQUEST_CAPABILITY, /** * The client cancelled the request to monitor that capability. */ EIS_EVENT_CANCEL_CAPABILITY, EIS_EVENT_POINTER_MOTION = 300, EIS_EVENT_POINTER_MOTION_ABSOLUTE, EIS_EVENT_POINTER_BUTTON, EIS_EVENT_POINTER_SCROLL, EIS_EVENT_POINTER_SCROLL_DISCRETE, EIS_EVENT_KEYBOARD_KEY = 400, EIS_EVENT_TOUCH_DOWN = 500, EIS_EVENT_TOUCH_UP, EIS_EVENT_TOUCH_MOTION, }; /** * Create a new libeis context with a refcount of 1. */ struct eis * eis_new(void *user_data); struct eis * eis_ref(struct eis *eis); struct eis * eis_unref(struct eis *eis); void * eis_get_userdata(struct eis *eis); void eis_set_userdata(struct eis *eis, void *userdata); /** * Initialize the context with org.freedesktop.portal integration. */ int eis_portal_init(struct eis *ctx); /** * Initialize the context with a DBus backend on the org.freedesktop.Ei bus * name. */ int eis_dbus_init(struct eis *ctx); /** * Initialize the context with a UNIX socket name. * If the path does not start with / it is relative to $XDG_RUNTIME_DIR. */ int eis_setup_backend_socket(struct eis *ctx, const char *path); /** * Initialize the context that can take pre-configured sockets. */ int eis_setup_backend_fd(struct eis *ctx); /** * Add a new client to a context set up with eis_setup_backend_fd() */ int eis_backend_fd_add_fd(struct eis *ctx, int fd); int eis_get_fd(struct eis *eis); void eis_dispatch(struct eis *eis); /** * Returns the next event in the internal event queue (or NULL) and removes * it from the queue. * * The returned event is refcounted, use eis_event_unref() to drop the * reference. * * You must not call this function while holding a reference to an event * returned by eis_peek_event(). */ struct eis_event * eis_get_event(struct eis *eis); /** * Returns the next event in the internal event queue (or NULL) without * removing that event from the queue, i.e. the next call to eis_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 eis_peek_event() return the same event. * * The returned event is refcounted, use eis_event_unref() to drop the * reference. * * A caller must not call eis_get_event() while holding a ref to an event * returned by eis_peek_event(). */ struct eis_event * eis_peek_event(struct eis *eis); struct eis_event * eis_event_unref(struct eis_event *event); struct eis_client * eis_client_ref(struct eis_client *client); struct eis_client * eis_client_unref(struct eis_client *client); const char * eis_client_get_name(struct eis_client *client); /** * Allow connection from the client. This can only be done once, further * calls to this functions are ignored. * * When receiving an event of type @ref EIS_EVENT_CLIENT_CONNECT, the server * should connect client as soon as possible to allow communication with the * server. If the client is not authorized to talk to the server, call * eis_client_disconnect(). */ void eis_client_connect(struct eis_client *client); /** * Disconnect this client. Once disconnected the client may no longer talk * to this context, all resources associated with this client should be * released. * * It is not necessary to call this function when an @ref * EIS_EVENT_CLIENT_DISCONNECT event is received. */ void eis_client_disconnect(struct eis_client *client); enum eis_event_type eis_event_get_type(struct eis_event *event); struct eis_client * eis_event_get_client(struct eis_event *event); struct eis_client * eis_device_get_client(struct eis_device *device); struct eis_device * eis_device_ref(struct eis_device *device); struct eis_device * eis_device_unref(struct eis_device *device); const char * eis_device_get_name(struct eis_device *device); /** * Set the name of the device. This function has no effect if called after * eis_device_connect() */ const char * eis_device_set_name(struct eis_device *device, const char *name); bool eis_device_has_capability(struct eis_device *device, enum eis_device_capability cap); /** * Disable a capability on the device. This function has no effect if called after * eis_device_connect() */ void eis_device_disable_capability(struct eis_device *device, enum eis_device_capability cap); /** * Connects the device. * * This function should be called in response to an @ref * EIS_EVENT_DEVICE_ADDED if the server accepts the device creation. * Any changes to the device, e.g. eis_device_set_name() and * eis_device_disable_capability() must be performed before connecting the * device. * * Calling eis_device_connect() on a device with all capabilities set to * zero is a bug. * * If the device is rejected, call eis_device_disconnect() instead. * * The device is suspended, use eis_device_resume() to enable events from * the client. */ void eis_device_connect(struct eis_device *device); /** * Disconnect the device. * This does not release any resources associated with this device, use * eils_device_unref() for any references held by the caller. */ void eis_device_disconnect(struct eis_device *device); /** * Notify the client that the device is suspended and that no events * from the client will be processed. * * The library filters events sent by the client **after** the suspend * notification has been processed by the client but this does not affect * events already in transit. In other words, the server may still receive * a number of events from a device after it has been suspended and must * update its internal state accordingly. * * @param device A connected device */ void eis_device_suspend(struct eis_device *device); /** * Notify the client that the capabilities are resumed and that events * from the device will be processed. * * @param device A connected device */ void eis_device_resume(struct eis_device *device); /** * Get the width 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 server bug to call this function on a device without the @ref * EIS_DEVICE_CAP_POINTER_ABSOLUTE capability. * * @return The new width in 1/1000th of logical pixels */ uint32_t eis_device_get_pointer_width(struct eis_device *device); /** * @see eis_device_get_pointer_width */ uint32_t eis_device_get_pointer_height(struct eis_device *device); /** * @see eis_device_get_pointer_width */ uint32_t eis_device_get_touch_width(struct eis_device *device); /** * @see eis_device_get_touch_width */ uint32_t eis_device_get_touch_height(struct eis_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. */ int eis_device_get_keymap(struct eis_device *device); enum eis_keymap_type eis_device_get_keymap_type(struct eis_device *device); /** * Set the keymap on the device. This overwrites the client's choice of * keyboard. Note that **not** calling this function when * eis_device_get_keymap() returns a value other than -1 is equivalent to * accepting the client's choice of keymap. * * If the fd is not -1, it is a memmap-able file descriptor pointing to the * keymap used by the device. This keymap is constant for the lifetime of * the device and assigned to this device individually. Where the keymap has * to change, remove the device and wait for the client to create a new one. * * If the fd is -1, the device does not have an individual keymap assigned. * and keymap type argument is ignored. A server that does not handle * individual client keymaps must call this function with an fd of * -1. * * This function has no effect if called after eis_device_connect() * * @param type the type of the keymap * @param fd a memmap-able file descriptor to the keymap */ void eis_device_keyboard_set_keymap(struct eis_device *device, enum eis_keymap_type type, int fd); /** * 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 eis_device * eis_event_get_device(struct eis_event *event); /** * For an event of type @ref EIS_EVENT_POINTER_MOTION return the x movement * in logical pixels. */ double eis_event_pointer_get_x(struct eis_event *event); /** * For an event of type @ref EIS_EVENT_POINTER_MOTION return the y movement * in logical pixels. */ double eis_event_pointer_get_y(struct eis_event *event); /** * For an event of type @ref EIS_EVENT_POINTER_MOTION_ABSOLUTE return the x * position in logical pixels. */ double eis_event_pointer_get_absolute_x(struct eis_event *event); /** * For an event of type @ref EIS_EVENT_POINTER_MOTION_ABSOLUTE return the y * position in logical pixels. */ double eis_event_pointer_get_absolute_y(struct eis_event *event); /** * For an event of type @ref EIS_EVENT_POINTER_BUTTON return the button * code as defined in linux/input-event-codes.h */ uint32_t eis_event_pointer_get_button(struct eis_event *event); /** * For an event of type @ref EIS_EVENT_POINTER_BUTTON return true if the * event is a button press, false for a release. */ bool eis_event_pointer_get_button_is_press(struct eis_event *event); /** * For an event of type @ref EIS_EVENT_POINTER_SCROLL return the x scroll * distance in logical pixels. */ double eis_event_pointer_get_scroll_x(struct eis_event *event); /** * For an event of type @ref EIS_EVENT_POINTER_SCROLL return the y scroll * distance in logical pixels. */ double eis_event_pointer_get_scroll_y(struct eis_event *event); /** * For an event of type @ref EIS_EVENT_POINTER_SCROLL_DISCRETE return the x * scroll distance in fractions or multiples of 120. */ int32_t eis_event_pointer_get_scroll_discrete_x(struct eis_event *event); /** * For an event of type @ref EIS_EVENT_POINTER_SCROLL_DISCRETE return the y * scroll distance in fractions or multiples of 120. */ int32_t eis_event_pointer_get_scroll_discrete_y(struct eis_event *event); /** * For an event of type @ref EIS_EVENT_KEYBOARD_KEY return the key code (as * defined in include/linux/input-event-codes.h). */ uint32_t eis_event_keyboard_get_key(struct eis_event *event); /** * For an event of type @ref EIS_EVENT_KEYBOARD_KEY return true if the * event is a key down, false for a release. */ bool eis_event_keyboard_get_key_is_press(struct eis_event *event);