libei/src/libeis.h
Peter Hutterer d4e274ee6f libeis: flatten the event hierarchy
Same as already done for libei. There's relatively little benefit here since
we won't have a lot of different events and any caller will do the switch
based on the event type anyway. So let's just export a single event type and
have everything contained in that.

Since this required rewriting all getters, let's move the lot to a new file
and streamline things a bit that way.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2020-08-18 16:05:52 +10:00

493 lines
14 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 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);