1
0
forked from drath/libratbag

asus: new quirks for Chakram X and other mice

This commit is contained in:
Kyoken
2024-05-10 20:10:42 +03:00
committed by staticssleever668
parent ad6540e39b
commit 7bdca904f5
8 changed files with 287 additions and 72 deletions

View File

@@ -1,14 +1,16 @@
[Device]
Name=ASUS ROG Chakram X
DeviceMatch=usb:0b05:1a18
DeviceMatch=usb:0b05:1a18;usb:0b05:1a1a
DeviceType=mouse
Driver=asus
[Driver/asus]
Profiles=3
Buttons=5
Profiles=5
Buttons=14
Leds=3
Dpis=4
Wireless=1
DpiRange=100:36000@100
Quirks=DOUBLE_DPI
Quirks=DOUBLE_DPI;RAW_BRIGHTNESS;SEPARATE_XY_DPI;SEPARATE_LEDS;BUTTONS_SECONDARY
ButtonMapping=f0;f1;f2;0;0;e6;e8;e9;d0;d1;d2;d3
ButtonMappingSecondary=0;0;ea;eb;ec;ed

View File

@@ -11,3 +11,4 @@ Leds=3
Dpis=2
DpiRange=100:7200@100
ButtonMapping=f0;f1;f2;e4;e5;e6;0;e8;e9;e1;e2
LedModes=ON;BREATHING;ON;CYCLE

View File

