forked from drath/libratbag
asus: new quirks for Chakram X and other mice
This commit is contained in:
committed by
staticssleever668
parent
ad6540e39b
commit
7bdca904f5
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
55
src/asus.c
55
src/asus.c
@@ -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);
|
||||
|
||||
39
src/asus.h
39
src/asus.h
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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 = [
|
||||
|
||||
Reference in New Issue
Block a user