Skip to content

Instantly share code, notes, and snippets.

@dvdhrm
Created May 12, 2013 14:09
Show Gist options
  • Save dvdhrm/5563703 to your computer and use it in GitHub Desktop.
Save dvdhrm/5563703 to your computer and use it in GitHub Desktop.
libinputmapper API proposal
/*
* libinputmapper - Input Mapper Library
*
* Copyright (c) 2012-2013 David Herrmann <dh.herrmann@gmail.com>
*
* 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 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.
*/
/*
* Input Mapper Library
* libinputmapper detects capabilities of linux input devices and provides
* optional mapping tables to overcome device incompatibilities. A huge set
* of global and local configuration options is available to allow fast
* updates of device tables and mappings.
* The main users are graphic-servers, compositors and other applications
* that work directly with linux evdev input devices. libinputmapper does
* not hook into the evdev input event path. Instead, it provides a bunch
* of small helpers that can detect device capabilities, provide fixup
* button mappings or parse global and local user configurations. This gives
* us global input device configuration, while still allowing graphics-servers
* to perform custom input event handling and to apply local configurations.
*
* inmap_context is the main top-level object that is required for all other
* objects. It keeps track of global configuration options, logging helpers
* and more. Multiple contexts can be used independently from each other.
* It reads global configuration options and optionally detects runtime
* configuration changes.
*
* inmap_evdev wraps a single linux evdev input device and provides helpers
* to read or write device attributes and features. It does not handle the
* input event stream. This is still up to the applications. But it can read
* device capabilities and provide fixup mapping tables which then can be
* optionally applied by the application.
*
* inmap_mapping is an opaque mapping table. Each one is for a single device
* and for a single purpose. It does nothing more than mapping linux input
* events via a *_map() function.
*/
#ifndef INMAP_H
#define INMAP_H
#include <inttypes.h>
#include <linux/input.h>
#include <stdbool.h>
#include <stdlib.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @file
* Main libinputmapper API
*/
/**
* @struct inmap_context
* Opaque top level library context object
*
* Context objects contain shared state (eg., include paths, logging
* functions, ..) for all other libinputmapper objects. Objects created on
* different contexts do not share any memory and can be used independently.
* However, a single context object (and all objects created on it) must not
* be used simultaneously from multiple threads without synchronization, if
* not otherwise noted.
* Context objects also manage the system configuration and optionally
* monitor them for runtime modifications.
*/
struct inmap_context;
/**
* @struct inmap_evdev
* Opaque linux event device object
*
* Evdev objects wrap the device-detection of any linux input event device.
* It must be created by the caller either by fd or sysfs-path and then
* performs the device detection. It uses a context object to apply any
* system configuration and then assembles the capabilities of the detected
* device. Depending on which capabilities are requested, it can allocate
* the required mapping tables.
*/
struct inmap_evdev;
/**
* @struct inmap_mapping
* Opaque mapping table for a single device and purpose
*
* After being allocated, a mapping table is constant and serves only to
* map input events to the correct output event. It takes the full linux
* input_event object and performs the transformation inline. So you should
* apply it directly after reading the event from the kernel and before
* processing it.
* Mapping tables are opaque so they can be shared between different devices
* on a single inmap_context. Furthermore, they can be extended to perform
* more complicated mappings than simple KEY_* and BTN_* 1-to-1 mappings.
*/
struct inmap_mapping;
/**
* @enum inmap_capability
* Generic device capabilities
*
* Device capabilities describe what generic interface is provided by the
* detected device. A device can support any combination of them (or none).
* Each interface follows specific rules. If a device does not follow these
* rules, we must provide a mapping table so the correct data is reported.
*
* Capabilities can be added for all kinds of generic devices. However, custom
* devices with model-specific features do not belong here, as their drivers
* need to perform device-detection themselves, anyway.
*
* Furthermore, each capability needs a well-defined protocol. They are mostly
* already provided by the kernel. But there are many devices and drivers
* which provide inconsistent behavior. That's why each capability has to
* be consistent and coherent and misbehaving devices get fixup mappings, if
* we cannot fix it in the kernel device driver itself.
*/
enum inmap_capability {
/**
* @INMAP_CAP_KEYBOARD
* Keyboard interface
*
* The device is a real keyboard that is used for normal input.
* Power-buttons and similar devices which report KEY_* events for
* non-keyboard buttons are not considered a keyboard in this sense.
* Only real keyboards and small extension devices (like external
* NumPads) belong here.
* The defined KEY_* events are not listed here as normally no
* mapping is applied. Libraries like libxkbcommon should be used
* for keyboard handling and mapping.
*/
INMAP_CAP_KEYBOARD = (1 << 0),
/**
* @INMAP_CAP_MOUSE
* Mouse interface
*
* The device is a real mouse with relative motion events. Motion
* is reported as REL_X/Y. Buttons are reported as BTN_0-BTN_9 or
* BTN_LEFT-BTN_TASK.
* Other mouse-like devices (especially those with absolute motion
* events) do not belong here.
*/
INMAP_CAP_MOUSE = (1 << 1),
/**
* @INMAP_CAP_TOUCHPAD
* Touchpad interface
*
* Touchpad devices belong here. But only those that are used as
* pointing devices and are intended to drive a mouse device. That is,
* the input is interpreted as relative motion, even though the
* reported data is normally absolute.
* Hence, touchscreens do not belong here. They are normally
* interpreted as absolute position input.
*
* For multitouch devices, libmtdev defines the protocol.
*
* @TODO define the protocol (see the synaptics descriptions)
*/
INMAP_CAP_TOUCHPAD = (1 << 2),
/**
* @INMAP_CAP_TOUCHSCREEN
* Touchscreen interface
*
* Touchscreens are exactly the same as @INMAP_CAP_TOUCHPAD, but they
* are normally attached to a single monitor and interpreted as
* absolute positioning input.
* Therefore, they are not included in @INMAP_CAP_TOUCHPAD, but are
* a separate group instead. The reported protocol is the same, though.
*
* @sa INMAP_CAP_TOUCHPAD
*/
INMAP_CAP_TOUCHSCREEN = (1 << 3),
/**
* @INMAP_CAP_ACCELEROMETER
* Accelerometer interface
*
* Accelerometer devices report linear acceleration data as ABS_X/Y/Z
* and rotational acceleration as ABS_RX/Y/Z.
*
* @TODO this collides with ABS_X/Y of absolute pointing devices
* introduce ABS_ACCELX/Y/Z
*/
INMAP_CAP_ACCELEROMETER = (1 << 4),
/**
* @INMAP_CAP_GAMEPAD
* Gamepad interface
*
* All standard gamepad devices belong here.
*
* @TODO define gamepad mapping (see linux-input@vger discussion)
*/
INMAP_CAP_GAMEPAD = (1 << 5),
/**
* @INMAP_CAP_JOYSTICK
* Joystick interface
*
* All standard joystick devices belong here.
*
* @TODO define joystick mapping
*/
INMAP_CAP_JOYSTICK = (1 << 6),
};
/**
* @defgroup context Library Context
* Managing library contexts
*
* A context object contains all top-level information. It can be shared
* between multiple device objects and provides global infrastructure to them.
*
* @{
*/
/**
* @enum inmap_context_flags
* Context creation and operation flags
*
* Different flags that control how a context is created and how it behaves.
*
* @memberof inmap_context
* @sa inmap_context_new()
*/
enum inmap_context_flags {
/**
* @INMAP_CONTEXT_IGNORE_ENVIRONMENT
* Ignore environment variables
*
* The context object will not use any environment variables as
* default values if they are not explicitly set.
*
* @memberof inmap_context
*/
INMAP_CONTEXT_IGNORE_ENVIRONMENT = (1 << 0),
/**
* @INMAP_CONTEXT_MONITOR_CONF_FILES
* Monitor configuration files
*
* If set, the context will monitor configuration files for runtime
* modifications. This allows adapting to changes without restarting
* the application.
* Changes are not automatically applied. The application has to
* react to these events and retrigger device detection for all
* active devices.
*
* @memberof inmap_context
* @sa inmap_context_dispatch()
*/
INMAP_CONTEXT_MONITOR_CONF_FILES = (1 << 1),
/**
* @INMAP_CONTEXT_NO_DEFAULT_CONF
* Skip default configuration
*
* If set, the global default configuration is not parsed.
*
* @memberof inmap_context
*/
INMAP_CONTEXT_NO_DEFAULT_CONF = (1 << 2),
};
/**
* Create new context
*
* @param[out] out Pointer to the new context is stored here
* @param[in] caps Capabilities that are used with this context
* @param[in] flags Optional flags or 0
*
* Create a new context and store a pointer to it in @out. You must specify
* all capabilities that you want to use with this context in @caps. This
* causes the context to ignore and skip all configuration options for
* other capabilities to save memory.
* You cannot modify the capabilities afterwards.
*
* You can change the behavior of the context with additional flags. See the
* @inmap_context_flags for a description of flags.
*
* Context objects are reference counted. Initial ref-count is 1. You can
* modify it via @inmap_context_ref() and @inmap_context_unref().
*
* @returns 0 on success, negative error code on failure.
*
* @memberof inmap_context
* @sa inmap_context_flags
* @sa inmap_context_ref()
* @sa inmap_context_unref()
*/
int inmap_context_new(struct inmap_context **out,
enum inmap_capability caps,
enum inmap_context_flags flags);
/**
* Increase context ref-count
*
* @param[in] ctx Valid context object or NULL
*
* Increase ref-count of the given context by 1. If NULL is passed as
* context, then nothing is done.
*
* @memberof inmap_context
* @sa inmap_context_new()
* @sa inmap_context_unref()
*/
void inmap_context_ref(struct inmap_context *ctx);
/**
* Decrease context ref-count
*
* @param[in] ctx Valid context object or NULL
*
* Decrease ref-count of @ctx by 1. You must not access @ctx afterwards if
* you do not own another reference. This function destroys @ctx if the
* ref-count drops to 0.
* If @ctx is NULL, nothing is done.
*
* @memberof inmap_context
* @sa inmap_context_new()
* @sa inmap_context_ref()
*/
void inmap_context_unref(struct inmap_context *ctx);
/**
* Set user-data
*
* @param[in] ctx Valid context object
* @param[in] user_data User-data pointer
*
* Set a user-controlled pointer field in @ctx. This allows the user to
* associate any data with this context. It can be retrieved via
* @inmap_context_get_user_data() again.
* This field is set to NULL during context initialization and then never
* modified by the library code itself. It is a fully user controlled field.
*
* @memberof inmap_context
* @sa inmap_context_get_user_data()
*/
void inmap_context_set_user_data(struct inmap_context *ctx, void *user_data);
/**
* Get user-data
*
* @param[in] ctx Valid context object
*
* @returns user-data field previously set via @inmap_context_set_user_data()
*
* @memberof inmap_context
* @sa inmap_context_set_user_data()
*/
void *inmap_context_get_user_data(struct inmap_context *ctx);
/**
* @enum inmap_context_log_level
* Log-level of context objects
*
* The log-levels are exactly the same as the kernel log-levels.
*
* @memberof inmap_context
*/
enum inmap_context_log_level {
INMAP_CONTEXT_LOG_LEVEL_EMERGENCY,
INMAP_CONTEXT_LOG_LEVEL_ALERT,
INMAP_CONTEXT_LOG_LEVEL_CRITICAL,
INMAP_CONTEXT_LOG_LEVEL_ERROR,
INMAP_CONTEXT_LOG_LEVEL_WARNING,
INMAP_CONTEXT_LOG_LEVEL_NOTICE,
INMAP_CONTEXT_LOG_LEVEL_INFO,
INMAP_CONTEXT_LOG_LEVEL_DEBUG,
};
/**
* Set log level
*
* @param[in] ctx Valid context object
* @param[in] level New log level
*
* Change the default log-level to @level. Only log-messages with equal or
* higher priority are passed to the log-function. Default log-level is
* @INMAP_CONTEXT_LOG_LEVEL_ERROR.
*
* During context creation, the log-level is set to the value of the
* environment variable INMAP_LOG_LEVEL if set. It may be specified as a
* number or name.
*
* @memberof inmap_context
* @sa inmap_context_log_level
* @sa inmap_context_get_log_level()
* @sa inmap_context_set_log_fn()
*/
void inmap_context_set_log_level(struct inmap_context *ctx, unsigned int level);
/**
* Get log level
*
* @param[in] ctx Valid context object
*
* @returns log-level previously set via inmap_context_log_leve()
*
* @memberof inmap_context
* @sa inmap_context_log_level
* @sa inmap_context_set_log_level()
* @sa inmap_context_set_log_fn()
*/
unsigned int inmap_context_get_log_level(struct inmap_context *ctx);
/**
* Set log function
*
* @param[in] ctx Valid context object
* @param[in] log_fn Log-function or NULL
*
* Change the default log-function to @log_fn. If @log_fn is NULL, no
* logging will be done.
* This log-function is called for every log-message that has a higher
* or equal priority as the currently set log-level.
*
* The first argument is the context object, followed by the user_data field
* which can also be retrieved via inmap_context_get_user_data(). Then the
* log-level of the message, the file/line/function information where the
* message originated and the format/args combination with the actual
* log message.
*
* @memberof inmap_context
* @sa inmap_context_log_level
* @sa inmap_context_set_log_level()
*/
void inmap_context_set_log_fn(struct inmap_context *ctx,
void (*log_fn) (struct inmap_context *ctx,
void *user_data,
unsigned int level,
const char *file,
int line,
const char *fn,
const char *format,
va_list args));
/**
* Return the context file-descriptor
*
* @param[in] ctx Valid context
*
* If the context was created with the @INMAP_CONTEXT_MONITOR_CONF_FILES
* flag, it will allocate kernel resources to monitor configuration files.
* These report changes via file-descriptors. You can track these via this
* function.
* Whenever the file-descriptor is readable, you must call
* inmap_context_dispatch() to let the library handle the events.
*
* If you didn't use config-file tracking, this will always return -1 and
* there is no reason to call this or inmap_context_dispatch().
*
* @returns file-descriptor or -1 if not used
*
* @memberof inmap_context
* @sa inmap_context_dispatch()
*/
int inmap_context_get_fd(struct inmap_context *ctx);
/**
* @enum inmap_context_dispatch_event
* Dispatch events
*
* Events that are handled by the context object and returned to the caller
* so they can react to it.
*
* @memberof inmap_context
* @sa inmap_context_dispatch()
*/
enum inmap_context_dispatch_event {
/**
* @INMAP_CONTEXT_CONF_CHANGED
* Configuration changed
*
* This is returned whenever a configuration file was modified and
* @INMAP_CONTEXT_MONITOR_CONF_FILES was used. The library itself
* does not react to this event, so you need to reread the
* configuration files yourself via inmap_context_conf_refresh() and
* recreate the inmap_evdev objects that might have changed.
*
* @memberof inmap_context
*/
INMAP_CONTEXT_CONF_CHANGED = (1 << 0),
};
/**
* Dispatch outstanding work
*
* @param[in] ctx Valid context object
*
* Whenever the internal file-descriptor of this context is readable (see
* also @inmap_context_get_fd()), you must call this function to dispatch
* any outstanding work.
* This is currently only used for the @INMAP_CONTEXT_MONITOR_CONF_FILES
* implementation. If @inmap_context_get_fd() does not return a valid
* file-descriptor, you can skip calling this function.
* All events that were detected are returned as bitmask so the caller can
* react on them.
*
* @returns @inmap_context_dispatch_event event-flags on success, negative
* error code on failure.
*
* @memberof inmap_context
* @sa inmap_context_get_fd()
*/
int inmap_context_dispatch(struct inmap_context *ctx);
/** @} */
/**
* @defgroup context-conf Library Context Configuration Files
* Managing configuration files
*
* Users can supply configuration files to extend the detection logic
* without modifying the source code. Default configurations are always
* used (except if INMAP_CONTEXT_NO_DEFAULT_CONF is used) but you can
* supply additional files for local configurations.
*
* If a configuration file is given by path or filename it can be monitored
* for runtime modifications if INMAP_CONTEXT_MONITOR_CONF_FILES is used.
* Configurations given via memory cannot be monitored.
*
* Configuration files contain matching-rules and filenames of
* device-configuration-files to apply for matched devices. So the main
* configuration file simply contains a list of names and IDs for devices
* that need special fixups.
*
* Syntax of configuration files is ini-style like this:
* @code
* [match <optional-name>]
* name = *name*wild*mask
* bus = <bus-name>,<another-bus-name>,..
* vid = <vendor-id>,<another-vendor-id>,..
* pid = <product-id>,..
* rules = <relative-path-to-device-conf>
* @endcode
* You can put as many of these [match] groups into a configuration file. All
* fields except for "rules" are optional. If a device matches a [match] block,
* the rules that are found in "rules" are applied to the device. Multiple
* blocks may match and are applied in the order as specified.
* Fields are matched with a logical "AND". So if "bus" and "name" are
* specified, the device must match both. Multiple entries in the same
* category are matched with a logical "OR". So if multiple "vid" entries
* are given, only one of them must match.
* Unknown rules are silently ignored. This allows to easily extend this file
* with further entries in the future.
*
* Rule-files contain rules that are to be applied to a device. Unknown entries
* are silently ignored. This allows to store additional information in
* these files for other libraries to use.
* Supported entries are:
* @code
* [capabilities <optional-name>]
* add = <cap1>,<cap2>,..
* remove = <cap1>,<cap2>,..
* set = <cap1>,<cap2>,..
* @endcode
* This overwrites the heuristics used to detect device capabilities. "add"
* causes the library to add the given capabilities to the auto-detected caps.
* "remove" causes the library to remove them and "set" overwrites all of
* them. "set" is mutually exclusive to "add" and "remove", obviously.
* @code
* [mapping <optional-name>]
* map = <type>:<code> => [<type>:]<code>,
* [<type>:]<code> => [<type>:]<code>,
* ..
* @endcode
* This specifies a simple mapping table. <type> must only be specified once
* and will automatically be kept for following entries that have no explicit
* <type> prefix.
* inmap_evdev will create a mapping table from these rules and map the
* specified type+code combinations to the target type+code. The "value"
* field cannot be modified for now.
*
* @{
*/
/** configuration file parser flags */
enum inmap_context_conf_flags {
/** Allow any file type, not only regular files. */
INMAP_CONTEXT_CONF_ALLOW_ANY = (1 << 0),
/** Do not monitor this file. */
INMAP_CONTEXT_CONF_DONT_MONITOR = (1 << 1),
};
/**
* Add configuration file from memory buffer
*
* @param[in] ctx Valid context object
* @param[in] buffer Pointer to the memory buffer to read from. Does not
* have to be zero terminated.
* @param[in] length Length of @buffer not including any possible
* terminating zero character.
* @param[in] flags Optional flags for the parser or 0.
*
* Parses the buffer given in @buffer as configuration file and updates the
* context accordingly.
*
* @INMAP_CONTEXT_CONF_ALLOW_ANY has no effect if set and is ignored.
*
* Obviously, @INMAP_CONTEXT_MONITOR_CONF_FILES has no effect on
* configurations that are parsed with this function. If you want to track
* configuration files for changes, you must use
* @inmap_context_conf_add_from_path.
* @INMAP_CONTEXT_CONF_DONT_MONITOR is ignored, too.
*
* @returns 0 on success, negative error code on failure.
*
* @memberof inmap_context
* @sa inmap_context_conf_add_from_path()
*/
int inmap_context_conf_add_from_buffer(struct inmap_context *ctx,
const void *buffer, size_t length,
enum inmap_context_conf_flags flags);
/**
* Add configuration file from file path
*
* @param[in] ctx Valid context object
* @param[in] path Path to the configuration file. Must be a zero-
* terminated string.
*
* Parses the configuration file at @path and updates the context
* accordingly.
*
* @returns 0 on success, negative error code on failure.
*
* @memberof inmap_context
* @sa inmap_context_conf_add_from_buffer()
*/
int inmap_context_conf_add_from_path(struct inmap_context *ctx,
const char *path);
/**
* Parse configuration files
*
* @param[in] ctx Valid context object
*
* This resets the configuration-file cache and re-reads all files. Use
* this whenever a configuration file changed. You also must call this
* after creating the context to read the default configurations.
*
* Files added via @inmap_context_conf_add_from_path() are automatically
* parsed while added, but can be re-parsed by calling this function.
*
* @returns 0 on success, negative error code on failure
*
* @memberof inmap_context
*/
int inmap_context_conf_parse(struct inmap_context *ctx);
/** @} */
/**
* @defgroup evdev Evdev input devices
* Managing evdev input device detection and rules
*
* @{
*/
/**
* Create new evdev device from fd
*
* @param[in] ctx Valid context object
* @param[out] out Pointer to new evdev object is stored here
* @param[in] fd File-descriptor of input evdev device
*
* Create a new inmap_evdev context and retrieve information via a normal
* file-descriptor. The file-descriptor is not kept by this function but
* only used during initialization to retrieve device-name and so on.
*
* The new evdev object will be associated with the given context. All
* matching rules are immediately applied and device detection will be
* performed.
*
* inmap_evdev objects are ref-counted. Initial ref-count will be 1.
*
* @returns 0 on success, negative error code on failure
*
* @memberof inmap_evdev
*/
int inmap_evdev_new_from_fd(struct inmap_context *ctx,
struct inmap_evdev **out,
int fd);
/**
* Create new evdev device from sysfs-path
*
* @param[in] ctx Valid context object
* @param[out] out Pointer to new evdev object is stored here
* @param[in] path Path to sysfs-device directory
*
* Create a new inmap_evdev context and retrieve information via sysfs. No
* file-descriptor to the event-device is needed.
* The sysfs path @path normally points to a directory like
* /sys/class/input/input<num>/
* Note that this must be the input-device directory, not the event/evdev
* device directory!
*
* The new evdev object will be associated with the given context. All
* matching rules are immediately applied and device detection will be
* performed.
*
* inmap_evdev objects are ref-counted. Initial ref-count will be 1.
*
* @returns 0 on success, negative error code on failure
*
* @memberof inmap_evdev
*/
int inmap_evdev_new_from_syspath(struct inmap_context *ctx,
struct inmap_evdev **out,
const char *path);
/**
* Increase inmap_evdev ref-count
*
* @param[in] evdev Valid evdev object, or NULL
*
* Increase ref-count of @evdev by 1. Does nothing if @evdev is NULL.
*
* @memberof inmap_evdev
*/
void inmap_evdev_ref(struct inmap_evdev *evdev);
/**
* Decrease inmap_evdev ref-count
*
* @param[in] evdev Valid evdev object, or NULL
*
* Decrease ref-count of @evdev by 1. This destroys the object immediately,
* iff the ref-count drops to 0. Does nothing if @evdev is NULL.
*
* @memberof inmap_evdev
*/
void inmap_evdev_unref(struct inmap_evdev *evdev);
/**
* Get device capabilities
*
* @param[in] evdev Valid evdev object
*
* Return a bitmask of capabilities of the given device. You can use these
* to decide which device drivers to load on this input device.
*
* @returns bitmask of capabilities
*
* @memberof inmap_evdev
*/
enum inmap_capabilities inmap_evdev_get_capabilities(struct inmap_evdev *evdev);
/**
* Create mapping table
*
* @param[in] evdev Valid evdev object
* @param[out] out Pointer to new mapping table is stored here
* @param[in] caps Capability bitmask
*
* Create new mapping tables for the capabilities given in @caps. The new
* table is stored in @out. If no table is available, @out will be NULL
* afterwards.
* This combines all required tables for the given capabilities in one
* single mapping-table. You should apply these mappings before processing
* the read input events.
*
* @returns 0 on success, negative error code on failure
*
* @memberof inmap_evdev
*/
int inmap_evdev_get_mapping(struct inmap_evdev *evdev,
struct inmap_mapping **out,
unsigned int caps);
/** @} */
/**
* @defgroup mapping Event mapping
* Mapping linux input-events
*
* @{
*/
/**
* Increase ref-count of mapping table
*
* @param[in] map Valid mapping table, or NULL
*
* Increase ref-count of @map by 1. Does nothing if @map is NULL.
*
* @memberof inmap_mapping
*/
void inmap_mapping_ref(struct inmap_mapping *map);
/**
* Decrease ref-count of mapping table
*
* @param[in] map Valid mapping table, or NULL
*
* Decrease ref-count of @map by 1. Destroys the object iff the ref-count
* drops to 0. Does nothing if @map is NULL.
*
* @memberof inmap_mapping
*/
void inmap_mapping_unref(struct inmap_mapping *map);
/**
* Map linux input-event
*
* @param[in] map Valid mapping table, or NULL
* @param[in,out] event Linux input event
*
* Map the input-event in @event according to the rules in @map. If @map is
* NULL no mapping is applied.
* The mapping is performed inline, so @event will be modified by this
* function.
*
* @memberof inmap_mapping
*/
void inmap_mapping_map(struct inmap_mapping *map,
struct input_event *event);
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* INMAP_H */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment