mirror of https://github.com/nirenjan/libx52.git
384 lines
11 KiB
C
384 lines
11 KiB
C
/*
|
|
* Virtual keyboard/mouse interface
|
|
*
|
|
* Copyright (C) 2026 Nirenjan Krishnan (nirenjan@nirenjan.org)
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0-only WITH Classpath-exception-2.0
|
|
*/
|
|
|
|
/**
|
|
* @file vkm.h
|
|
* @brief Functions, structures and enumerations for the virtual
|
|
* keyboard/mouse interface library (VKM).
|
|
*
|
|
* This file contains the type, enum and function prototypes for VKM.
|
|
* These functions allow an application to inject keyboard/mouse events
|
|
* into the host OS, as long as it has the necessary permissions.
|
|
*
|
|
* @author Nirenjan Krishnan (nirenjan@nirenjan.org)
|
|
*/
|
|
#ifndef VKM_H
|
|
#define VKM_H
|
|
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/**
|
|
* @brief Opaque structure used by the VKM framework
|
|
*/
|
|
struct vkm_context;
|
|
|
|
/**
|
|
* @brief Virtual device context structure used by the VKM framework
|
|
*
|
|
* All VKM API functions require the application to pass in a pointer to
|
|
* a valid context structure. A pointer can be obtained by calling
|
|
* \ref vkm_init
|
|
*/
|
|
typedef struct vkm_context vkm_context;
|
|
|
|
/**
|
|
* @brief Return type used by VKM API functions
|
|
*/
|
|
typedef int32_t vkm_result;
|
|
|
|
/**
|
|
* @brief Feature identifiers
|
|
*
|
|
* These are used to check for platform support of the relevant feature.
|
|
*/
|
|
typedef enum {
|
|
/** Check if mouse is supported on this platform */
|
|
VKM_FEAT_MOUSE = (1 << 0),
|
|
|
|
/** Check if US keyboard is supported on this platform */
|
|
VKM_FEAT_KEYBOARD_US = (1 << 1),
|
|
|
|
/* Additional flags may be added in the future */
|
|
} vkm_feature;
|
|
|
|
/**
|
|
* @brief Error code list
|
|
*/
|
|
typedef enum {
|
|
/** No error, indicates success */
|
|
VKM_SUCCESS = 0,
|
|
|
|
/** Unknown error, used as a catch-all error state */
|
|
VKM_ERROR_UNKNOWN,
|
|
|
|
/** Not started, must call vkm_start first */
|
|
VKM_ERROR_NOT_READY,
|
|
|
|
/** Out of memory */
|
|
VKM_ERROR_OUT_OF_MEMORY,
|
|
|
|
/** Invalid parameter(s) */
|
|
VKM_ERROR_INVALID_PARAM,
|
|
|
|
/** Not supported */
|
|
VKM_ERROR_NOT_SUPPORTED,
|
|
|
|
/** Unable to create virtual devices */
|
|
VKM_ERROR_DEV_FAILURE,
|
|
|
|
/** Unable to write event */
|
|
VKM_ERROR_EVENT,
|
|
|
|
/** No state change in the event, please retry */
|
|
VKM_ERROR_NO_CHANGE,
|
|
|
|
/* Maximum error states, do not use in external code*/
|
|
VKM_ERROR_MAX,
|
|
} vkm_error_code;
|
|
|
|
/**
|
|
* @brief Return a short description for a \ref vkm_result / \ref vkm_error_code value
|
|
*
|
|
* The returned pointer refers to static storage and must not be freed. For
|
|
* unrecognized codes, the same static buffer may be overwritten by a later call.
|
|
*
|
|
* When native language support (NLS) is enabled at build time, these messages
|
|
* are translated like \ref libx52_strerror. Bind the \c libx52 text domain and
|
|
* set \c LC_MESSAGES as for other libx52 components.
|
|
*
|
|
* @param[in] code Value returned from a VKM API function
|
|
*
|
|
* @returns Pointer to a NUL-terminated description string
|
|
*/
|
|
const char *vkm_strerror(vkm_result code);
|
|
|
|
/**
|
|
* @brief Option list
|
|
*/
|
|
typedef enum {
|
|
/**
|
|
* @brief Set the high resolution scrolling behavior of the mouse
|
|
*
|
|
* This option must be passed a boolean which lets VKM know whether to
|
|
* enable or disable high resolution scrolling.
|
|
*
|
|
* Defaults to false. When enabled together with \ref vkm_start,
|
|
* \ref vkm_mouse_scroll emits high-resolution REL_*_HI_RES events (120 units
|
|
* per step) in addition to discrete REL_WHEEL / REL_HWHEEL ticks.
|
|
*/
|
|
VKM_OPT_HI_RES_SCROLL,
|
|
|
|
/**
|
|
* @brief Enable or disable horizontal scrolling of the mouse
|
|
*
|
|
* This option must be passed in a boolean which lets VKM know whether to
|
|
* enable or disable horizontal scrolling. If horizontal scrolling is
|
|
* disabled, then any requests to \ref vkm_mouse_scroll with
|
|
* \ref VKM_MOUSE_SCROLL_LEFT or \ref VKM_MOUSE_SCROLL_RIGHT will return
|
|
* \ref VKM_ERROR_INVALID_PARAM.
|
|
*
|
|
* Defaults to false.
|
|
*/
|
|
VKM_OPT_HORIZONTAL_SCROLL,
|
|
|
|
/**
|
|
* @brief Set the virtual device name in the system.
|
|
*
|
|
* This option sets the name of the virtual input device in the system.
|
|
* If not set, the virtual device will have a name determined by the
|
|
* timestamp at which it was initialized.
|
|
*
|
|
* Only applicable on Linux.
|
|
*/
|
|
VKM_OPT_DEVICE_NAME,
|
|
|
|
/* Max number of options, do not use in external code */
|
|
VKM_OPT_MAX
|
|
} vkm_option;
|
|
|
|
/**
|
|
* @brief Button state
|
|
*/
|
|
typedef enum {
|
|
/** Button is released */
|
|
VKM_BUTTON_RELEASED,
|
|
|
|
/** Button is pressed */
|
|
VKM_BUTTON_PRESSED,
|
|
|
|
/* Max number of button states, do not use in external code */
|
|
VKM_BUTTON_STATE_MAX
|
|
} vkm_button_state;
|
|
|
|
/**
|
|
* @brief Mouse button identifiers
|
|
*/
|
|
typedef enum {
|
|
/** Mouse left button */
|
|
VKM_MOUSE_BTN_LEFT,
|
|
|
|
/** Mouse right button */
|
|
VKM_MOUSE_BTN_RIGHT,
|
|
|
|
/** Mouse middle button */
|
|
VKM_MOUSE_BTN_MIDDLE,
|
|
|
|
/* Max number of mouse buttons, do not use in external code */
|
|
VKM_MOUSE_BTN_MAX
|
|
} vkm_mouse_button;
|
|
|
|
/**
|
|
* @brief Scroll directions
|
|
*/
|
|
typedef enum {
|
|
/** Scroll up */
|
|
VKM_MOUSE_SCROLL_UP,
|
|
|
|
/** Scroll down */
|
|
VKM_MOUSE_SCROLL_DOWN,
|
|
|
|
/** Scroll left (horizontal scrolling) */
|
|
VKM_MOUSE_SCROLL_LEFT,
|
|
|
|
/** Scroll right (horizontal scrolling) */
|
|
VKM_MOUSE_SCROLL_RIGHT,
|
|
|
|
/* Maximum number of scroll states, do not use in external code */
|
|
VKM_MOUSE_SCROLL_MAX
|
|
} vkm_mouse_scroll_direction;
|
|
|
|
/**
|
|
* @brief Initialize the VKM library
|
|
*
|
|
* This function initializes the VKM library, sets up any internal data
|
|
* structures to send input events, and returns a \ref vkm_context pointer
|
|
* in the output parameter. All calls to VKM use the returned pointer to
|
|
* inject keyboard/mouse events.
|
|
*
|
|
* @par Example
|
|
* @code
|
|
* vkm_result rc;
|
|
* vkm_context *ctx;
|
|
* rc = vkm_init(&ctx);
|
|
* if (rc != LIBX52_SUCCESS) {
|
|
* // Error handling omitted for brevity
|
|
* }
|
|
* // Save ctx for use later
|
|
* @endcode
|
|
*
|
|
* @param[out] ctx Pointer to a \ref vkm_context *. This function will
|
|
* allocate a context and return the pointer to the context in this variable.
|
|
*
|
|
* @returns \ref vkm_error_code indicating status
|
|
*/
|
|
vkm_result vkm_init(vkm_context **ctx);
|
|
|
|
/**
|
|
* @brief Exit the VKM library and free up any resources used
|
|
*
|
|
* This function releases any resources allocated by \ref vkm_init and
|
|
* terminates the library. Using the freed context now is invalid and can
|
|
* cause errors
|
|
*
|
|
* @param[in] ctx Context pointer
|
|
*/
|
|
void vkm_exit(vkm_context *ctx);
|
|
|
|
/**
|
|
* @brief Start any virtual keyboard/mouse devices on the platform
|
|
*
|
|
* This must be done before injecting any events, and after setting all
|
|
* options through \ref vkm_set_option.
|
|
*
|
|
* @param[in] ctx Context pointer
|
|
*
|
|
* @returns
|
|
* - \ref VKM_SUCCESS on successful start
|
|
* - \ref VKM_ERROR_INVALID_PARAM on bad pointer
|
|
* - \ref VKM_ERROR_UNKNOWN on other errors
|
|
*/
|
|
vkm_result vkm_start(vkm_context *ctx);
|
|
|
|
/**
|
|
* @brief check if VKM is started and ready
|
|
*
|
|
* @param[in] ctx Context pointer
|
|
*
|
|
* @returns boolean indicating if ready or not.
|
|
*/
|
|
bool vkm_is_ready(vkm_context *ctx);
|
|
|
|
/**
|
|
* @brief Check if VKM is supported on this platform
|
|
*
|
|
* On some platforms, there is no support yet for the virtual keyboard/mouse.
|
|
* This function will return a boolean indicating if it is supported or not.
|
|
*
|
|
* @returns boolean indicating support.
|
|
*/
|
|
bool vkm_platform_supported(void);
|
|
|
|
/**
|
|
* @brief Check if a particular feature is enabled on this platform
|
|
*
|
|
* Features may be limited on a per-platform basis.
|
|
*
|
|
* @param[in] feat Feature identifier
|
|
*
|
|
* @returns boolean indicating if feature is supported or not.
|
|
*/
|
|
bool vkm_feature_supported(vkm_feature feat);
|
|
|
|
/**
|
|
* @brief Set an option flag for VKM.
|
|
*
|
|
* Option flags control the behavior of VKM. All options must be set before
|
|
* calling \ref vkm_start.
|
|
*
|
|
* @param[in] ctx Context pointer
|
|
* @param[in] option Which option to set
|
|
* @param[in] ... Any required arguments for the specified option
|
|
*
|
|
* @returns
|
|
* - \ref VKM_SUCCESS on success
|
|
* - \ref VKM_ERROR_INVALID_PARAM if the option or arguments are invalid
|
|
* - \ref VKM_ERROR_NOT_SUPPORTED if the option is valid but not supported on this platform
|
|
*/
|
|
vkm_result vkm_set_option(vkm_context *ctx, vkm_option option, ...);
|
|
|
|
/**
|
|
* @brief Move the mouse by the specified amount
|
|
*
|
|
* The move mouse takes in a delta of x and y coordinates that tell the system
|
|
* to move the mouse by those relative numbers.
|
|
*
|
|
* @param[in] ctx Context pointer
|
|
* @param[in] dx Delta by which to move the mouse in the horizontal axis
|
|
* @param[in] dy Delta by which to move the mouse in the vertical axis
|
|
*
|
|
* @returns
|
|
* - \ref VKM_SUCCESS on successful move
|
|
* - \ref VKM_ERROR_UNKNOWN on a generic error
|
|
* - \ref VKM_ERROR_NOT_SUPPORTED if the mouse move is not supported on this platform
|
|
*/
|
|
vkm_result vkm_mouse_move(vkm_context *ctx, int dx, int dy);
|
|
|
|
/**
|
|
* @brief Click the mouse button
|
|
*
|
|
* Send a mouse button event, this may be either a button down or button up event.
|
|
*
|
|
* @param[in] ctx Context pointer
|
|
* @param[in] button Button identifier
|
|
* @param[in] state Button state (press or release)
|
|
*
|
|
* @returns
|
|
* - \ref VKM_SUCCESS on successful move
|
|
* - \ref VKM_ERROR_UNKNOWN on a generic error
|
|
* - \ref VKM_ERROR_NOT_SUPPORTED if the mouse button click is not supported on this platform
|
|
*/
|
|
vkm_result vkm_mouse_click(vkm_context *ctx, vkm_mouse_button button, vkm_button_state state);
|
|
|
|
/**
|
|
* @brief Scroll the mouse wheel
|
|
*
|
|
* Send a single scroll event to the mouse wheel (one detent in the chosen
|
|
* direction). If \ref VKM_OPT_HI_RES_SCROLL was enabled before \ref vkm_start,
|
|
* also emits REL_WHEEL_HI_RES / REL_HWHEEL_HI_RES using the standard 120
|
|
* units per detent scale before the corresponding discrete REL_WHEEL /
|
|
* REL_HWHEEL event.
|
|
*
|
|
* @param[in] ctx Context pointer
|
|
* @param[in] dir Scroll direction
|
|
*
|
|
* @returns
|
|
* - \ref VKM_SUCCESS on successful move
|
|
* - \ref VKM_ERROR_UNKNOWN on a generic error
|
|
* - \ref VKM_ERROR_INVALID_PARAM if horizontal scrolling is not enabled
|
|
* and \p dir is \ref VKM_MOUSE_SCROLL_LEFT or \ref VKM_MOUSE_SCROLL_RIGHT
|
|
* - \ref VKM_ERROR_NOT_SUPPORTED if the mouse scrolling is not supported on this platform
|
|
*/
|
|
vkm_result vkm_mouse_scroll(vkm_context *ctx, vkm_mouse_scroll_direction dir);
|
|
|
|
/**
|
|
* @brief Send a sync packet to the OS
|
|
*
|
|
* On some platforms, a sync packet is necessary for the previously injected
|
|
* events to actually get reflected in the system. For platforms where this
|
|
* is not needed, this is a noop.
|
|
*
|
|
* @param[in] ctx Context pointer
|
|
*
|
|
* @returns
|
|
* - \ref VKM_SUCCESS on successful move
|
|
* - \ref VKM_ERROR_UNKNOWN on a generic error
|
|
* - \ref VKM_ERROR_INVALID_PARAM if parameters are invalid
|
|
*/
|
|
vkm_result vkm_sync(vkm_context *ctx);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif // !defined VKM_H
|