forked from drath/libratbag
hidpp20: parse the buttons mapping in the profiles
Only export the actual buttons in ratbag_button for now. Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
This commit is contained in:
@@ -64,7 +64,7 @@ struct hidpp20drv_data {
|
||||
};
|
||||
|
||||
static void
|
||||
hidpp20drv_read_button(struct ratbag_button *button)
|
||||
hidpp20drv_button_key_1b04_read_button(struct ratbag_button *button)
|
||||
{
|
||||
struct ratbag_device *device = button->profile->device;
|
||||
struct hidpp20drv_data *drv_data = ratbag_get_drv_data(device);
|
||||
@@ -96,6 +96,40 @@ hidpp20drv_read_button(struct ratbag_button *button)
|
||||
ratbag_button_enable_action_type(button, RATBAG_BUTTON_ACTION_TYPE_SPECIAL);
|
||||
}
|
||||
|
||||
static void
|
||||
hidpp20drv_onboard_profile_8100_read_button(struct ratbag_button *button)
|
||||
{
|
||||
struct ratbag_device *device = button->profile->device;
|
||||
struct hidpp20drv_data *drv_data = ratbag_get_drv_data(device);
|
||||
struct hidpp20_profile *profile;
|
||||
|
||||
if (!(drv_data->capabilities & HIDPP_CAP_ONBOARD_PROFILES_8100))
|
||||
return;
|
||||
|
||||
profile = &drv_data->profiles->profiles[button->profile->index];
|
||||
|
||||
switch (profile->buttons[button->index].type) {
|
||||
case HIDPP20_BUTTON_HID_MOUSE:
|
||||
button->action.type = RATBAG_BUTTON_ACTION_TYPE_BUTTON;
|
||||
button->action.action.button = profile->buttons[button->index].code;
|
||||
break;
|
||||
default:
|
||||
button->action.type = RATBAG_BUTTON_ACTION_TYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
ratbag_button_enable_action_type(button, RATBAG_BUTTON_ACTION_TYPE_BUTTON);
|
||||
ratbag_button_enable_action_type(button, RATBAG_BUTTON_ACTION_TYPE_KEY);
|
||||
ratbag_button_enable_action_type(button, RATBAG_BUTTON_ACTION_TYPE_SPECIAL);
|
||||
ratbag_button_enable_action_type(button, RATBAG_BUTTON_ACTION_TYPE_MACRO);
|
||||
}
|
||||
|
||||
static void
|
||||
hidpp20drv_read_button(struct ratbag_button *button)
|
||||
{
|
||||
hidpp20drv_button_key_1b04_read_button(button);
|
||||
hidpp20drv_onboard_profile_8100_read_button(button);
|
||||
}
|
||||
|
||||
static int
|
||||
hidpp20drv_write_button(struct ratbag_button *button,
|
||||
const struct ratbag_button_action *action)
|
||||
|
||||
@@ -930,6 +930,9 @@ int hidpp20_adjustable_dpi_set_sensor_dpi(struct hidpp20_device *device,
|
||||
#define CMD_ONBOARD_PROFILES_GET_CURRENT_DPI_INDEX 0xb0
|
||||
#define CMD_ONBOARD_PROFILES_SET_CURRENT_DPI_INDEX 0xc0
|
||||
|
||||
#define HIDPP20_PROFILE_SIZE (15*16)
|
||||
#define HIDPP20_BUTTON_HID 0x80
|
||||
|
||||
static int
|
||||
hidpp20_onboard_profiles_read_memory(struct hidpp20_device *device,
|
||||
uint16_t page,
|
||||
@@ -1066,7 +1069,7 @@ int hidpp20_onboard_profiles_read(struct hidpp20_device *device,
|
||||
unsigned int index,
|
||||
struct hidpp20_profiles *profiles_list)
|
||||
{
|
||||
uint8_t data[16] = {0};
|
||||
uint8_t data[HIDPP20_PROFILE_SIZE] = {0};
|
||||
struct hidpp20_profile *profile = &profiles_list->profiles[index];
|
||||
unsigned i;
|
||||
int rc;
|
||||
@@ -1074,12 +1077,14 @@ int hidpp20_onboard_profiles_read(struct hidpp20_device *device,
|
||||
if (index >= profiles_list->num_profiles)
|
||||
return -EINVAL;
|
||||
|
||||
rc = hidpp20_onboard_profiles_read_memory(device,
|
||||
index + 1,
|
||||
0x0000,
|
||||
data);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
for (i = 0; i < HIDPP20_PROFILE_SIZE / 0x10; i++) {
|
||||
rc = hidpp20_onboard_profiles_read_memory(device,
|
||||
index + 1,
|
||||
i * 0x10,
|
||||
data + i * 0x10);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
}
|
||||
|
||||
profile->report_rate = 1000 / max(1, data[0]);
|
||||
profile->default_dpi = data[1];
|
||||
@@ -1089,6 +1094,25 @@ int hidpp20_onboard_profiles_read(struct hidpp20_device *device,
|
||||
profile->dpi[i] = hidpp20_get_unaligned_be_u16(&data[2 * i + 3]);
|
||||
}
|
||||
|
||||
for (i = 0; i < profiles_list->num_buttons; i++) {
|
||||
uint8_t *button = data + 0x20 + i * 4;
|
||||
|
||||
profile->buttons[i].type = button[0];
|
||||
|
||||
if (button[0] == HIDPP20_BUTTON_HID) {
|
||||
profile->buttons[i].type |= button[1];
|
||||
|
||||
if (profile->buttons[i].type == HIDPP20_BUTTON_HID_KEYBOARD) {
|
||||
profile->buttons[i].modifiers = button[2];
|
||||
profile->buttons[i].code = button[3];
|
||||
} else {
|
||||
profile->buttons[i].code = ffs(hidpp20_get_unaligned_u16(&button[2]));
|
||||
}
|
||||
} else if (button[0] == HIDPP20_BUTTON_SPECIAL) {
|
||||
profile->buttons[i].code = button[1];
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -264,6 +264,15 @@ int hidpp20_adjustable_dpi_set_sensor_dpi(struct hidpp20_device *device,
|
||||
|
||||
#define HIDPP_PAGE_ONBOARD_PROFILES 0x8100
|
||||
|
||||
#define HIDPP20_BUTTON_HID_MOUSE 0x81
|
||||
#define HIDPP20_BUTTON_HID_KEYBOARD 0x82
|
||||
#define HIDPP20_BUTTON_HID_CONSUMER_CONTROL 0x83
|
||||
#define HIDPP20_BUTTON_SPECIAL 0x90
|
||||
#define HIDPP20_BUTTON_DISABLED 0xFF
|
||||
|
||||
#define HIDPP20_MODIFIER_KEY_CTRL 0x01
|
||||
#define HIDPP20_MODIFIER_KEY_SHIFT 0x02
|
||||
|
||||
struct hidpp20_profile {
|
||||
uint8_t index;
|
||||
uint8_t enabled;
|
||||
@@ -271,6 +280,11 @@ struct hidpp20_profile {
|
||||
unsigned default_dpi;
|
||||
unsigned switched_dpi;
|
||||
uint16_t dpi[5];
|
||||
struct {
|
||||
uint8_t type;
|
||||
uint8_t modifiers;
|
||||
uint8_t code;
|
||||
} buttons[32];
|
||||
};
|
||||
|
||||
struct hidpp20_profiles {
|
||||
|
||||
Reference in New Issue
Block a user