@@ -75,15 +75,18 @@ static const unsigned char ASUS_KEY_MAPPING[] = {
/* 5E */ KEY_KP8, KEY_KP9, 0,
};
static unsigned int ASUS_POLLING_RATES[] = { 125, 250, 500, 1000 };
static unsigned int ASUS_DEBOUNCE_TIMES[] = { 4, 8, 12, 16, 20, 24, 28, 32 };
static const uint8_t ASUS_JOYSTICK_CODES[] = { 0xd0, 0xd1, 0xd2, 0xd3, 0xd7, 0xd8, 0xda, 0xdb };
static const unsigned int ASUS_POLLING_RATES[] = { 125, 250, 500, 1000 };
static const unsigned int ASUS_DEBOUNCE_TIMES[] = { 4, 8, 12, 16, 20, 24, 28, 32 };
/* search for ASUS button by ratbag types */
const struct asus_button *
asus_find_button_by_action(struct ratbag_button_action action)
asus_find_button_by_action(struct ratbag_button_action action, bool is_joystick)
{
const struct asus_button *asus_button;
ARRAY_FOR_EACH(ASUS_BUTTON_MAPPING, asus_button) {
if (is_joystick != asus_code_is_joystick(asus_button->asus_code))
continue;
if ((action.type == RATBAG_BUTTON_ACTION_TYPE_BUTTON && asus_button->button == action.action.button) ||
(action.type == RATBAG_BUTTON_ACTION_TYPE_SPECIAL && asus_button->special == action.action.special))
return asus_button;
@@ -113,6 +116,15 @@ asus_find_key_code(unsigned int linux_code)
return -1;
}
bool
asus_code_is_joystick(uint8_t asus_code) {
for (unsigned int i = 0; i < ARRAY_LENGTH(ASUS_JOYSTICK_CODES); i++) {
if (ASUS_JOYSTICK_CODES[i] == asus_code)
return true;
}
return false;
}
int
asus_get_linux_key_code(uint8_t asus_code) {
if (asus_code > ARRAY_LENGTH(ASUS_KEY_MAPPING)) {
@@ -216,6 +228,11 @@ asus_get_profile_data(struct ratbag_device *device, struct asus_profile_data *da
else
data->profile_id = response.data.results[8];
if (response.data.results[9])
data->dpi_preset = response.data.results[9] - 1;
else
data->dpi_preset = -1;
data->version_primary_major = response.data.results[13];
data->version_primary_minor = response.data.results[12];
data->version_primary_build = response.data.results[11];
@@ -246,12 +263,13 @@ asus_set_profile(struct ratbag_device *device, unsigned int index)
/* read button bindings */
int
asus_get_binding_data(struct ratbag_device *device, union asus_binding_data *data)
asus_get_binding_data(struct ratbag_device *device, union asus_binding_data *data, unsigned int group)
{
int rc;
union asus_response response;
union asus_request request = {
.data.cmd = ASUS_CMD_GET_BUTTON_DATA,
.data.params[0] = (uint8_t)group,
};
rc = asus_query(device, &request, &response);
@@ -289,7 +307,7 @@ asus_set_button_action(struct ratbag_device *device, uint8_t asus_code_src,
}
int
asus_get_resolution_data(struct ratbag_device *device, union asus_resolution_data *data)
asus_get_resolution_data(struct ratbag_device *device, union asus_resolution_data *data, bool sep_xy_dpi)
{
int rc;
uint32_t quirks = ratbag_device_data_asus_get_quirks(device->data);
@@ -298,6 +316,7 @@ asus_get_resolution_data(struct ratbag_device *device, union asus_resolution_dat
unsigned int i;
union asus_request request = {
.data.cmd = ASUS_CMD_GET_SETTINGS,
.data.params[0] = sep_xy_dpi ? 2 : 0,
};
rc = asus_query(device, &request, &response);
@@ -319,13 +338,24 @@ asus_get_resolution_data(struct ratbag_device *device, union asus_resolution_dat
break;
case 4: /* 4 DPI presets */
for (i = 0; i < dpi_count; i++) {
data->data4.dpi[i] = data->data4.dpi[i] * 50 + 50;
if (quirks & ASUS_QUIRK_DOUBLE_DPI)
data->data4.dpi[i] *= 2;
if (sep_xy_dpi) { /* separate X & Y values */
for (i = 0; i < dpi_count; i++) {
data->data_xy.dpi[i].x = data->data_xy.dpi[i].x * 50 + 50;
data->data_xy.dpi[i].y = data->data_xy.dpi[i].y * 50 + 50;
if (quirks & ASUS_QUIRK_DOUBLE_DPI) {
data->data_xy.dpi[i].x *= 2;
data->data_xy.dpi[i].y *= 2;
}
}
} else {
for (i = 0; i < dpi_count; i++) {
data->data4.dpi[i] = data->data4.dpi[i] * 50 + 50;
if (quirks & ASUS_QUIRK_DOUBLE_DPI)
data->data4.dpi[i] *= 2;
}
data->data4.rate = ASUS_POLLING_RATES[data->data4.rate];
data->data4.response = ASUS_DEBOUNCE_TIMES[data->data4.response];
}
data->data4.rate = ASUS_POLLING_RATES[data->data4.rate];
data->data4.response = ASUS_DEBOUNCE_TIMES[data->data4.response];
break;
default:
@@ -440,12 +470,13 @@ asus_set_angle_snapping(struct ratbag_device *device, bool is_enabled)
}
int
asus_get_led_data(struct ratbag_device *device, union asus_led_data *data)
asus_get_led_data(struct ratbag_device *device, union asus_led_data *data, unsigned int led)
{
int rc;
union asus_response response;
union asus_request request = {
.data.cmd = ASUS_CMD_GET_LED_DATA,
.data.params[0] = led,
};
rc = asus_query(device, &request, &response);

View File

@@ -9,6 +9,10 @@
#define ASUS_QUIRK_DOUBLE_DPI 1 << 0
#define ASUS_QUIRK_STRIX_PROFILE 1 << 1
#define ASUS_QUIRK_BATTERY_V2 1 << 2
#define ASUS_QUIRK_RAW_BRIGHTNESS 1 << 3
#define ASUS_QUIRK_SEPARATE_XY_DPI 1 << 4
#define ASUS_QUIRK_SEPARATE_LEDS 1 << 5
#define ASUS_QUIRK_BUTTONS_SECONDARY 1 << 6
#define ASUS_PACKET_SIZE 64
#define ASUS_BUTTON_ACTION_TYPE_KEY 0 /* keyboard key */
@@ -18,6 +22,7 @@
/* maximum number of buttons across all ASUS devices */
#define ASUS_MAX_NUM_BUTTON 17
#define ASUS_MAX_NUM_BUTTON_GROUP 2
/* maximum number of DPI presets across all ASUS devices */
/* for 4 DPI devices: 0 - red, 1 - purple, 2 - blue (default), 3 - green */
@@ -26,6 +31,7 @@
/* maximum number of LEDs across all ASUS devices */
#define ASUS_MAX_NUM_LED 3
#define ASUS_MAX_NUM_LED_MODES 7
/* base request */
@@ -57,6 +63,7 @@ union asus_response {
struct asus_profile_data {
unsigned int profile_id;
int dpi_preset;
uint8_t version_primary_major;
uint8_t version_primary_minor;
uint8_t version_primary_build;
@@ -90,6 +97,7 @@ struct _asus_dpi2_data {
uint16_t rate; /* polling rate */
uint16_t response; /* button response */
uint16_t snapping; /* angle snapping (on/off) */
uint16_t pad2;
} __attribute__((packed)); /* struct for storing 2 DPI presets and extra settings */
struct _asus_dpi4_data {
@@ -98,11 +106,23 @@ struct _asus_dpi4_data {
uint16_t rate;
uint16_t response;
uint16_t snapping;
uint16_t pad2;
} __attribute__((packed)); /* struct for storing 4 DPI presets and extra settings */
struct _asus_dpi_xy {
uint16_t x;
uint16_t y;
};
struct _asus_dpi_xy_data {
uint32_t pad;
struct _asus_dpi_xy dpi[4];
} __attribute__((packed)); /* struct for storing 4 DPI presets with separate X & Y */
union asus_resolution_data {
struct _asus_dpi2_data data2; /* data for 2 DPI presets */
struct _asus_dpi4_data data4; /* data for 4 DPI presets */
struct _asus_dpi_xy_data data_xy; /* data for 4 DPI presets with separate X & Y */
uint8_t raw[sizeof(struct _asus_dpi4_data)];
};
@@ -153,10 +173,18 @@ static const struct asus_button ASUS_BUTTON_MAPPING[] = {
{ 0xed, RATBAG_BUTTON_ACTION_TYPE_NONE, 0, 0 }, /* side button D */
{ 0xee, RATBAG_BUTTON_ACTION_TYPE_NONE, 0, 0 }, /* side button E */
{ 0xef, RATBAG_BUTTON_ACTION_TYPE_NONE, 0, 0 }, /* side button F */
{ 0xd0, RATBAG_BUTTON_ACTION_TYPE_NONE, 0, 0 }, /* joystick up */
{ 0xd1, RATBAG_BUTTON_ACTION_TYPE_NONE, 0, 0 }, /* joystick down */
{ 0xd2, RATBAG_BUTTON_ACTION_TYPE_NONE, 0, 0 }, /* joystick forward */
{ 0xd3, RATBAG_BUTTON_ACTION_TYPE_NONE, 0, 0 }, /* joystick backward */
{ 0xd7, RATBAG_BUTTON_ACTION_TYPE_SPECIAL, 0, RATBAG_BUTTON_ACTION_SPECIAL_WHEEL_DOWN }, /* joystick axis -Y */
{ 0xd8, RATBAG_BUTTON_ACTION_TYPE_SPECIAL, 0, RATBAG_BUTTON_ACTION_SPECIAL_WHEEL_UP }, /* joystick axis +Y */
{ 0xda, RATBAG_BUTTON_ACTION_TYPE_SPECIAL, 0, RATBAG_BUTTON_ACTION_SPECIAL_WHEEL_RIGHT }, /* joystick axis -X */
{ 0xdb, RATBAG_BUTTON_ACTION_TYPE_SPECIAL, 0, RATBAG_BUTTON_ACTION_SPECIAL_WHEEL_LEFT }, /* joystick axis +X */
};
const struct asus_button *
asus_find_button_by_action(struct ratbag_button_action action);
asus_find_button_by_action(struct ratbag_button_action action, bool is_joystick);
const struct asus_button *
asus_find_button_by_code(uint8_t asus_code);
@@ -164,6 +192,9 @@ asus_find_button_by_code(uint8_t asus_code);
int
asus_find_key_code(unsigned int linux_code);
bool
asus_code_is_joystick(uint8_t asus_code);
/*
* @param asus_code ASUS key code.
* @return Linux key code (as defined defined in linux/input-event-codes.h) or
@@ -207,7 +238,7 @@ asus_set_profile(struct ratbag_device *device, unsigned int index);
/* button bindings */
int
asus_get_binding_data(struct ratbag_device *device, union asus_binding_data *data);
asus_get_binding_data(struct ratbag_device *device, union asus_binding_data *data, unsigned int group);
int
asus_set_button_action(struct ratbag_device *device, uint8_t asus_code_src,
@@ -216,7 +247,7 @@ asus_set_button_action(struct ratbag_device *device, uint8_t asus_code_src,
/* resolution settings */
int
asus_get_resolution_data(struct ratbag_device *device, union asus_resolution_data *data);
asus_get_resolution_data(struct ratbag_device *device, union asus_resolution_data *data, bool sep_xy_dpi);
int
asus_set_dpi(struct ratbag_device *device, unsigned int index, unsigned int dpi);
@@ -233,7 +264,7 @@ asus_set_angle_snapping(struct ratbag_device *device, bool is_enabled);
/* LED settings */
int
asus_get_led_data(struct ratbag_device *device, union asus_led_data *data);
asus_get_led_data(struct ratbag_device *device, union asus_led_data *data, unsigned int led);
int
asus_set_led(struct ratbag_device *device,

View File

@@ -46,17 +46,9 @@ static int ASUS_CONFIG_BUTTON_MAPPING[] = {
0xe6, /* DPI */
0xe8, /* wheel up */
0xe9, /* wheel down */
-1, /* placeholder */
-1, /* placeholder */
-1, /* placeholder */
-1, /* placeholder */
-1, /* placeholder */
-1, /* placeholder */
-1, /* placeholder */
-1, /* placeholder */
-1, /* placeholder */
};
/* LedModes configuration property defaults */
static unsigned int ASUS_LED_MODE[] = {
RATBAG_LED_ON,
RATBAG_LED_BREATHING,
@@ -69,12 +61,13 @@ static unsigned int ASUS_LED_MODE[] = {
struct asus_data {
uint8_t is_ready;
int button_mapping[ASUS_MAX_NUM_BUTTON];
int button_indices[ASUS_MAX_NUM_BUTTON];
int button_mapping[ASUS_MAX_NUM_BUTTON * ASUS_MAX_NUM_BUTTON_GROUP];
int button_indices[ASUS_MAX_NUM_BUTTON * ASUS_MAX_NUM_BUTTON_GROUP];
int led_modes[ASUS_MAX_NUM_LED_MODES];
};
static int
asus_driver_load_profile(struct ratbag_device *device, struct ratbag_profile *profile)
asus_driver_load_profile(struct ratbag_device *device, struct ratbag_profile *profile, int dpi_preset)
{
int rc;
const struct _asus_binding *asus_binding;
@@ -84,18 +77,28 @@ asus_driver_load_profile(struct ratbag_device *device, struct ratbag_profile *pr
struct ratbag_led *led;
struct ratbag_resolution *resolution;
union asus_binding_data binding_data;
union asus_binding_data binding_data_secondary;
union asus_led_data led_data;
union asus_resolution_data resolution_data;
union asus_resolution_data xy_resolution_data;
unsigned int dpi_count = ratbag_device_get_profile(device, 0)->num_resolutions;
unsigned int led_count = ratbag_device_get_num_leds(device);
uint32_t quirks = ratbag_device_data_asus_get_quirks(device->data);
struct asus_data *drv_data = ratbag_get_drv_data(device);
/* get buttons */
log_debug(device->ratbag, "Loading buttons data\n");
rc = asus_get_binding_data(device, &binding_data);
rc = asus_get_binding_data(device, &binding_data, 0);
if (rc)
return rc;
if (quirks & ASUS_QUIRK_BUTTONS_SECONDARY) {
rc = asus_get_binding_data(device, &binding_data_secondary, 1);
if (rc)
return rc;
}
ratbag_profile_for_each_button(profile, button) {
int asus_index = drv_data->button_indices[button->index];
if (asus_index == -1) {
@@ -103,7 +106,11 @@ asus_driver_load_profile(struct ratbag_device *device, struct ratbag_profile *pr
continue;
}
asus_binding = &binding_data.data.binding[asus_index];
if (asus_index < ASUS_MAX_NUM_BUTTON) {
asus_binding = &binding_data.data.binding[asus_index];
} else {
asus_binding = &binding_data_secondary.data.binding[asus_index % ASUS_MAX_NUM_BUTTON];
}
/* disabled */
if (asus_binding->action == ASUS_BUTTON_CODE_DISABLED) {
@@ -144,31 +151,59 @@ asus_driver_load_profile(struct ratbag_device *device, struct ratbag_profile *pr
/* get DPIs */
log_debug(device->ratbag, "Loading resolutions data\n");
rc = asus_get_resolution_data(device, &resolution_data);
rc = asus_get_resolution_data(device, &resolution_data, false);
if (rc)
return rc;
if (quirks & ASUS_QUIRK_SEPARATE_XY_DPI) {
rc = asus_get_resolution_data(device, &xy_resolution_data, true);
if (rc)
return rc;
}
switch (dpi_count) {
case 2: /* 2 DPI presets */
profile->hz = resolution_data.data2.rate;
profile->angle_snapping = resolution_data.data2.snapping;
profile->debounce = resolution_data.data2.response;
ratbag_profile_for_each_resolution(profile, resolution)
ratbag_resolution_set_resolution(
resolution,
resolution_data.data2.dpi[resolution->index],
resolution_data.data2.dpi[resolution->index]);
ratbag_profile_for_each_resolution(profile, resolution) {
if (quirks & ASUS_QUIRK_SEPARATE_XY_DPI) {
ratbag_resolution_set_cap(resolution, RATBAG_RESOLUTION_CAP_SEPARATE_XY_RESOLUTION);
ratbag_resolution_set_resolution(
resolution,
xy_resolution_data.data_xy.dpi[resolution->index].x,
xy_resolution_data.data_xy.dpi[resolution->index].y);
} else {
ratbag_resolution_set_resolution(
resolution,
resolution_data.data2.dpi[resolution->index],
resolution_data.data2.dpi[resolution->index]);
}
if (dpi_preset != -1 && (unsigned int)dpi_preset == resolution->index)
resolution->is_active = true;
}
break;
case 4: /* 4 DPI presets */
profile->hz = resolution_data.data4.rate;
profile->angle_snapping = resolution_data.data4.snapping;
profile->debounce = resolution_data.data4.response;
ratbag_profile_for_each_resolution(profile, resolution)
ratbag_resolution_set_resolution(
resolution,
resolution_data.data4.dpi[resolution->index],
resolution_data.data4.dpi[resolution->index]);
ratbag_profile_for_each_resolution(profile, resolution) {
if (quirks & ASUS_QUIRK_SEPARATE_XY_DPI) {
ratbag_resolution_set_cap(resolution, RATBAG_RESOLUTION_CAP_SEPARATE_XY_RESOLUTION);
ratbag_resolution_set_resolution(
resolution,
xy_resolution_data.data_xy.dpi[resolution->index].x,
xy_resolution_data.data_xy.dpi[resolution->index].y);
} else {
ratbag_resolution_set_resolution(
resolution,
resolution_data.data4.dpi[resolution->index],
resolution_data.data4.dpi[resolution->index]);
}
if (dpi_preset != -1 && (unsigned int)dpi_preset == resolution->index)
resolution->is_active = true;
}
break;
default:
@@ -177,16 +212,31 @@ asus_driver_load_profile(struct ratbag_device *device, struct ratbag_profile *pr
/* get LEDs */
log_debug(device->ratbag, "Loading LEDs data\n");
rc = asus_get_led_data(device, &led_data);
if (rc)
return rc;
if (!(quirks & ASUS_QUIRK_SEPARATE_LEDS) && led_count) {
log_debug(device->ratbag, "Loading LEDs data\n");
rc = asus_get_led_data(device, &led_data, 0);
if (rc)
return rc;
}
ratbag_profile_for_each_led(profile, led) {
asus_led = &led_data.data.led[led->index];
led->mode = ASUS_LED_MODE[asus_led->mode];
/* convert brightness from 0-4 to 0-256 */
led->brightness = asus_led->brightness * 64;
if (quirks & ASUS_QUIRK_SEPARATE_LEDS) {
log_debug(device->ratbag, "Loading LED %d data\n", led->index);
rc = asus_get_led_data(device, &led_data, led->index);
if (rc)
return rc;
asus_led = &led_data.data.led[0];
} else {
asus_led = &led_data.data.led[led->index];
}
led->mode = drv_data->led_modes[asus_led->mode];
if (quirks & ASUS_QUIRK_RAW_BRIGHTNESS) {
led->brightness = asus_led->brightness;
} else {
/* convert brightness from 0-4 to 0-256 */
led->brightness = asus_led->brightness * 64;
}
led->color.red = asus_led->r;
led->color.green = asus_led->g;
led->color.blue = asus_led->b;
@@ -203,6 +253,7 @@ asus_driver_save_profile(struct ratbag_device *device, struct ratbag_profile *pr
struct ratbag_led *led;
struct ratbag_resolution *resolution;
struct asus_data *drv_data = ratbag_get_drv_data(device);
uint32_t quirks = ratbag_device_data_asus_get_quirks(device->data);
/* set buttons */
ratbag_profile_for_each_button(profile, button) {
@@ -218,6 +269,7 @@ asus_driver_save_profile(struct ratbag_device *device, struct ratbag_profile *pr
const struct asus_button *asus_button;
uint8_t asus_code_src;
uint8_t asus_code_dst;
bool is_joystick;
rc = drv_data->button_mapping[asus_index];
if (rc == -1) {
@@ -250,7 +302,18 @@ asus_driver_save_profile(struct ratbag_device *device, struct ratbag_profile *pr
case RATBAG_BUTTON_ACTION_TYPE_BUTTON:
case RATBAG_BUTTON_ACTION_TYPE_SPECIAL:
/* ratbag action to ASUS code */
asus_button = asus_find_button_by_action(button->action);
is_joystick = asus_code_is_joystick(asus_code_src);
if (is_joystick) {
asus_button = asus_find_button_by_action(button->action, true);
if (asus_button != NULL) { /* found button to bind to */
rc = asus_set_button_action(
device, asus_code_src, asus_button->asus_code,
ASUS_BUTTON_ACTION_TYPE_BUTTON);
break;
}
}
asus_button = asus_find_button_by_action(button->action, false);
if (asus_button != NULL) /* found button to bind to */
rc = asus_set_button_action(
device, asus_code_src, asus_button->asus_code,
@@ -306,15 +369,20 @@ asus_driver_save_profile(struct ratbag_device *device, struct ratbag_profile *pr
log_debug(device->ratbag, "LED %d changed\n", led->index);
uint8_t led_mode = 0;
for (unsigned int i = 0; i < ARRAY_LENGTH(ASUS_LED_MODE); i++) {
if (ASUS_LED_MODE[i] == led->mode) {
for (unsigned int i = 0; i < ASUS_MAX_NUM_LED_MODES; i++) {
if (drv_data->led_modes[i] == (int) led->mode) {
led_mode = i;
break;
}
}
/* convert brightness from 0-256 to 0-4 */
uint8_t led_brightness = (uint8_t)round((double)led->brightness / 64.0);
uint8_t led_brightness;
if (quirks & ASUS_QUIRK_RAW_BRIGHTNESS) {
led_brightness = led->brightness;
} else {
/* convert brightness from 0-256 to 0-4 */
led_brightness = (uint8_t)round((double)led->brightness / 64.0);
}
rc = asus_set_led(device, led->index, led_mode, led_brightness, led->color);
if (rc)
return rc;
@@ -365,7 +433,7 @@ asus_driver_load_profiles(struct ratbag_device *device)
return rc;
}
rc = asus_driver_load_profile(device, profile);
rc = asus_driver_load_profile(device, profile, profile_data.dpi_preset);
if (rc)
return rc;
}
@@ -469,23 +537,37 @@ asus_driver_probe(struct ratbag_device *device)
button_count = ratbag_device_data_asus_get_button_count(device->data);
led_count = ratbag_device_data_asus_get_led_count(device->data);
const int *bm = ratbag_device_data_asus_get_button_mapping(device->data);
const int *led_modes = ratbag_device_data_asus_get_led_modes(device->data);
/* merge ButtonMapping configuration property with defaults */
for (unsigned int i = 0; i < ASUS_MAX_NUM_BUTTON; i++) {
drv_data->button_mapping[i] = bm[i] != -1 ? bm[i] : ASUS_CONFIG_BUTTON_MAPPING[i];
for (unsigned int i = 0; i < ASUS_MAX_NUM_BUTTON * ASUS_MAX_NUM_BUTTON_GROUP; i++) {
if (bm[i] != -1) {
drv_data->button_mapping[i] = bm[i];
} else {
if (i < ARRAY_LENGTH(ASUS_CONFIG_BUTTON_MAPPING)) {
drv_data->button_mapping[i] = ASUS_CONFIG_BUTTON_MAPPING[i];
} else {
drv_data->button_mapping[i] = -1;
}
}
drv_data->button_indices[i] = -1;
}
/* merge LedModes configuration property with defaults */
for (unsigned int i = 0; i < ASUS_MAX_NUM_LED_MODES; i++)
drv_data->led_modes[i] = (led_modes[i] != -1) ? led_modes[i] : (int) ASUS_LED_MODE[i];
/* setup a lookup table for all defined buttons */
unsigned int button_index = 0;
ARRAY_FOR_EACH(ASUS_BUTTON_MAPPING, asus_button) {
/* search for this button in the ButtonMapping by it's ASUS code */
for (unsigned int i = 0; i < ASUS_MAX_NUM_BUTTON; i++) {
for (unsigned int i = 0; i < ASUS_MAX_NUM_BUTTON * ASUS_MAX_NUM_BUTTON_GROUP; i++) {
if (drv_data->button_mapping[i] == (int)asus_button->asus_code) {
/* add button to indices array */
drv_data->button_indices[button_index] = (int)i;
log_debug(device->ratbag, "Button %d is mapped to 0x%02x\n",
button_index, (uint8_t)drv_data->button_mapping[i]);
log_debug(device->ratbag, "Button %d is mapped to 0x%02x at position %d group %d\n",
button_index, (uint8_t)drv_data->button_mapping[i],
i % ASUS_MAX_NUM_BUTTON, i / ASUS_MAX_NUM_BUTTON);
button_index++;
break;
}

View File

@@ -100,12 +100,13 @@ struct data_steelseries {
struct data_asus {
int profile_count;
int button_count;
int button_mapping[ASUS_MAX_NUM_BUTTON];
int button_mapping[ASUS_MAX_NUM_BUTTON * ASUS_MAX_NUM_BUTTON_GROUP];
int led_count;
int dpi_count;
int is_wireless;
struct dpi_range *dpi_range;
uint32_t quirks;
int led_modes[ASUS_MAX_NUM_LED_MODES];
};
struct ratbag_device_data {
@@ -375,8 +376,10 @@ init_data_asus(struct ratbag *ratbag,
data->asus.dpi_range = NULL;
data->asus.is_wireless = -1;
data->asus.quirks = 0;
for (unsigned int i = 0; i < ASUS_MAX_NUM_BUTTON; i++)
for (unsigned int i = 0; i < ASUS_MAX_NUM_BUTTON * ASUS_MAX_NUM_BUTTON_GROUP; i++)
data->asus.button_mapping[i] = -1;
for (unsigned int i = 0; i < ASUS_MAX_NUM_LED_MODES; i++)
data->asus.led_modes[i] = -1;
int profiles = g_key_file_get_integer(keyfile, group, "Profiles", &error);
if (!error && profiles >= 0)
@@ -388,11 +391,20 @@ init_data_asus(struct ratbag *ratbag,
data->asus.button_count = buttons;
g_clear_error(&error);
gsize button_mapping_count = 0;
_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] = strtoul(button_mapping[i], NULL, 16);
gsize btn_map_count = 0;
_cleanup_(g_strfreevp) char **btn_map = g_key_file_get_string_list(keyfile, group, "ButtonMapping", &btn_map_count, &error);
if (!error && btn_map) {
for (unsigned int i = 0; i < btn_map_count; i++) {
data->asus.button_mapping[i] = strtoul(btn_map[i], NULL, 16);
}
}
g_clear_error(&error);
gsize btn_map_2nd_count = 0;
_cleanup_(g_strfreevp) char **btn_map_2nd = g_key_file_get_string_list(keyfile, group, "ButtonMappingSecondary", &btn_map_2nd_count, &error);
if (!error && btn_map_2nd) {
for (unsigned int i = 0; i < btn_map_2nd_count; i++) {
data->asus.button_mapping[i + ASUS_MAX_NUM_BUTTON] = strtoul(btn_map_2nd[i], NULL, 16);
}
}
g_clear_error(&error);
@@ -425,8 +437,33 @@ init_data_asus(struct ratbag *ratbag,
data->asus.quirks |= ASUS_QUIRK_DOUBLE_DPI;
} else if (streq(quirks[i], "STRIX_PROFILE")) {
data->asus.quirks |= ASUS_QUIRK_STRIX_PROFILE;
} else if (streq(quirks[i], "RAW_BRIGHTNESS")) {
data->asus.quirks |= ASUS_QUIRK_RAW_BRIGHTNESS;
} else if (streq(quirks[i], "SEPARATE_XY_DPI")) {
data->asus.quirks |= ASUS_QUIRK_SEPARATE_XY_DPI;
} else if (streq(quirks[i], "SEPARATE_LEDS")) {
data->asus.quirks |= ASUS_QUIRK_SEPARATE_LEDS;
} else if (streq(quirks[i], "BUTTONS_SECONDARY")) {
data->asus.quirks |= ASUS_QUIRK_BUTTONS_SECONDARY;
} else {
log_debug(ratbag, "%s is invalid quirk. Ignoring...\n", quirks[i]);
log_error(ratbag, "%s is invalid quirk. Ignoring...\n", quirks[i]);
}
}
}
g_clear_error(&error);
gsize led_modes_count = 0;
_cleanup_(g_strfreevp) char **led_modes = g_key_file_get_string_list(keyfile, group, "LedModes", &led_modes_count, &error);
if (!error && led_modes) {
for (unsigned int i = 0; i < led_modes_count; i++) {
if (streq(led_modes[i], "ON")) {
data->asus.led_modes[i] = RATBAG_LED_ON;
} else if (streq(led_modes[i], "BREATHING")) {
data->asus.led_modes[i] = RATBAG_LED_BREATHING;
} else if (streq(led_modes[i], "CYCLE")) {
data->asus.led_modes[i] = RATBAG_LED_CYCLE;
} else {
log_error(ratbag, "%s is invalid LED mode. Ignoring...\n", led_modes[i]);
}
}
}
@@ -895,6 +932,13 @@ ratbag_device_data_asus_get_led_count(const struct ratbag_device_data *data)
return data->asus.led_count;
}
const int *
ratbag_device_data_asus_get_led_modes(const struct ratbag_device_data *data)
{
assert(data->drivertype == ASUS);
return data->asus.led_modes;
}
int
ratbag_device_data_asus_get_dpi_count(const struct ratbag_device_data *data)
{

View File

@@ -164,6 +164,12 @@ ratbag_device_data_asus_get_button_mapping(const struct ratbag_device_data *data
int
ratbag_device_data_asus_get_led_count(const struct ratbag_device_data *data);
/**
* @return Array of LED modes
*/
const int *
ratbag_device_data_asus_get_led_modes(const struct ratbag_device_data *data);
/**
* @return Number of DPI presets
*/

View File

@@ -108,10 +108,12 @@ def check_profile_type_str(string: str):
def check_section_asus(section: configparser.SectionProxy):
permitted_keys = (
"ButtonMapping",
"ButtonMappingSecondary",
"Buttons",
"DpiRange",
"Dpis",
"Leds",
"LedModes",
"Profiles",
"Quirks",
"Wireless",
@@ -129,6 +131,10 @@ def check_section_asus(section: configparser.SectionProxy):
quirks = (
"DOUBLE_DPI",
"STRIX_PROFILE",
"RAW_BRIGHTNESS",
"SEPARATE_XY_DPI",
"SEPARATE_LEDS",
"BUTTONS_SECONDARY",
)
for quirk in section["Quirks"].split(";"):
assert quirk in quirks
@@ -136,6 +142,18 @@ def check_section_asus(section: configparser.SectionProxy):
# No such section - not an error.
pass
try:
led_modes = (
"ON",
"BREATHING",
"CYCLE",
)
for led_mode in section["LedModes"].split(";"):
assert led_mode in led_modes
except KeyError:
# No such section - not an error.
pass
def check_section_hidpp10(section: configparser.SectionProxy):
permitted = [