forked from drath/libratbag
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:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
128
src/libratbag.h
128
src/libratbag.h
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user