1
0
forked from drath/libratbag

Add the outline of an actual API

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
Peter Hutterer
2015-08-13 15:59:32 +10:00
parent 87e18f3170
commit 4e232834b3

View File

@@ -28,6 +28,7 @@
extern "C" {
#endif
#include <stdlib.h>
#include <stdarg.h>
#define LIBRATBAG_ATTRIBUTE_PRINTF(_format, _args) \
@@ -36,15 +37,519 @@ extern "C" {
/**
* @defgroup base Initialization and manipulation of libratbag contexts
* @defgroup device Querying and manipulating devices
*
* Device configuration is managed by "profiles" (see @ref ratbag_profile).
* In the simplest case, a device has a single profile that can be fetched,
* queried and manipulated and then re-applied to the device. Other devices
* may have multiple profiles, each of which can be queried and managed
* independently.
*
* FIXME: Logitech G500s software on the Mac: profiles are DPI+report rate,
* but buttons are independent of the profiles. There are buttons to switch
* the DPI/report rate but not the buttons at the same time.
* Could be handled in software by updating all profiles when a button is
* reassigned but that potentially changes the data from underneath the
* client that already has a profile handle.
* Possible solution: see ratbag_profile_get_button_by_index() vs
* ratbag_get_button_by_index()
*/
/**
* @ingroup base
* @struct ratbag
*
* A ratbag context represents one single device. This struct is
* refcounted, use ratbag_ref() and ratbag_unref().
*
* FIXME: missing: set/get_userdata
*/
struct ratbag;
/**
* @ingroup device
* @struct ratbag_profile
*
* A handle to a profile context on devices with the @ref
* RATBAG_CAP_SWITCHABLE_PROFILE capability.
* This struct is refcounted, use ratbag_profile_ref() and
* ratbag_profile_unref().
*
* FIXME: missing: set/get_userdata
*/
struct ratbag_profile;
/**
* @ingroup device
* @struct ratbag_button
*
* Represents a button on the device.
*
* This struct is refcounted, use ratbag_button_ref() and
* ratbag_button_unref().
*
* FIXME: missing: set/get_userdata
*/
struct ratbag_button;
/**
* @ingroup base
*
* A base handle for accessing devices. This struct is
* refcounted, use ratbag_ref() and ratbag_unref().
* Create a new ratbag context from the given fd. The file descriptor must
* point to a /dev/input/eventX event node and be opened in O_RDWR.
*/
struct ratbag;
struct ratbag*
ratbag_new_from_fd(int fd);
/**
* @ingroup device
*/
enum ratbag_capability {
RATBAG_CAP_NONE = 0,
/**
* The device can change resolution, either software-controlled or
* by a hardware button.
*
* FIXME: what about devices that only have hw buttons? can we
* query that, even if we can't switch it ourselves? Maybe better to
* have a separate cap for that then.
*/
RATBAG_CAP_SWITCHABLE_RESOLUTION,
/**
* The device can switch between hardware profiles.
* A device with this capability can store multiple profiles in the
* hardware and provides the ability to switch between the profiles,
* possibly with a button.
* Devices without this capability will only have a single profile.
*/
RATBAG_CAP_SWITCHABLE_PROFILE,
/**
* The device's button layout can be configured per-profile rather
* than once per device.
* FIXME: how do we handle a single button profile?
*/
RATBAG_CAP_BUTTON_PROFILES,
/**
* The device supports assigning button numbers, key events or key +
* modifier combinations.
*/
RATBAG_CAP_BUTTON_KEY,
/**
* The device supports user-defined key or button sequences.
*/
RATBAG_CAP_BUTTON_MACROS,
};
/**
* @ingroup device
*
* @retval 1 The context has the capability
* @retval 0 The context does not have the capability
*/
int
ratbag_has_capability(const struct ratbag *ratbag, enum ratbag_capability cap);
/**
* @ingroup device
*
* Return the number of profiles supported by this device.
*
* Note that the number of profiles available may be different to the number
* of profiles currently active. This function returns the maximum number of
* profiles available and is static for the lifetime of the device.
*
* A device that does not support profiles in hardware provides a single
* profile that reflects the current settings of the device.
*
* @param ratbag A previously initialized ratbag context
* @return The number of profiles available on this device.
*/
unsigned int
ratbag_get_num_profiles(struct ratbag *ratbag);
/**
* @ingroup device
*
* Return the number of buttons available on this device.
*
* @param ratbag A previously initialized ratbag context
* @return The number of buttons available on this device.
*/
unsigned int
ratbag_get_num_buttons(struct ratbag *ratbag);
/**
* @ingroup device
*
* This function creates if necessary and returns a profile for the given
* index. The index must be less than the number returned by
* ratbag_get_num_profiles().
*
* The profile is refcounted with an initial value of at least 1.
* Use ratbag_profile_unref() to release the profile.
*
* @param ratbag A previously initialized ratbag context
* @param index The index of the profile
*
* @return The profile at the given index, or NULL if the profile does not
* exist.
*
* @see ratbag_get_num_profiles
*/
struct ratbag_profile *
ratbag_get_profile_by_index(struct ratbag *ratbag, unsigned int index);
/**
* @ingroup device
*
* This function returns the currently active profile. Note that some
* devices allow switching profiles with hardware buttons thus making the
* use of this function racy.
*
* The profile is refcounted with an initial value of at least 1.
* Use ratbag_profile_unref() to release the profile.
*
* @param ratbag A previously initialized ratbag context
*
* @return The profile currently active on the device.
*/
struct ratbag_profile *
ratbag_get_active_profile(struct ratbag *ratbag);
/**
* @ingroup device
*
* This function sets the currently active profile to the one provided.
*
* @param ratbag A previously initialized ratbag context
* @param profile The profile to make the active profile.
*
* @return 0 on success or nonzero otherwise.
*/
int
ratbag_set_active_profile(struct ratbag *ratbag,
struct ratbag_profile *profile);
/**
* @ingroup device
*
* @param profile A previously initialized ratbag profile
* @return The current resolution in dots-per-inch.
* @retval 0 The resolution is unknown
*/
int
ratbag_profile_get_resolution_dpi(const struct ratbag_profile *profile);
/**
* @ingroup device
*
* Sets the current resolution to the given dpi.
*
* @note If the profile is the currently active profile, this may change the
* devices' behavior immediately.
*
* @param profile A previously initialized ratbag profile
* @param dpi The new resolution in dots-per-inch
*
* @return 0 on success or -1 on failure
*/
int
ratbag_profile_set_resolution_dpi(struct ratbag_profile *profile, int dpi);
/**
* @ingroup device
*
* @param profile A previously initialized ratbag profile
* @return The current report rate in Hz
* @retval 0 The report rate is unknown
*/
int
ratbag_profile_get_report_rate_hz(const struct ratbag_profile *profile);
/**
* @ingroup device
*
* Sets the current report rate to the given frequency in Hz.
*
* @note If the profile is the currently active profile, this may change the
* devices' behavior immediately.
*
* @param profile A previously initialized ratbag profile
* @param hz The new report rate in Hz
*
* @return 0 on success or -1 on failure
*/
int
ratbag_profile_set_report_rate_hz(struct ratbag_profile *profile, int hz);
/**
* @ingroup device
*
* Return a reference to the button given by the index. The order of the
* buttons is device-specific though indices 0, 1 and 2 should always refer
* to left, middle, right buttons.
*
* The button is refcounted with an initial value of at least 1.
* Use ratbag_button_unref() to release the button.
*
* @note If the device does not have @ref RATBAG_CAP_BUTTON_PROFILES, this
* function always returns NULL. Use ratbag_get_button_by_index() instead.
*
* @param profile A previously initialized ratbag profile
* @param index The index of the button
*
* @return A button context, or NULL if the button does not exist.
*
* @see ratbag_get_num_buttons
*/
struct ratbag_button*
ratbag_profile_get_button_by_index(struct ratbag_profile *profile,
unsigned int index);
/**
* @ingroup device
*
* Return a reference to the button given by the index. The order of the
* buttons is device-specific though indices 0, 1 and 2 should always refer
* to left, middle, right buttons.
*
* The button is refcounted with an initial value of at least 1.
* Use ratbag_button_unref() to release the button.
*
* @note If the device has @ref RATBAG_CAP_BUTTON_PROFILES, this function
* always returns NULL. Use ratbag_profile_get_button_by_index() instead.
*
* @param ratbag A previously initialized ratbag context
* @param index The index of the button
*
* @return A button context, or NULL if the button does not exist.
*
* @see ratbag_get_num_buttons
*/
struct ratbag_button*
ratbag_get_button_by_index(struct ratbag *ratbag, unsigned int index);
enum ratbag_button_type {
RATBAG_BUTTON_TYPE_UNKNOWN = 0,
RATBAG_BUTTON_TYPE_LEFT,
RATBAG_BUTTON_TYPE_MIDDLE,
RATBAG_BUTTON_TYPE_RIGHT,
RATBAG_BUTTON_TYPE_THUMB,
RATBAG_BUTTON_TYPE_THUMB2,
RATBAG_BUTTON_TYPE_RESOLUTION_UP,
RATBAG_BUTTON_TYPE_RESOLUTION_DOWN,
RATBAG_BUTTON_TYPE_WHEEL_LEFT,
RATBAG_BUTTON_TYPE_WHEEL_RIGHT,
RATBAG_BUTTON_TYPE_WHEEL_CLICK, /* FIXME: same as wheel click? */
};
/**
* @ingroup device
*
* Return the type of the physical button. This function is intended to be
* used by configuration tools to provide a generic list of button names or
* handles to configure devices.
*
* FIXME: if we do this with linux/input.h instead, we need to add things like
* BTN_RESOLUTION_UP/DOWN there. But this is supposed to describe the
* physical location of the button, so input.h is not a good match.
*
* @return The type of the button
*/
enum ratbag_button_type
ratbag_button_get_type(struct ratbag_button *button);
/**
* @ingroup device
*
* Return the identifier of the physical button, if stored in the hardware.
*
* FIXME: does this even exist? this function is only here because I though
* of get_type second :)
* FIXME: do we need to handle UTF8 here?
*
* @return The identifier of the button.
*/
const char *
ratbag_button_get_identifier(struct ratbag_button *button);
/**
* @ingroup device
*
* The type assigned to a button.
*/
enum ratbag_button_action_type {
/**
* Button action is unknown
*/
RATBAG_BUTTON_ACTION_TYPE_UNKNOWN = -1,
/**
* Button is disabled
*/
RATBAG_BUTTON_ACTION_TYPE_NONE = 0,
/**
* Button sends numeric button events
*/
RATBAG_BUTTON_ACTION_TYPE_BUTTON,
/**
* Button sends a key or key + modifier combination
*/
RATBAG_BUTTON_ACTION_TYPE_KEY,
/**
* Button sends a user-defined key or button sequence
*/
RATBAG_BUTTON_ACTION_TYPE_MACRO,
};
/**
* @ingroup device
*
* @return The type of the action currently configured for this button
*/
enum ratbag_button_action_type
ratbag_button_get_action_type(struct ratbag_button *button);
/**
* @ingroup device
*
* If the button's action type is not @ref RATBAG_BUTTON_ACTION_TYPE_BUTTON,
* this function returns 0.
*
* @return The button number this button sends, in one of BTN_*, as defined
* in linux/input.h.
* @retval 0 This button is disabled or its action type is not @ref
* RATBAG_BUTTON_ACTION_TYPE_BUTTON.
*/
unsigned int
ratbag_button_get_button(struct ratbag_button *button);
/**
* @ingroup device
*
* @param button A previously initialized ratbag button
* @param btn The button number to assign to this button, one of BTN_* as
* defined in linux/input.h
* @return 0 on success or nonzero otherwise. On success, the button's
* action is set to @ref RATBAG_BUTTON_ACTION_TYPE_BUTTON.
*/
int
ratbag_button_set_button(struct ratbag_button *button,
unsigned int btn);
/**
* @ingroup device
*
* Return the key or button configured for this button.
*
* If the button's action type is not @ref RATBAG_BUTTON_ACTION_TYPE_KEY,
* this function returns 0 and leaves modifiers and sz untouched.
*
* @param button A previously initialized ratbag button
* @param[out] modifiers Will be filled with the modifiers required for this
* action. The modifiers are as defined in linux/input.h.
* @param[in,out] sz Takes the size of the modifiers array and returns the
* number of modifiers filled in. sz may be 0 if no modifiers are required.
*
* @note The caller must ensure that modifiers is large enough to accomodate
* for the key combination.
*
* @return The button number
*/
unsigned int
ratbag_button_get_key(struct ratbag_button *button,
unsigned int *modifiers,
size_t *sz);
/**
* @ingroup device
*
* @param button A previously initialized ratbag button
* @param btn The button number to assign to this button, one of BTN_* as
* defined in linux/input.h
* @param modifiers The modifiers required for this action. The
* modifiers are as defined in linux/input.h, in the order they should be
* pressed.
* @param sz The size of the modifiers array. sz may be 0 if no modifiers
* are required.
*
* @return 0 on success or nonzero otherwise. On success, the button's
* action is set to @ref RATBAG_BUTTON_ACTION_TYPE_KEY.
*/
int
ratbag_button_set_key(struct ratbag_button *button,
unsigned int btn,
unsigned int *modifiers,
size_t sz);
/**
* @ingroup device
*
* FIXME: no idea at this point
*/
unsigned int
ratbag_button_get_macro(struct ratbag_button *button);
/**
* @ingroup device
*
* FIXME: no idea at this point
*/
unsigned int
ratbag_button_set_macro(struct ratbag_button *button);
/**
* @ingroup device
*
* Add a reference to the button. A button is destroyed whenever the
* reference count reaches 0. See @ref ratbag_button_unref.
*
* @param button A previously initialized valid ratbag button
* @return The passed ratbag button
*/
struct ratbag_button *
ratbag_button_ref(struct ratbag_button *button);
/**
* @ingroup device
*
* Dereference the ratbag button. After this, the button may have been
* destroyed, if the last reference was dereferenced. If so, the button is
* invalid and may not be interacted with.
*
* @param button A previously initialized ratbag button
* @return NULL if context was destroyed otherwise the passed button
*/
struct ratbag_button *
ratbag_button_unref(struct ratbag_button *button);
/**
* @ingroup device
*
* Add a reference to the profile. A profile is destroyed whenever the
* reference count reaches 0. See @ref ratbag_profile_unref.
*
* @param profile A previously initialized valid ratbag profile
* @return The passed ratbag profile
*/
struct ratbag_profile *
ratbag_profile_ref(struct ratbag_profile *profile);
/**
* @ingroup device
*
* Dereference the ratbag profile. After this, the profile may have been
* destroyed, if the last reference was dereferenced. If so, the profile is
* invalid and may not be interacted with.
*
* @param profile A previously initialized ratbag profile
* @return NULL if context was destroyed otherwise the passed profile
*/
struct ratbag_profile *
ratbag_profile_unref(struct ratbag_profile *profile);
/**
* @ingroup base