Revamp button action handling

One giant commit, but I didn't know how to split this up easier. The problem
is a misunderstanding in what the button type is and the code that built on
that misunderstanding, requiring a lot of interdependent parts to be updated
at once.

The button _type_ is the physical description of the button.
The button _action type_ is what will happen when you hit the buttons.

The type is read-only, since we're not dealing with mr potato head here.
The action is adjustible and we now support buttons, keys and special
in-hardware actions (e.g. dpi changes). A few FIXMEs still in place, e.g. we
don't handle modifiers with keys.

For buttons we just take numerical button numbers. i.e. we can map a button to
button 4, which will result in BTN_SIDE, and eventually logical button 8 in X.
For keys we take KEY_FOO, since eventually we want this to come out as that
(could do this for button as well I guess). Modifiers are currently ignored.
For special actions we have a enum of actions we support.

The button type enum is thus reduced a lot, and everything needs to be
switched.

This breaks ratbag-command change-button, will be fixed later since it's
misdesigned as it is anyway.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
Peter Hutterer
2015-08-26 16:00:26 +10:00
parent ec9456c940
commit 7db22756b7
10 changed files with 305 additions and 196 deletions

View File

@@ -100,92 +100,70 @@ print_key(uint8_t key)
return "UNKNOWN";
}
static enum ratbag_button_action_type
etekcity_raw_to_action(uint8_t data, enum ratbag_button_type button_type)
{
if (button_type == RATBAG_BUTTON_TYPE_UNKNOWN)
return RATBAG_BUTTON_ACTION_TYPE_NONE;
return RATBAG_BUTTON_ACTION_TYPE_BUTTON;
}
struct etekcity_button_mapping {
uint8_t raw;
enum ratbag_button_type type;
struct ratbag_button_action action;
};
static struct etekcity_button_mapping etekcity_button_mapping[] = {
{ 1, RATBAG_BUTTON_TYPE_LEFT },
{ 2, RATBAG_BUTTON_TYPE_RIGHT },
{ 3, RATBAG_BUTTON_TYPE_MIDDLE },
// { 4, "2 x BTN_LEFT" },
{ 6, RATBAG_BUTTON_TYPE_NONE },
{ 0, RATBAG_BUTTON_TYPE_NONE },
{ 7, RATBAG_BUTTON_TYPE_EXTRA },
{ 8, RATBAG_BUTTON_TYPE_SIDE },
{ 9, RATBAG_BUTTON_TYPE_WHEEL_UP },
{ 10, RATBAG_BUTTON_TYPE_WHEEL_DOWN },
{ 11, RATBAG_BUTTON_TYPE_WHEEL_LEFT },
{ 12, RATBAG_BUTTON_TYPE_WHEEL_RIGHT },
/* DPI switch */
{ 13, RATBAG_BUTTON_TYPE_RESOLUTION_CYCLE_UP },
{ 14, RATBAG_BUTTON_TYPE_RESOLUTION_UP },
{ 15, RATBAG_BUTTON_TYPE_RESOLUTION_DOWN },
/* Macro */
{ 16, RATBAG_BUTTON_TYPE_MACRO },
/* Profile */
{ 18, RATBAG_BUTTON_TYPE_PROFILE_CYCLE_UP },
{ 19, RATBAG_BUTTON_TYPE_PROFILE_UP },
{ 20, RATBAG_BUTTON_TYPE_PROFILE_DOWN },
// { 21, "HOLD BTN_LEFT ON/OFF" },
/* multimedia */
{ 25, RATBAG_BUTTON_TYPE_KEY_CONFIG },
{ 26, RATBAG_BUTTON_TYPE_KEY_PREVIOUSSONG },
{ 27, RATBAG_BUTTON_TYPE_KEY_NEXTSONG },
{ 28, RATBAG_BUTTON_TYPE_KEY_PLAYPAUSE },
{ 29, RATBAG_BUTTON_TYPE_KEY_STOPCD },
{ 30, RATBAG_BUTTON_TYPE_KEY_MUTE },
{ 31, RATBAG_BUTTON_TYPE_KEY_VOLUMEUP },
{ 32, RATBAG_BUTTON_TYPE_KEY_VOLUMEDOWN },
/* windows */
{ 33, RATBAG_BUTTON_TYPE_KEY_CALC },
{ 34, RATBAG_BUTTON_TYPE_KEY_MAIL },
{ 35, RATBAG_BUTTON_TYPE_KEY_BOOKMARKS },
{ 36, RATBAG_BUTTON_TYPE_KEY_FORWARD },
{ 37, RATBAG_BUTTON_TYPE_KEY_BACK },
{ 38, RATBAG_BUTTON_TYPE_KEY_STOP },
{ 39, RATBAG_BUTTON_TYPE_KEY_FILE },
{ 40, RATBAG_BUTTON_TYPE_KEY_REFRESH },
{ 41, RATBAG_BUTTON_TYPE_KEY_HOMEPAGE },
{ 42, RATBAG_BUTTON_TYPE_KEY_SEARCH },
{ 1, BUTTON_ACTION_BUTTON(1) },
{ 2, BUTTON_ACTION_BUTTON(2) },
{ 3, BUTTON_ACTION_BUTTON(3) },
{ 4, BUTTON_ACTION_SPECIAL(RATBAG_BUTTON_ACTION_SPECIAL_DOUBLECLICK) },
{ 6, BUTTON_ACTION_NONE },
{ 7, BUTTON_ACTION_BUTTON(4) },
{ 8, BUTTON_ACTION_BUTTON(5) },
{ 9, BUTTON_ACTION_SPECIAL(RATBAG_BUTTON_ACTION_SPECIAL_WHEEL_UP) },
{ 10, BUTTON_ACTION_SPECIAL(RATBAG_BUTTON_ACTION_SPECIAL_WHEEL_DOWN) },
{ 11, BUTTON_ACTION_SPECIAL(RATBAG_BUTTON_ACTION_SPECIAL_WHEEL_LEFT) },
{ 12, BUTTON_ACTION_SPECIAL(RATBAG_BUTTON_ACTION_SPECIAL_WHEEL_RIGHT) },
{ 13, BUTTON_ACTION_SPECIAL(RATBAG_BUTTON_ACTION_SPECIAL_RESOLUTION_CYCLE_UP) },
{ 14, BUTTON_ACTION_SPECIAL(RATBAG_BUTTON_ACTION_SPECIAL_RESOLUTION_UP) },
{ 15, BUTTON_ACTION_SPECIAL(RATBAG_BUTTON_ACTION_SPECIAL_RESOLUTION_DOWN) },
{ 16, BUTTON_ACTION_NONE },
{ 17, BUTTON_ACTION_SPECIAL(RATBAG_BUTTON_ACTION_SPECIAL_PROFILE_CYCLE_UP) },
{ 18, BUTTON_ACTION_SPECIAL(RATBAG_BUTTON_ACTION_SPECIAL_PROFILE_UP) },
{ 19, BUTTON_ACTION_SPECIAL(RATBAG_BUTTON_ACTION_SPECIAL_PROFILE_DOWN) },
{ 25, BUTTON_ACTION_KEY(KEY_CONFIG) },
{ 26, BUTTON_ACTION_KEY(KEY_PREVIOUSSONG) },
{ 27, BUTTON_ACTION_KEY(KEY_NEXTSONG) },
{ 28, BUTTON_ACTION_KEY(KEY_PLAYPAUSE) },
{ 29, BUTTON_ACTION_KEY(KEY_STOPCD) },
{ 30, BUTTON_ACTION_KEY(KEY_MUTE) },
{ 31, BUTTON_ACTION_KEY(KEY_VOLUMEUP) },
{ 32, BUTTON_ACTION_KEY(KEY_VOLUMEDOWN) },
{ 33, BUTTON_ACTION_KEY(KEY_CALC) },
{ 34, BUTTON_ACTION_KEY(KEY_MAIL) },
{ 35, BUTTON_ACTION_KEY(KEY_BOOKMARKS) },
{ 36, BUTTON_ACTION_KEY(KEY_FORWARD) },
{ 37, BUTTON_ACTION_KEY(KEY_BACK) },
{ 38, BUTTON_ACTION_KEY(KEY_STOP) },
{ 39, BUTTON_ACTION_KEY(KEY_FILE) },
{ 40, BUTTON_ACTION_KEY(KEY_REFRESH) },
{ 41, BUTTON_ACTION_KEY(KEY_HOMEPAGE) },
{ 42, BUTTON_ACTION_KEY(KEY_SEARCH) },
};
static enum ratbag_button_type
etekcity_raw_to_button_type(uint8_t data)
static const struct ratbag_button_action*
etekcity_raw_to_button_action(uint8_t data)
{
struct etekcity_button_mapping *mapping;
ARRAY_FOR_EACH(etekcity_button_mapping, mapping) {
if (mapping->raw == data)
return mapping->type;
return &mapping->action;
}
return RATBAG_BUTTON_TYPE_UNKNOWN;
return NULL;
}
static uint8_t
etekcity_button_type_to_raw(enum ratbag_button_type type)
etekcity_button_action_to_raw(const struct ratbag_button_action *action)
{
struct etekcity_button_mapping *mapping;
ARRAY_FOR_EACH(etekcity_button_mapping, mapping) {
if (mapping->type == type)
if (mapping->action.type == action->type)
return mapping->raw;
}
@@ -330,17 +308,20 @@ etekcity_read_button(struct ratbag_button *button)
struct etekcity_data *drv_data = ratbag_get_drv_data(device);
uint8_t data;
unsigned index = etekcity_button_to_index(button->index);
const struct ratbag_button_action *action;
data = drv_data->profiles[profile->index][3 + index * 3];
log_debug(device->ratbag,
" - button%d: %s (%02x) %s:%d\n",
button->index, print_key(data), data, __FILE__, __LINE__);
button->type = etekcity_raw_to_button_type(data);
button->action_type = etekcity_raw_to_action(data, button->type);
action = etekcity_raw_to_button_action(data);
button->action = *action;
/* FIXME: button->type needs a separate lookup table */
}
static int
etekcity_write_button(struct ratbag_button *button)
etekcity_write_button(struct ratbag_button *button,
const struct ratbag_button_action *action)
{
struct ratbag_profile *profile = button->profile;
struct ratbag_device *device = profile->device;
@@ -350,9 +331,7 @@ etekcity_write_button(struct ratbag_button *button)
data = &drv_data->profiles[profile->index][3 + index * 3];
if (button->action_type == RATBAG_BUTTON_ACTION_TYPE_BUTTON) {
*data = etekcity_button_type_to_raw(button->type);
}
*data = etekcity_button_action_to_raw(action);
return 0;
}

