From 041a8023b8615a58000a7cac25fe8d93c2b9ffff Mon Sep 17 00:00:00 2001 From: Kyoken Date: Sun, 13 Nov 2022 23:00:25 +0300 Subject: [PATCH] asus: button mapping reworked --- data/devices/asus-rog-chakram-x.device | 13 ++++ .../asus-rog-gladius2-origin-pink.device | 1 - data/devices/asus-rog-gladius2-origin.device | 1 - data/devices/asus-rog-gladius2.device | 4 +- data/devices/asus-rog-pugio.device | 4 +- data/devices/device.example | 4 +- src/asus.c | 26 +------ src/asus.h | 23 +++++- src/driver-asus.c | 72 +++++++++++++------ src/libratbag-data.c | 2 +- 10 files changed, 94 insertions(+), 56 deletions(-) create mode 100644 data/devices/asus-rog-chakram-x.device diff --git a/data/devices/asus-rog-chakram-x.device b/data/devices/asus-rog-chakram-x.device new file mode 100644 index 00000000..6bd8b53b --- /dev/null +++ b/data/devices/asus-rog-chakram-x.device @@ -0,0 +1,13 @@ +[Device] +Name=ASUS ROG Chakram X +DeviceMatch=usb:0b05:1a1a +Driver=asus + +[Driver/asus] +Profiles=3 +Buttons=5 +Leds=3 +Dpis=4 +Wireless=1 +DpiRange=100:36000@100 +Quirks=DOUBLE_DPI;STRIX_PROFILE diff --git a/data/devices/asus-rog-gladius2-origin-pink.device b/data/devices/asus-rog-gladius2-origin-pink.device index 5f66dbfb..83bfa421 100644 --- a/data/devices/asus-rog-gladius2-origin-pink.device +++ b/data/devices/asus-rog-gladius2-origin-pink.device @@ -9,5 +9,4 @@ Buttons=8 Leds=3 Dpis=2 DpiRange=100:12000@100 -ButtonMapping=0;1;2;7;8;5;3;4 Quirks=DOUBLE_DPI diff --git a/data/devices/asus-rog-gladius2-origin.device b/data/devices/asus-rog-gladius2-origin.device index fa17df35..2da0cc2c 100644 --- a/data/devices/asus-rog-gladius2-origin.device +++ b/data/devices/asus-rog-gladius2-origin.device @@ -10,5 +10,4 @@ Buttons=8 Leds=3 Dpis=2 DpiRange=100:12000@100 -ButtonMapping=0;1;2;7;8;5;3;4 Quirks=DOUBLE_DPI diff --git a/data/devices/asus-rog-gladius2.device b/data/devices/asus-rog-gladius2.device index 22a37dc6..f157a621 100644 --- a/data/devices/asus-rog-gladius2.device +++ b/data/devices/asus-rog-gladius2.device @@ -5,8 +5,8 @@ Driver=asus [Driver/asus] Profiles=3 -Buttons=8 +Buttons=9 Leds=3 Dpis=2 DpiRange=100:12000@100 -ButtonMapping=0;1;2;7;8;5;3;4 +ButtonMapping=f0;f1;f2;e4;e5;e6;e7;e8;e9 diff --git a/data/devices/asus-rog-pugio.device b/data/devices/asus-rog-pugio.device index 8c205267..e470b850 100644 --- a/data/devices/asus-rog-pugio.device +++ b/data/devices/asus-rog-pugio.device @@ -9,6 +9,4 @@ Buttons=10 Leds=3 Dpis=2 DpiRange=100:7200@100 - -# Mappings the same as the Gladius II but with an extra 2 buttons -ButtonMapping=0;1;2;7;8;5;3;4;9;10 +ButtonMapping=f0;f1;f2;e4;e5;e6;e8;e9;e1;e2 diff --git a/data/devices/device.example b/data/devices/device.example index 71225288..ec5b3801 100644 --- a/data/devices/device.example +++ b/data/devices/device.example @@ -73,8 +73,8 @@ Dpis=2 # DPI range in format min:max@step DpiRange=100:16000@100 -# Button index mapping -# ButtonMapping=0;1;2;6;7;5;3;4 +# Button mapping +# ButtonMapping=f0;f1;f2;e4;e5;e6;e8;e9 # Device quirks # Quirk=DOUBLE_DPI;STRIX_PROFILE diff --git a/src/asus.c b/src/asus.c index d09b2c67..aaf8dfbb 100644 --- a/src/asus.c +++ b/src/asus.c @@ -46,26 +46,6 @@ #define ASUS_FIELD_RESPONSE 1 #define ASUS_FIELD_SNAPPING 2 -/* order is mandatory because index is mapped from ButtonMapping configuration property */ -static struct asus_button ASUS_BUTTON_MAPPING[] = { - { 0xf0, RATBAG_BUTTON_ACTION_TYPE_BUTTON, 1, 0 }, /* left */ - { 0xf1, RATBAG_BUTTON_ACTION_TYPE_BUTTON, 2, 0 }, /* right (button 3 in xev) */ - { 0xf2, RATBAG_BUTTON_ACTION_TYPE_BUTTON, 3, 0 }, /* middle (button 2 in xev) */ - { 0xe4, RATBAG_BUTTON_ACTION_TYPE_BUTTON, 4, 0 }, /* backward (on left side) */ - { 0xe5, RATBAG_BUTTON_ACTION_TYPE_BUTTON, 5, 0 }, /* forward (on left side) */ - { 0xe6, RATBAG_BUTTON_ACTION_TYPE_SPECIAL, 0, RATBAG_BUTTON_ACTION_SPECIAL_RESOLUTION_CYCLE_UP }, - { 0xe8, RATBAG_BUTTON_ACTION_TYPE_SPECIAL, 0, RATBAG_BUTTON_ACTION_SPECIAL_WHEEL_UP }, - { 0xe9, RATBAG_BUTTON_ACTION_TYPE_SPECIAL, 0, RATBAG_BUTTON_ACTION_SPECIAL_WHEEL_DOWN }, - { 0xe1, RATBAG_BUTTON_ACTION_TYPE_BUTTON, 4, 0 }, /* backward on right side */ - { 0xe2, RATBAG_BUTTON_ACTION_TYPE_BUTTON, 5, 0 }, /* forward on right side */ - { 0xff, RATBAG_BUTTON_ACTION_TYPE_NONE, 0, 0 }, /* placeholder */ - { 0xff, RATBAG_BUTTON_ACTION_TYPE_NONE, 0, 0 }, /* placeholder */ - { 0xff, RATBAG_BUTTON_ACTION_TYPE_NONE, 0, 0 }, /* placeholder */ - { 0xff, RATBAG_BUTTON_ACTION_TYPE_NONE, 0, 0 }, /* placeholder */ - { 0xff, RATBAG_BUTTON_ACTION_TYPE_NONE, 0, 0 }, /* placeholder */ - { 0xff, RATBAG_BUTTON_ACTION_TYPE_NONE, 0, 0 }, /* placeholder */ -}; - /* key mapping, the index is actual ASUS code */ static unsigned char ASUS_KEY_MAPPING[] = { /* 00 */ 0, 0, 0, 0, @@ -268,7 +248,7 @@ asus_set_profile(struct ratbag_device *device, unsigned int index) return 0; } -/* read button bindings using ButtonMapping configuration property */ +/* read button bindings */ int asus_get_binding_data(struct ratbag_device *device, union asus_binding_data *data) { @@ -288,7 +268,7 @@ asus_get_binding_data(struct ratbag_device *device, union asus_binding_data *dat /* set button binding using ASUS code of the button */ int -asus_set_button_action(struct ratbag_device *device, unsigned int asus_index, uint8_t asus_code, uint8_t asus_type) +asus_set_button_action(struct ratbag_device *device, uint8_t button_asus_code, uint8_t asus_code, uint8_t asus_type) { int rc; union asus_response response; @@ -297,7 +277,7 @@ asus_set_button_action(struct ratbag_device *device, unsigned int asus_index, ui }; /* source (physical mouse button) */ - request.data.params[2] = ASUS_BUTTON_MAPPING[asus_index].asus_code; + request.data.params[2] = button_asus_code; request.data.params[3] = ASUS_BUTTON_ACTION_TYPE_BUTTON; /* destination (mouse button or keyboard key action) */ diff --git a/src/asus.h b/src/asus.h index 73c66e6d..0d8386c4 100644 --- a/src/asus.h +++ b/src/asus.h @@ -8,6 +8,7 @@ #define ASUS_QUIRK_DOUBLE_DPI 1 << 0 #define ASUS_QUIRK_STRIX_PROFILE 1 << 1 +#define ASUS_QUIRK_BATTERY_V2 1 << 2 #define ASUS_PACKET_SIZE 64 #define ASUS_BUTTON_ACTION_TYPE_KEY 0 /* keyboard key */ @@ -133,6 +134,26 @@ struct asus_button { enum ratbag_button_action_special special; /* special action, optional */ }; +/* ASUS code, button type, button number, special button action */ +static struct asus_button ASUS_BUTTON_MAPPING[] = { + { 0xf0, RATBAG_BUTTON_ACTION_TYPE_BUTTON, 1, 0 }, /* left */ + { 0xf1, RATBAG_BUTTON_ACTION_TYPE_BUTTON, 2, 0 }, /* right (button 3 in xev) */ + { 0xf2, RATBAG_BUTTON_ACTION_TYPE_BUTTON, 3, 0 }, /* middle (button 2 in xev) */ + { 0xe8, RATBAG_BUTTON_ACTION_TYPE_SPECIAL, 0, RATBAG_BUTTON_ACTION_SPECIAL_WHEEL_UP }, + { 0xe9, RATBAG_BUTTON_ACTION_TYPE_SPECIAL, 0, RATBAG_BUTTON_ACTION_SPECIAL_WHEEL_DOWN }, + { 0xe6, RATBAG_BUTTON_ACTION_TYPE_SPECIAL, 0, RATBAG_BUTTON_ACTION_SPECIAL_RESOLUTION_CYCLE_UP }, + { 0xe4, RATBAG_BUTTON_ACTION_TYPE_BUTTON, 4, 0 }, /* backward, left side */ + { 0xe5, RATBAG_BUTTON_ACTION_TYPE_BUTTON, 5, 0 }, /* forward, left side */ + { 0xe1, RATBAG_BUTTON_ACTION_TYPE_BUTTON, 4, 0 }, /* backward, right side */ + { 0xe2, RATBAG_BUTTON_ACTION_TYPE_BUTTON, 5, 0 }, /* forward, right side */ + { 0xe7, RATBAG_BUTTON_ACTION_TYPE_SPECIAL, 0, RATBAG_BUTTON_ACTION_SPECIAL_RESOLUTION_ALTERNATE }, /* DPI target */ + { 0xff, RATBAG_BUTTON_ACTION_TYPE_NONE, 0, 0 }, /* placeholder */ + { 0xff, RATBAG_BUTTON_ACTION_TYPE_NONE, 0, 0 }, /* placeholder */ + { 0xff, RATBAG_BUTTON_ACTION_TYPE_NONE, 0, 0 }, /* placeholder */ + { 0xff, RATBAG_BUTTON_ACTION_TYPE_NONE, 0, 0 }, /* placeholder */ + { 0xff, RATBAG_BUTTON_ACTION_TYPE_NONE, 0, 0 }, /* placeholder */ +}; + struct asus_button * asus_find_button_by_action(struct ratbag_button_action action); @@ -183,7 +204,7 @@ int asus_get_binding_data(struct ratbag_device *device, union asus_binding_data *data); int -asus_set_button_action(struct ratbag_device *device, unsigned int index, +asus_set_button_action(struct ratbag_device *device, uint8_t button_asus_code, uint8_t asus_code, uint8_t asus_type); /* resolution settings */ diff --git a/src/driver-asus.c b/src/driver-asus.c index 0a077485..2a6cb769 100644 --- a/src/driver-asus.c +++ b/src/driver-asus.c @@ -37,16 +37,16 @@ #include "asus.h" -/* ButtonMapping configuration property defaults, stores indices for ASUS_BUTTON_MAPPING */ -static int8_t ASUS_BUTTON_MAPPING_INDEX[] = { - 0, /* left */ - 1, /* right (button 3 in xev) */ - 2, /* middle (button 2 in xev) */ - 6, /* wheel up */ - 7, /* wheel down */ - 5, /* DPI */ - 3, /* backward */ - 4, /* forward */ +/* ButtonMapping configuration property defaults */ +static int8_t ASUS_CONFIG_BUTTON_MAPPING[] = { + 0xf0, /* left */ + 0xf1, /* right (button 3 in xev) */ + 0xf2, /* middle (button 2 in xev) */ + 0xe4, /* backward */ + 0xe5, /* forward */ + 0xe6, /* DPI */ + 0xe8, /* wheel up */ + 0xe9, /* wheel down */ -1, /* placeholder */ -1, /* placeholder */ -1, /* placeholder */ @@ -69,13 +69,14 @@ static unsigned int ASUS_LED_MODE[] = { struct asus_data { uint8_t is_ready; + int8_t button_mapping[ASUS_MAX_NUM_BUTTON]; + int button_indices[ASUS_MAX_NUM_BUTTON]; }; static int asus_driver_load_profile(struct ratbag_device *device, struct ratbag_profile *profile) { int rc; - const int8_t *bmi = ratbag_device_data_asus_get_button_mapping(device->data); struct _asus_binding *asus_binding; struct _asus_led *asus_led; struct asus_button *asus_button; @@ -86,6 +87,7 @@ asus_driver_load_profile(struct ratbag_device *device, struct ratbag_profile *pr union asus_led_data led_data; union asus_resolution_data resolution_data; unsigned int dpi_count = ratbag_device_get_profile(device, 0)->num_resolutions; + struct asus_data *drv_data = ratbag_get_drv_data(device); /* get buttons */ @@ -95,7 +97,7 @@ asus_driver_load_profile(struct ratbag_device *device, struct ratbag_profile *pr return rc; ratbag_profile_for_each_button(profile, button) { - int asus_index = bmi[button->index] != -1 ? bmi[button->index] : ASUS_BUTTON_MAPPING_INDEX[button->index]; + int asus_index = drv_data->button_indices[button->index]; if (asus_index == -1) { log_debug(device->ratbag, "No mapping for button %d\n", button->index); continue; @@ -189,50 +191,51 @@ static int asus_driver_save_profile(struct ratbag_device *device, struct ratbag_profile *profile) { int rc = 0; - const int8_t *bmi = ratbag_device_data_asus_get_button_mapping(device->data); - struct asus_button *asus_button; struct ratbag_button *button; struct ratbag_led *led; struct ratbag_resolution *resolution; + struct asus_data *drv_data = ratbag_get_drv_data(device); /* set buttons */ ratbag_profile_for_each_button(profile, button) { if (!button->dirty) continue; - int asus_index = bmi[button->index] != -1 ? bmi[button->index] : ASUS_BUTTON_MAPPING_INDEX[button->index]; - int asus_code; + int asus_index = drv_data->button_indices[button->index]; if (asus_index == -1) { log_debug(device->ratbag, "No mapping for button %d\n", button->index); continue; } - log_debug(device->ratbag, "Button %d (%d) changed\n", button->index, asus_index); + int button_asus_code = drv_data->button_mapping[asus_index]; + log_debug(device->ratbag, "Button %d (%02x) changed\n", + button->index, (uint8_t) button_asus_code); switch (button->action.type) { case RATBAG_BUTTON_ACTION_TYPE_NONE: rc = asus_set_button_action( - device, asus_index, + device, button_asus_code, ASUS_BUTTON_CODE_DISABLED, ASUS_BUTTON_ACTION_TYPE_BUTTON); break; case RATBAG_BUTTON_ACTION_TYPE_KEY: /* Linux code to ASUS code */ - asus_code = asus_find_key_code(button->action.action.key.key); + int asus_code = asus_find_key_code(button->action.action.key.key); if (asus_code >= 0) rc = asus_set_button_action( - device, asus_index, + device, button_asus_code, asus_code, ASUS_BUTTON_ACTION_TYPE_KEY); break; case RATBAG_BUTTON_ACTION_TYPE_BUTTON: case RATBAG_BUTTON_ACTION_TYPE_SPECIAL: - asus_button = asus_find_button_by_action(button->action); + /* ratbag action to ASUS code */ + struct asus_button *asus_button = asus_find_button_by_action(button->action); if (asus_button != NULL) /* found button to bind to */ rc = asus_set_button_action( - device, asus_index, + device, button_asus_code, asus_button->asus_code, ASUS_BUTTON_ACTION_TYPE_BUTTON); break; @@ -423,6 +426,31 @@ asus_driver_probe(struct ratbag_device *device) dpi_count = ratbag_device_data_asus_get_dpi_count(device->data); button_count = ratbag_device_data_asus_get_button_count(device->data); led_count = ratbag_device_data_asus_get_led_count(device->data); + const int8_t *bm = ratbag_device_data_asus_get_button_mapping(device->data); + + /* merge ButtonMapping configuration property with defaults */ + for (unsigned int i = 0; i < button_count; i++) { + drv_data->button_mapping[i] = bm[i] != -1 ? bm[i] : ASUS_CONFIG_BUTTON_MAPPING[i]; + drv_data->button_indices[i] = -1; + } + + /* setup a lookup table for all defined buttons */ + unsigned int button_index = 0; + for (unsigned int i = 0; i < ARRAY_LENGTH(ASUS_BUTTON_MAPPING); i++) { + struct asus_button *asus_button = &ASUS_BUTTON_MAPPING[i]; + + /* search for this button in the ButtonMapping by it's ASUS code */ + for (unsigned int j = 0; j < button_count; j++) { + if (drv_data->button_mapping[j] == (int8_t) asus_button->asus_code) { + /* add button to indices array */ + drv_data->button_indices[button_index] = (int)j; + log_debug(device->ratbag, "Button %d is mapped to 0x%02x\n", + button_index, (uint8_t) drv_data->button_mapping[j]); + button_index++; + break; + } + } + } /* init profiles */ ratbag_device_init_profiles( diff --git a/src/libratbag-data.c b/src/libratbag-data.c index 32b07052..d7b26616 100644 --- a/src/libratbag-data.c +++ b/src/libratbag-data.c @@ -373,7 +373,7 @@ init_data_asus(struct ratbag *ratbag, _cleanup_(g_strfreevp) char **button_mapping = g_key_file_get_string_list(keyfile, group, "ButtonMapping", &button_mapping_count, &error); if (!error && button_mapping) { for (unsigned int i = 0; i < button_mapping_count; i++) { - data->asus.button_mapping[i] = (int8_t) strtoul(button_mapping[i], NULL, 10); + data->asus.button_mapping[i] = (int8_t) strtoul(button_mapping[i], NULL, 16); } } g_clear_error(&error);