1
0
forked from drath/libratbag

asus: button mapping reworked

This commit is contained in:
Kyoken
2022-11-13 23:00:25 +03:00
committed by Yaroslav Chvanov
parent e9470ff6f4
commit 041a8023b8
10 changed files with 94 additions and 56 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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) */

View File

@@ -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 */

View File

@@ -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(

View File

@@ -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);