View File

@@ -73,7 +73,7 @@ hidpp10drv_read_button(struct ratbag_button *button)
case 10:
case 11:
case 12: /* these don't actually exist on the device */
type = RATBAG_BUTTON_TYPE_NONE; break;
type = RATBAG_BUTTON_TYPE_UNKNOWN; break;
default:
break;
}
@@ -82,7 +82,8 @@ hidpp10drv_read_button(struct ratbag_button *button)
}
static int
hidpp10drv_write_button(struct ratbag_button *button)
hidpp10drv_write_button(struct ratbag_button *button,
const struct ratbag_button_action *action)
{
return -1;
}

View File

@@ -94,11 +94,12 @@ hidpp20drv_read_button(struct ratbag_button *button)
control->reporting.divert || control->reporting.persist ? "(redirected) " : "",
__FILE__, __LINE__);
button->type = hidpp20_1b04_get_logical_mapping(mapping);
button->action_type = hidpp20drv_raw_to_action(button->type);
button->action.type = hidpp20drv_raw_to_action(button->type);
}
static int
hidpp20drv_write_button(struct ratbag_button *button)
hidpp20drv_write_button(struct ratbag_button *button,
const struct ratbag_button_action *action)
{
struct ratbag_device *device = button->profile->device;
struct hidpp20drv_data *drv_data = ratbag_get_drv_data(device);

View File

@@ -512,7 +512,7 @@ struct hidpp20_1b04_mapping {
static const struct hidpp20_1b04_mapping hidpp20_1b04_logical_mapping[] =
{
{ 0, "None" , RATBAG_BUTTON_TYPE_NONE},
{ 0, "None" , RATBAG_BUTTON_TYPE_UNKNOWN},
{ 1, "Volume Up" , RATBAG_BUTTON_TYPE_UNKNOWN},
{ 2, "Volume Down" , RATBAG_BUTTON_TYPE_UNKNOWN},
{ 3, "Mute" , RATBAG_BUTTON_TYPE_UNKNOWN},
@@ -530,26 +530,32 @@ static const struct hidpp20_1b04_mapping hidpp20_1b04_logical_mapping[] =
{ 315, "LedToggle" , RATBAG_BUTTON_TYPE_UNKNOWN},
};
static const struct hidpp20_1b04_mapping hidpp20_1b04_physical_mapping[] =
struct hidpp20_1b04_action_mapping {
uint16_t value;
const char *name;
struct ratbag_button_action action;
};
static const struct hidpp20_1b04_action_mapping hidpp20_1b04_physical_mapping[] =
{
{ 0, "None" , RATBAG_BUTTON_TYPE_NONE},
{ 1, "Volume Up" , RATBAG_BUTTON_TYPE_UNKNOWN},
{ 2, "Volume Down" , RATBAG_BUTTON_TYPE_UNKNOWN},
{ 3, "Mute" , RATBAG_BUTTON_TYPE_UNKNOWN},
{ 4, "Play/Pause" , RATBAG_BUTTON_TYPE_UNKNOWN},
{ 5, "Next" , RATBAG_BUTTON_TYPE_UNKNOWN},
{ 6, "Previous" , RATBAG_BUTTON_TYPE_UNKNOWN},
{ 7, "Stop" , RATBAG_BUTTON_TYPE_UNKNOWN},
{ 56, "Left Click" , RATBAG_BUTTON_TYPE_LEFT},
{ 57, "Right Click" , RATBAG_BUTTON_TYPE_RIGHT},
{ 58, "Middle Click" , RATBAG_BUTTON_TYPE_MIDDLE},
{ 59, "Wheel Side Click Left" , RATBAG_BUTTON_TYPE_UNKNOWN},
{ 60, "Back Click" , RATBAG_BUTTON_TYPE_SIDE},
{ 61, "Wheel Side Click Right" , RATBAG_BUTTON_TYPE_UNKNOWN},
{ 62, "Forward Click" , RATBAG_BUTTON_TYPE_EXTRA},
{ 156, "Gesture Button" , RATBAG_BUTTON_TYPE_UNKNOWN},
{ 157, "SmartShift" , RATBAG_BUTTON_TYPE_UNKNOWN},
{ 221, "LedToggle" , RATBAG_BUTTON_TYPE_UNKNOWN},
{ 0, "None" , BUTTON_ACTION_NONE },
{ 1, "Volume Up" , BUTTON_ACTION_KEY(KEY_VOLUMEUP) },
{ 2, "Volume Down" , BUTTON_ACTION_KEY(KEY_VOLUMEDOWN) },
{ 3, "Mute" , BUTTON_ACTION_KEY(KEY_MUTE) },
{ 4, "Play/Pause" , BUTTON_ACTION_KEY(KEY_PLAYPAUSE) },
{ 5, "Next" , BUTTON_ACTION_KEY(KEY_NEXTSONG) },
{ 6, "Previous" , BUTTON_ACTION_KEY(KEY_PREVIOUSSONG) },
{ 7, "Stop" , BUTTON_ACTION_KEY(KEY_STOPCD) },
{ 56, "Left Click" , BUTTON_ACTION_BUTTON(1) },
{ 57, "Right Click" , BUTTON_ACTION_BUTTON(2) },
{ 58, "Middle Click" , BUTTON_ACTION_BUTTON(3) },
{ 59, "Wheel Side Click Left" , BUTTON_ACTION_BUTTON(10) }, /* FIXME */
{ 60, "Back Click" , BUTTON_ACTION_BUTTON(4) },
{ 61, "Wheel Side Click Right" , BUTTON_ACTION_BUTTON(11)}, /* FIXME */
{ 62, "Forward Click" , BUTTON_ACTION_BUTTON(5) },
{ 156, "Gesture Button" , BUTTON_ACTION_NONE },
{ 157, "SmartShift" , BUTTON_ACTION_NONE },
{ 221, "LedToggle" , BUTTON_ACTION_NONE },
};
enum ratbag_button_type
@@ -591,23 +597,23 @@ hidpp20_1b04_get_logical_mapping_name(uint16_t value)
return "UNKNOWN";
}
enum ratbag_button_type
const struct ratbag_button_action*
hidpp20_1b04_get_physical_mapping(uint16_t value)
{
const struct hidpp20_1b04_mapping *map;
const struct hidpp20_1b04_action_mapping *map;
ARRAY_FOR_EACH(hidpp20_1b04_physical_mapping, map) {
if (map->value == value)
return map->type;
return &map->action;
}
return RATBAG_BUTTON_TYPE_UNKNOWN;
return NULL;
}
const char *
hidpp20_1b04_get_physical_mapping_name(uint16_t value)
{
const struct hidpp20_1b04_mapping *map;
const struct hidpp20_1b04_action_mapping *map;
ARRAY_FOR_EACH(hidpp20_1b04_physical_mapping, map) {
if (map->value == value)

View File

@@ -174,7 +174,7 @@ int hidpp20_special_key_mouse_set_control(struct ratbag_device *device,
enum ratbag_button_type hidpp20_1b04_get_logical_mapping(uint16_t value);
uint16_t hidpp20_1b04_get_logical_control_id(enum ratbag_button_type type);
const char *hidpp20_1b04_get_logical_mapping_name(uint16_t value);
enum ratbag_button_type hidpp20_1b04_get_physical_mapping(uint16_t value);
const struct ratbag_button_action *hidpp20_1b04_get_physical_mapping(uint16_t value);
const char *hidpp20_1b04_get_physical_mapping_name(uint16_t value);
/* -------------------------------------------------------------------------- */

View File

@@ -36,6 +36,7 @@
#define VERSION_ANY 0xffff
struct ratbag_driver;
struct ratbag_button_action;
struct ratbag {
const struct ratbag_interface *interface;
@@ -161,7 +162,8 @@ struct ratbag_driver {
* should later on write the profile in one call to
* .write_profile().
*/
int (*write_button)(struct ratbag_button *button);
int (*write_button)(struct ratbag_button *button,
const struct ratbag_button_action *action);
/** For the given profile, overwrite the current resolution
* of the sensor expressed in DPI, and commit it to the hardware.
@@ -186,13 +188,37 @@ struct ratbag_profile {
int report_rate;
};
#define BUTTON_ACTION_NONE \
{ .type = RATBAG_BUTTON_ACTION_TYPE_NONE }
#define BUTTON_ACTION_BUTTON(num_) \
{ .type = RATBAG_BUTTON_ACTION_TYPE_BUTTON, \
.action.button = num_ }
#define BUTTON_ACTION_SPECIAL(sp_) \
{ .type = RATBAG_BUTTON_ACTION_TYPE_SPECIAL, \
.action.special = sp_ }
#define BUTTON_ACTION_KEY(k_) \
{ .type = RATBAG_BUTTON_ACTION_TYPE_KEY, \
.action.key.key = k_ }
struct ratbag_button_action {
enum ratbag_button_action_type type;
union ratbag_btn_action {
unsigned int button; /* action_type == button */
enum ratbag_button_action_special special; /* action_type == special */
struct {
unsigned int key; /* action_type == key */
/* FIXME: modifiers */
} key;
} action;
};
struct ratbag_button {
int refcount;
struct list link;
struct ratbag_profile *profile;
unsigned index;
enum ratbag_button_type type;
enum ratbag_button_action_type action_type;
struct ratbag_button_action action;
};
static inline int

View File

@@ -741,19 +741,103 @@ ratbag_button_get_type(struct ratbag_button *button)
return button->type;
}
LIBRATBAG_EXPORT int
ratbag_button_set_type(struct ratbag_button *button, enum ratbag_button_type type)
LIBRATBAG_EXPORT unsigned int
ratbag_button_get_button(struct ratbag_button *button)
{
enum ratbag_button_type orig_type = button->type;
if (!button->profile->device->driver->read_button)
return 0; /* FIXME */
if (button->action.type != RATBAG_BUTTON_ACTION_TYPE_BUTTON)
return 0;
return button->action.action.button;
}
LIBRATBAG_EXPORT int
ratbag_button_set_button(struct ratbag_button *button, unsigned int btn)
{
struct ratbag_button_action action;
int rc;
if (!button->profile->device->driver->write_button)
return -ENOTSUP;
button->type = type;
rc = button->profile->device->driver->write_button(button);
if (rc)
button->type = orig_type;
action.type = RATBAG_BUTTON_ACTION_TYPE_BUTTON;
action.action.button = btn;
rc = button->profile->device->driver->write_button(button, &action);
return rc;
}
LIBRATBAG_EXPORT enum ratbag_button_action_special
ratbag_button_get_special(struct ratbag_button *button)
{
if (!button->profile->device->driver->read_button)
return -ENOTSUP;
if (button->action.type != RATBAG_BUTTON_ACTION_TYPE_BUTTON)
return 0;
return button->action.action.button;
}
LIBRATBAG_EXPORT int
ratbag_button_set_special(struct ratbag_button *button,
enum ratbag_button_action_special act)
{
struct ratbag_button_action action;
int rc;
/* FIXME: range checks */
if (!button->profile->device->driver->write_button)
return -1;
action.type = RATBAG_BUTTON_ACTION_TYPE_SPECIAL;
action.action.special = act;
rc = button->profile->device->driver->write_button(button, &action);
return rc;
}
LIBRATBAG_EXPORT unsigned int
ratbag_button_get_key(struct ratbag_button *button,
unsigned int *modifiers,
size_t *sz)
{
if (!button->profile->device->driver->read_button)
return 0;
if (button->action.type != RATBAG_BUTTON_ACTION_TYPE_KEY)
return 0;
/* FIXME: modifiers */
*sz = 0;
return button->action.action.key.key;
}
LIBRATBAG_EXPORT int
ratbag_button_set_key(struct ratbag_button *button,
unsigned int key,
unsigned int *modifiers,
size_t sz)
{
struct ratbag_button_action action;
int rc;
/* FIXME: range checks */
if (!button->profile->device->driver->write_button)
return -1;
/* FIXME: modifiers */
action.type = RATBAG_BUTTON_ACTION_TYPE_KEY;
action.action.key.key = key;
rc = button->profile->device->driver->write_button(button, &action);
return rc;
}

View File

@@ -445,34 +445,6 @@ enum ratbag_button_type {
RATBAG_BUTTON_TYPE_PROFILE_CYCLE_UP,
RATBAG_BUTTON_TYPE_PROFILE_UP,
RATBAG_BUTTON_TYPE_PROFILE_DOWN,
/* Macro */
RATBAG_BUTTON_TYPE_MACRO,
/* multimedia */
RATBAG_BUTTON_TYPE_KEY_CONFIG,
RATBAG_BUTTON_TYPE_KEY_PREVIOUSSONG,
RATBAG_BUTTON_TYPE_KEY_NEXTSONG,
RATBAG_BUTTON_TYPE_KEY_PLAYPAUSE,
RATBAG_BUTTON_TYPE_KEY_STOPCD,
RATBAG_BUTTON_TYPE_KEY_MUTE,
RATBAG_BUTTON_TYPE_KEY_VOLUMEUP,
RATBAG_BUTTON_TYPE_KEY_VOLUMEDOWN,
/* desktop */
RATBAG_BUTTON_TYPE_KEY_CALC,
RATBAG_BUTTON_TYPE_KEY_MAIL,
RATBAG_BUTTON_TYPE_KEY_BOOKMARKS,
RATBAG_BUTTON_TYPE_KEY_FORWARD,
RATBAG_BUTTON_TYPE_KEY_BACK,
RATBAG_BUTTON_TYPE_KEY_STOP,
RATBAG_BUTTON_TYPE_KEY_FILE,
RATBAG_BUTTON_TYPE_KEY_REFRESH,
RATBAG_BUTTON_TYPE_KEY_HOMEPAGE,
RATBAG_BUTTON_TYPE_KEY_SEARCH,
/* disabled button */
RATBAG_BUTTON_TYPE_NONE,
};
/**
@@ -491,21 +463,6 @@ enum ratbag_button_type {
enum ratbag_button_type
ratbag_button_get_type(struct ratbag_button *button);
/**
* @ingroup device
*
* Change the type of the physical button. This function is intended to be
* used by configuration tools 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 error code or 0 on success.
*/
int
ratbag_button_set_type(struct ratbag_button *button, enum ratbag_button_type type);
/**
* @ingroup device
*
@@ -524,6 +481,11 @@ enum ratbag_button_action_type {
* Button sends numeric button events
*/
RATBAG_BUTTON_ACTION_TYPE_BUTTON,
/**
* Button triggers a mouse-specific special function. This includes
* resolution changes and profile changes.
*/
RATBAG_BUTTON_ACTION_TYPE_SPECIAL,
/**
* Button sends a key or key + modifier combination
*/
@@ -542,16 +504,50 @@ enum ratbag_button_action_type {
enum ratbag_button_action_type
ratbag_button_get_action_type(struct ratbag_button *button);
enum ratbag_button_action_special {
/**
* This button is not set up for a special action
*/
RATBAG_BUTTON_ACTION_SPECIAL_INVALID = -1,
RATBAG_BUTTON_ACTION_SPECIAL_UNKNOWN = (1 << 30),
RATBAG_BUTTON_ACTION_SPECIAL_DOUBLECLICK,
/* Wheel mappings */
RATBAG_BUTTON_ACTION_SPECIAL_WHEEL_LEFT,
RATBAG_BUTTON_ACTION_SPECIAL_WHEEL_RIGHT,
RATBAG_BUTTON_ACTION_SPECIAL_WHEEL_UP,
RATBAG_BUTTON_ACTION_SPECIAL_WHEEL_DOWN,
/* DPI switch */
RATBAG_BUTTON_ACTION_SPECIAL_RESOLUTION_CYCLE_UP,
RATBAG_BUTTON_ACTION_SPECIAL_RESOLUTION_UP,
RATBAG_BUTTON_ACTION_SPECIAL_RESOLUTION_DOWN,
/* Profile */
RATBAG_BUTTON_ACTION_SPECIAL_PROFILE_CYCLE_UP,
RATBAG_BUTTON_ACTION_SPECIAL_PROFILE_UP,
RATBAG_BUTTON_ACTION_SPECIAL_PROFILE_DOWN,
};
/**
* @ingroup device
*
* This function returns the logical button number this button is mapped to,
* starting at 1. The button numbers are in sequence and do not correspond
* to any meaning other than its numeric value. It is up to the input stack
* how to map that logical button number, but usually buttons 1, 2 and 3 are
* mapped into left, middle, right.
*
* 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.
* @return The logical button number this button sends.
* @retval 0 This button is disabled or its action type is not @ref
* RATBAG_BUTTON_ACTION_TYPE_BUTTON.
*
* @see ratbag_button_set_button
*/
unsigned int
ratbag_button_get_button(struct ratbag_button *button);
@@ -559,16 +555,50 @@ ratbag_button_get_button(struct ratbag_button *button);
/**
* @ingroup device
*
* See ratbag_button_get_button() for a description of the button number.
*
* @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 btn The logical button number to assign to this button.
* @return 0 on success or nonzero otherwise. On success, the button's
* action is set to @ref RATBAG_BUTTON_ACTION_TYPE_BUTTON.
*
* @see ratbag_button_get_button
*/
int
ratbag_button_set_button(struct ratbag_button *button,
unsigned int btn);
/**
* @ingroup device
*
* This function returns the special function assigned to this button.
*
* If the button's action type is not @ref RATBAG_BUTTON_ACTION_TYPE_SPECIAL,
* this function returns @ref RATBAG_BUTTON_ACTION_SPECIAL_INVALID.
*
* @return The special function assigned to this button
*
* @see ratbag_button_set_button
*/
enum ratbag_button_action_special
ratbag_button_get_special(struct ratbag_button *button);
/**
* @ingroup device
*
* This function sets the special function assigned to this button.
*
* @param button A previously initialized ratbag button
* @param action The special action to assign to this button.
* @return 0 on success or nonzero otherwise. On success, the button's
* action is set to @ref RATBAG_BUTTON_ACTION_TYPE_SPECIAL.
*
* @see ratbag_button_get_button
*/
int
ratbag_button_set_special(struct ratbag_button *button,
enum ratbag_button_action_special action);
/**
* @ingroup device
*
@@ -597,7 +627,7 @@ ratbag_button_get_key(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
* @param key 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
@@ -610,7 +640,7 @@ ratbag_button_get_key(struct ratbag_button *button,
*/
int
ratbag_button_set_key(struct ratbag_button *button,
unsigned int btn,
unsigned int key,
unsigned int *modifiers,
size_t sz);

View File

@@ -5,7 +5,12 @@ global:
ratbag_create_context;
ratbag_button_ref;
ratbag_button_get_type;
ratbag_button_set_type;
ratbag_button_get_button;
ratbag_button_get_key;
ratbag_button_get_special;
ratbag_button_set_button;
ratbag_button_set_key;
ratbag_button_set_special;
ratbag_button_unref;
ratbag_device_unref;
ratbag_device_get_active_profile;

View File

@@ -31,6 +31,7 @@
#include <unistd.h>
#include <getopt.h>
#include <sys/stat.h>
#include <linux/input.h>
#include <libratbag.h>
#include <libratbag-util.h>
@@ -155,34 +156,6 @@ button_type_to_str(enum ratbag_button_type type)
case RATBAG_BUTTON_TYPE_PROFILE_CYCLE_UP: str = "profile cycle up"; break;
case RATBAG_BUTTON_TYPE_PROFILE_UP: str = "profile up"; break;
case RATBAG_BUTTON_TYPE_PROFILE_DOWN: str = "profile down"; break;
/* Macro */
case RATBAG_BUTTON_TYPE_MACRO: str = "macro"; break;
/* multimedia */
case RATBAG_BUTTON_TYPE_KEY_CONFIG: str = "key config"; break;
case RATBAG_BUTTON_TYPE_KEY_PREVIOUSSONG: str = "key previous song"; break;
case RATBAG_BUTTON_TYPE_KEY_NEXTSONG: str = "key next song"; break;
case RATBAG_BUTTON_TYPE_KEY_PLAYPAUSE: str = "key play/pause"; break;
case RATBAG_BUTTON_TYPE_KEY_STOPCD: str = "key stop"; break;
case RATBAG_BUTTON_TYPE_KEY_MUTE: str = "key mute"; break;
case RATBAG_BUTTON_TYPE_KEY_VOLUMEUP: str = "key volume up"; break;
case RATBAG_BUTTON_TYPE_KEY_VOLUMEDOWN: str = "key volume down"; break;
/* desktop */
case RATBAG_BUTTON_TYPE_KEY_CALC: str = "key calc"; break;
case RATBAG_BUTTON_TYPE_KEY_MAIL: str = "key mail"; break;
case RATBAG_BUTTON_TYPE_KEY_BOOKMARKS: str = "key bookmarks"; break;
case RATBAG_BUTTON_TYPE_KEY_FORWARD: str = "key forward"; break;
case RATBAG_BUTTON_TYPE_KEY_BACK: str = "key back"; break;
case RATBAG_BUTTON_TYPE_KEY_STOP: str = "key stop"; break;
case RATBAG_BUTTON_TYPE_KEY_FILE: str = "key file"; break;
case RATBAG_BUTTON_TYPE_KEY_REFRESH: str = "key refresh"; break;
case RATBAG_BUTTON_TYPE_KEY_HOMEPAGE: str = "key homepage"; break;
case RATBAG_BUTTON_TYPE_KEY_SEARCH: str = "key search"; break;
/* disabled button */
case RATBAG_BUTTON_TYPE_NONE: str = "none"; break;
}
return str;
@@ -373,6 +346,8 @@ ratbag_cmd_switch_etekcity(struct ratbag *ratbag, uint32_t flags, int argc, char
struct ratbag_button *button_6, *button_7;
struct ratbag_profile *profile = NULL;
int rc = 1, commit = 0;
unsigned int modifiers[10];
size_t modifiers_sz = 10;
if (argc != 1) {
usage();
@@ -402,15 +377,15 @@ ratbag_cmd_switch_etekcity(struct ratbag *ratbag, uint32_t flags, int argc, char
button_6 = ratbag_profile_get_button_by_index(profile, 6);
button_7 = ratbag_profile_get_button_by_index(profile, 7);
if (ratbag_button_get_type(button_6) == RATBAG_BUTTON_TYPE_KEY_VOLUMEUP &&
ratbag_button_get_type(button_7) == RATBAG_BUTTON_TYPE_KEY_VOLUMEDOWN) {
ratbag_button_set_type(button_6, RATBAG_BUTTON_TYPE_NONE);
ratbag_button_set_type(button_7, RATBAG_BUTTON_TYPE_NONE);
if (ratbag_button_get_key(button_6, modifiers, &modifiers_sz) == KEY_VOLUMEUP &&
ratbag_button_get_key(button_7, modifiers, &modifiers_sz) == KEY_VOLUMEDOWN) {
ratbag_button_set_button(button_6, 0);
ratbag_button_set_button(button_7, 0);
commit = 1;
} else if (ratbag_button_get_type(button_6) == RATBAG_BUTTON_TYPE_NONE &&
ratbag_button_get_type(button_7) == RATBAG_BUTTON_TYPE_NONE) {
ratbag_button_set_type(button_6, RATBAG_BUTTON_TYPE_KEY_VOLUMEUP);
ratbag_button_set_type(button_7, RATBAG_BUTTON_TYPE_KEY_VOLUMEDOWN);
} else if (ratbag_button_get_button(button_6) == 0 &&
ratbag_button_get_button(button_7) == 0) {
ratbag_button_set_key(button_6, KEY_VOLUMEUP, modifiers, 0);
ratbag_button_set_key(button_7, KEY_VOLUMEDOWN, modifiers, 0);
commit = 2;
}
@@ -459,6 +434,7 @@ ratbag_cmd_change_button(struct ratbag *ratbag, uint32_t flags, int argc, char *
type_index = atoi(argv[1]);
path = argv[2];
#if 0 /* FIXME */
device = ratbag_cmd_open_device(ratbag, path);
if (!device) {
error("Looks like '%s' is not supported\n", path);
@@ -514,6 +490,7 @@ out:
profile = ratbag_profile_unref(profile);
device = ratbag_device_unref(device);
#endif
return rc;
}