From 2c799eca30a39459e7cd5fd10ee81995d0a8bbcc Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Mon, 24 Jul 2017 12:21:51 +0200 Subject: [PATCH] hidpp10: correctly retrieve the profile directory and use it We need to read the directory and the profiles only once. Nothing tells us how many profiles are supported, so use the specifications from Logitech website, and add a hwdb entry for those. Signed-off-by: Benjamin Tissoires --- hwdb/70-libratbag-mouse.hwdb | 22 ++++ src/driver-hidpp10.c | 43 +++++--- src/hidpp10.c | 194 +++++++++++++++-------------------- src/hidpp10.h | 26 ++--- src/liblur.c | 5 +- tools/hidpp10-dump-page.c | 2 +- 6 files changed, 146 insertions(+), 146 deletions(-) diff --git a/hwdb/70-libratbag-mouse.hwdb b/hwdb/70-libratbag-mouse.hwdb index 9ca946f1..1eee0352 100644 --- a/hwdb/70-libratbag-mouse.hwdb +++ b/hwdb/70-libratbag-mouse.hwdb @@ -69,31 +69,41 @@ mouse:usb:v046dpc041:name:*: RATBAG_HIDPP10_DPI_LIST=400;800;1600;2000 # G5 2007 +# http://support.logitech.com/en_us/product/g5-laser-mouse-product/specs mouse:usb:v046dpc049:name:*: RATBAG_DRIVER=hidpp10 RATBAG_HIDPP10_DPI_LIST=400;800;1600;2000 + RATBAG_HIDPP10_PROFILE_COUNT=1 # G7 +# http://support.logitech.com/en_us/product/g7-laser-cordless-mouse/specs mouse:usb:v046dpc51a:name:*: RATBAG_DRIVER=hidpp10 + RATBAG_HIDPP10_PROFILE_COUNT=1 # G9 +# http://support.logitech.com/en_us/product/g9-laser-mouse/specs mouse:usb:v046dpc048:name:*: RATBAG_DRIVER=hidpp10 RATBAG_HIDPP10_DPI_LIST=0;200;400;600;800;1000;1200;1400;1600;1800;2000;2200;2400;2600;2800;3000;3200 RATBAG_HIDPP10_PROFILE=G9 + RATBAG_HIDPP10_PROFILE_COUNT=5 # G9x [Original] +# http://support.logitech.com/en_us/product/g9x-laser-mouse/specs mouse:usb:v046dpc066:name:*: RATBAG_DRIVER=hidpp10 RATBAG_HIDPP10_DPI=0:5700@23.53 RATBAG_HIDPP10_PROFILE=G500 + RATBAG_HIDPP10_PROFILE_COUNT=5 # G9x [Call of Duty MW3 Edition] +# http://support.logitech.com/en_us/product/laser-mouse-g9x/specs mouse:usb:v046dpc249:name:*: RATBAG_DRIVER=hidpp10 RATBAG_HIDPP10_DPI=0:5700@23.53 RATBAG_HIDPP10_PROFILE=G500 + RATBAG_HIDPP10_PROFILE_COUNT=5 # G300 mouse:usb:v046dpc246:name:*: @@ -106,18 +116,22 @@ mouse:usb:v046dpc082:name:*: RATBAG_SVG=logitech-g403.svg # G500 +# http://support.logitech.com/en_us/product/gaming-mouse-g500/specs mouse:usb:v046dpc068:name:*: RATBAG_DRIVER=hidpp10 RATBAG_SVG=logitech-g500.svg RATBAG_HIDPP10_DPI=0:5700@23.53 RATBAG_HIDPP10_PROFILE=G500 + RATBAG_HIDPP10_PROFILE_COUNT=1 # G500s +# http://support.logitech.com/en_us/product/g500s-laser-gaming-mouse/specs mouse:usb:v046dpc24e:name:*: RATBAG_DRIVER=hidpp10 RATBAG_SVG=logitech-g500s.svg RATBAG_HIDPP10_DPI=0:8200@50 RATBAG_HIDPP10_PROFILE=G500 + RATBAG_HIDPP10_PROFILE_COUNT=1 # G502 Proteus Core over USB mouse:usb:v046dpc07d:name:*: @@ -130,33 +144,41 @@ mouse:usb:v046dpc332:name:*: RATBAG_SVG=logitech-g502.svg # G700 over USB +# http://support.logitech.com/en_us/product/wireless-gaming-mouse-g700/specs mouse:usb:v046dpc06b:name:*: RATBAG_DRIVER=hidpp10 RATBAG_SVG=logitech-g700.svg RATBAG_HIDPP10_DPI=0:5700@23.53 RATBAG_HIDPP10_PROFILE=G700 + RATBAG_HIDPP10_PROFILE_COUNT=5 # G700 over wireless USB +# http://support.logitech.com/en_us/product/wireless-gaming-mouse-g700/specs mouse:usb:v046dpc531:name:*: RATBAG_DRIVER=hidpp10 RATBAG_HIDPP10_DPI=0:5700@23.53 RATBAG_HIDPP10_PROFILE=G700 RATBAG_HIDPP10_INDEX=1 + RATBAG_HIDPP10_PROFILE_COUNT=5 # G700s over USB +# http://support.logitech.com/en_us/product/g700s-rechargable-wireless-gaming-mouse/specs mouse:usb:v046dpc07c:name:*: RATBAG_DRIVER=hidpp10 RATBAG_SVG=logitech-g700.svg RATBAG_HIDPP10_DPI=0:8200@50 RATBAG_HIDPP10_PROFILE=G700 + RATBAG_HIDPP10_PROFILE_COUNT=5 # G700s over wireless USB +# http://support.logitech.com/en_us/product/g700s-rechargable-wireless-gaming-mouse/specs mouse:usb:v046dpc531:name:*: RATBAG_DRIVER=hidpp10 RATBAG_SVG=logitech-g700.svg RATBAG_HIDPP10_DPI=0:8200@50 RATBAG_HIDPP10_PROFILE=G700 RATBAG_HIDPP10_INDEX=1 + RATBAG_HIDPP10_PROFILE_COUNT=5 # MX Master over unifying mouse:usb:v046dp4041:name:*: diff --git a/src/driver-hidpp10.c b/src/driver-hidpp10.c index 4b88c3d7..d39d3379 100644 --- a/src/driver-hidpp10.c +++ b/src/driver-hidpp10.c @@ -356,12 +356,12 @@ hidpp10drv_read_profile(struct ratbag_profile *profile, unsigned int index) struct ratbag_device *device = profile->device; struct hidpp10drv_data *drv_data; struct hidpp10_device *hidpp10; - struct hidpp10_profile p; + struct hidpp10_profile p = {0}; struct ratbag_resolution *res; int rc; unsigned int i; uint16_t xres, yres; - int8_t idx; + uint8_t idx; drv_data = ratbag_get_drv_data(device); hidpp10 = drv_data->dev; @@ -369,6 +369,8 @@ hidpp10drv_read_profile(struct ratbag_profile *profile, unsigned int index) if (rc) return; + profile->is_enabled = p.enabled; + rc = hidpp10_get_current_profile(hidpp10, &idx); if (rc == 0 && (unsigned int)idx == profile->index) profile->is_active = true; @@ -458,24 +460,23 @@ static int hidpp10drv_fill_from_profile(struct ratbag_device *device, struct hidpp10_device *dev) { int rc; - struct hidpp10_profile profile; - struct hidpp10_directory directory[16]; - int count; - - count = hidpp10_get_profile_directory(dev, directory, ARRAY_LENGTH(directory)); - if (count < 0) - return count; + struct hidpp10_profile profile = {0}; + unsigned int i; /* We don't know the HID++1.0 requests to query for buttons, etc. - * Simply get the first profile and fill the device information in - * from that. + * Simply get the first enabled profile and fill in the device + * information from that. */ - rc = hidpp10_get_profile(dev, 0, &profile); - if (rc) - return rc; + for (i = 0; i < dev->profile_count; i++) { + rc = hidpp10_get_profile(dev, i, &profile); + if (rc) + return rc; + if (profile.enabled) + break; + } ratbag_device_init_profiles(device, - count, + dev->profile_count, profile.num_dpi_modes, profile.num_buttons, profile.num_leds); @@ -483,6 +484,7 @@ hidpp10drv_fill_from_profile(struct ratbag_device *device, struct hidpp10_device if (dev->profile_type != HIDPP10_PROFILE_UNKNOWN) { ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_PROFILE); ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_SWITCHABLE_PROFILE); + ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_DISABLE_PROFILE); ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_BUTTON); ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_BUTTON_KEY); ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_BUTTON_MACROS); @@ -516,6 +518,7 @@ hidpp10drv_probe(struct ratbag_device *device) const char *prop; int device_idx = HIDPP_WIRED_DEVICE_IDX; int nread = 0; + unsigned int profile_count = 1; rc = ratbag_find_hidraw(device, hidpp10drv_test_hidraw); if (rc) @@ -533,6 +536,10 @@ hidpp10drv_probe(struct ratbag_device *device) type = HIDPP10_PROFILE_G700; else if (strcasecmp("G9", prop) == 0) type = HIDPP10_PROFILE_G9; + + prop = ratbag_device_get_udev_property(device, "RATBAG_HIDPP10_PROFILE_COUNT"); + if (prop) + profile_count = atoi(prop); } prop = ratbag_device_get_udev_property(device, "RATBAG_HIDPP10_INDEX"); @@ -554,7 +561,7 @@ hidpp10drv_probe(struct ratbag_device *device) * If there is a special need like for G700(s), we can pass a * udev prop RATBAG_HIDPP10_INDEX. */ - dev = hidpp10_device_new(&base, device_idx, type); + dev = hidpp10_device_new(&base, device_idx, type, profile_count); if (!dev) { log_error(device->ratbag, @@ -592,6 +599,10 @@ hidpp10drv_probe(struct ratbag_device *device) device->name); } + rc = hidpp10_device_read_profiles(dev); + if (rc) + goto err; + drv_data->dev = dev; ratbag_set_drv_data(device, drv_data); diff --git a/src/hidpp10.c b/src/hidpp10.c index 8fb8ba0c..836fdd0a 100644 --- a/src/hidpp10.c +++ b/src/hidpp10.c @@ -163,9 +163,6 @@ hidpp10_build_dpi_table_from_list(struct hidpp10_device *dev, if (index != count) goto err; - /* mark the state as invalid */ - dev->profile_count = 0; - return 0; err: @@ -203,9 +200,6 @@ hidpp10_build_dpi_table_from_dpi_info(struct hidpp10_device *dev, dev->dpi_table[i].dpi = round((min + step * i) / 25.0f) * 25; } - /* mark the state as invalid */ - dev->profile_count = 0; - return 0; } @@ -720,31 +714,20 @@ hidpp10_get_dpi_value(struct hidpp10_device *dev, uint8_t raw_value) return 0; } -int -hidpp10_get_profile_directory(struct hidpp10_device *dev, - struct hidpp10_directory *out, - size_t nelems) +static int +hidpp10_read_profile_directory(struct hidpp10_device *dev) { unsigned int i; int res; uint8_t bytes[HIDPP10_PAGE_SIZE] = { 0 }; struct hidpp10_directory *directory = (struct hidpp10_directory *)bytes; - size_t count; + unsigned int count; if (dev->profile_type == HIDPP10_PROFILE_UNKNOWN) { hidpp_log_debug(&dev->base, "no profile type given\n"); return 0; } - if (dev->profile_directory) { - count = 0; - while (dev->profile_directory[count].page) { - count++; - } - - goto out; - } - hidpp_log_raw(&dev->base, "Fetching the profiles' directory\n"); res = hidpp10_read_page(dev, 0x01, bytes); @@ -752,46 +735,29 @@ hidpp10_get_profile_directory(struct hidpp10_device *dev, return res; count = 0; - /* assume 16 profiles max */ - for (i = 0; i < 16; i++) { + for (i = 0; i < dev->profile_count; i++) { if (directory[i].page == 0xFF) break; + dev->profiles[i].page = directory[i].page; + dev->profiles[i].offset = directory[i].offset; + dev->profiles[i].enabled = true; count++; } - dev->profile_directory = zalloc((count + 1) * sizeof(struct hidpp10_directory)); - memcpy(dev->profile_directory, directory, count * sizeof(struct hidpp10_directory)); - -out: - if (dev->profile_count != count) { - if (dev->profiles) - free(dev->profiles); - dev->profiles = zalloc(count * sizeof(struct hidpp10_profile)); - dev->profile_count = count; - } - count = min(count, nelems); - memcpy(out, dev->profile_directory, count * sizeof(out[0])); + for (i = count; i < dev->profile_count; i++) + dev->profiles[i].enabled = false; return count; } int -hidpp10_get_current_profile(struct hidpp10_device *dev, int8_t *current_profile) +hidpp10_get_current_profile(struct hidpp10_device *dev, uint8_t *current_profile) { unsigned idx = dev->index; union hidpp10_message profile = CMD_PROFILE(idx, GET_REGISTER_REQ); int res; unsigned i; - int8_t type, page, offset; - struct hidpp10_directory directory[16]; /* completely random profile count */ - int count = 0; - - hidpp_log_raw(&dev->base, "Fetching the profiles' directory\n"); - - count = hidpp10_get_profile_directory(dev, directory, - ARRAY_LENGTH(directory)); - if (count < 0) - return count; + uint8_t type, page, offset; hidpp_log_raw(&dev->base, "Fetching current profile\n"); @@ -806,14 +772,14 @@ hidpp10_get_current_profile(struct hidpp10_device *dev, int8_t *current_profile) *current_profile = page; /* If the profile exceeds the directory length, default to * the first */ - if (*current_profile > count) + if (*current_profile > dev->profile_count) *current_profile = 0; return 0; case PROFILE_TYPE_ADDRESS: offset = profile.msg.parameters[2]; - for (i = 0; i < ARRAY_LENGTH(directory) && directory[i].page < 32; i++) { - if (page == directory[i].page && - offset == directory[i].offset) { + for (i = 0; i < dev->profile_count; i++) { + if (page == dev->profiles[i].page && + offset == dev->profiles[i].offset) { *current_profile = i; return 0; } @@ -833,21 +799,12 @@ hidpp10_get_current_profile(struct hidpp10_device *dev, int8_t *current_profile) static int hidpp10_set_internal_current_profile(struct hidpp10_device *dev, - int16_t current_profile, + uint16_t current_profile, uint8_t profile_type) { unsigned idx = dev->index; union hidpp10_message profile = CMD_PROFILE(idx, SET_REGISTER_REQ); int8_t page, offset; - struct hidpp10_directory directory[16]; /* completely random profile count */ - int count = 0; - - hidpp_log_raw(&dev->base, "Fetching the profiles' directory\n"); - - count = hidpp10_get_profile_directory(dev, directory, - ARRAY_LENGTH(directory)); - if (count < 0) - return count; hidpp_log_raw(&dev->base, "Setting current profile\n"); @@ -855,7 +812,7 @@ hidpp10_set_internal_current_profile(struct hidpp10_device *dev, switch (profile_type) { case PROFILE_TYPE_INDEX: - if (current_profile > count) + if (current_profile > dev->profile_count) return -EINVAL; profile.msg.parameters[1] = current_profile & 0xFF; break; @@ -878,7 +835,7 @@ hidpp10_set_internal_current_profile(struct hidpp10_device *dev, } int -hidpp10_set_current_profile(struct hidpp10_device *dev, int16_t current_profile) +hidpp10_set_current_profile(struct hidpp10_device *dev, uint16_t current_profile) { return hidpp10_set_internal_current_profile(dev, current_profile, @@ -1431,8 +1388,8 @@ hidpp10_profile_set_names(struct hidpp10_device *dev, struct hidpp10_profile *pr } } -int -hidpp10_get_profile(struct hidpp10_device *dev, int8_t number, struct hidpp10_profile *profile_return) +static int +hidpp10_read_profile(struct hidpp10_device *dev, uint8_t number) { uint8_t page_data[HIDPP10_PAGE_SIZE]; union _hidpp10_profile_data *data = (union _hidpp10_profile_data *)page_data; @@ -1442,9 +1399,7 @@ hidpp10_get_profile(struct hidpp10_device *dev, int8_t number, struct hidpp10_pr size_t i; int res; struct hidpp10_profile *profile; - struct hidpp10_directory directory[16]; /* completely random profile count */ union _hidpp10_button_binding *buttons; - int count = 0; uint8_t page; /* Page 0 is RAM @@ -1458,19 +1413,18 @@ hidpp10_get_profile(struct hidpp10_device *dev, int8_t number, struct hidpp10_pr hidpp_log_raw(&dev->base, "Fetching profile %d\n", number); - count = hidpp10_get_profile_directory(dev, directory, - ARRAY_LENGTH(directory)); - if (count < 0) - return count; - - if (count == 0 || dev->profile_type == HIDPP10_PROFILE_UNKNOWN) + if (dev->profile_type == HIDPP10_PROFILE_UNKNOWN) return -ENOTSUP; - if (number >= count) { - hidpp_log_error(&dev->base, "Profile number %d not in the directory.\n", number); + if (number >= dev->profile_count) { + hidpp_log_error(&dev->base, "Profile number %d is not supported.\n", number); return -EINVAL; } + profile = &dev->profiles[number]; + if (!profile->enabled) + return 0; + switch (dev->profile_type) { case HIDPP10_PROFILE_G500: buttons = p500->buttons; @@ -1486,10 +1440,8 @@ hidpp10_get_profile(struct hidpp10_device *dev, int8_t number, struct hidpp10_pr return -EINVAL; } - profile = &dev->profiles[number]; if (!profile->initialized) { - - page = directory[number].page; + page = profile->page; res = hidpp10_read_page(dev, page, page_data); if (res == -EILSEQ) { /* @@ -1597,8 +1549,21 @@ hidpp10_get_profile(struct hidpp10_device *dev, int8_t number, struct hidpp10_pr } } - *profile_return = *profile; + return 0; +} +int +hidpp10_get_profile(struct hidpp10_device *dev, uint8_t number, struct hidpp10_profile *profile_return) +{ + if (dev->profile_type == HIDPP10_PROFILE_UNKNOWN) + return -ENOTSUP; + + if (number >= dev->profile_count) { + hidpp_log_error(&dev->base, "Profile number %d is not supported.\n", number); + return -EINVAL; + } + + *profile_return = dev->profiles[number]; return 0; } @@ -1648,7 +1613,7 @@ hidpp10_onboard_profiles_get_code_from_special(enum ratbag_button_action_special } int -hidpp10_set_profile(struct hidpp10_device *dev, int8_t number, struct hidpp10_profile *profile) +hidpp10_set_profile(struct hidpp10_device *dev, uint8_t number, struct hidpp10_profile *profile) { uint8_t page_data[HIDPP10_PAGE_SIZE]; union _hidpp10_profile_data *data = (union _hidpp10_profile_data *)page_data; @@ -1656,27 +1621,24 @@ hidpp10_set_profile(struct hidpp10_device *dev, int8_t number, struct hidpp10_pr struct _hidpp10_profile_700 *p700 = &data->profile_700; struct _hidpp10_profile_9 *p9 = &data->profile_9; int res; - struct hidpp10_directory directory[16]; /* completely random profile count */ union _hidpp10_button_binding *buttons; - int count = 0; uint16_t crc; uint8_t page; hidpp_log_raw(&dev->base, "Fetching profile %d\n", number); - count = hidpp10_get_profile_directory(dev, directory, - ARRAY_LENGTH(directory)); - if (count < 0) - return count; - - if (count == 0 || dev->profile_type == HIDPP10_PROFILE_UNKNOWN) + if (dev->profile_type == HIDPP10_PROFILE_UNKNOWN) return -ENOTSUP; - if (number >= count) { - hidpp_log_error(&dev->base, "Profile number %d not in the directory.\n", number); + if (number >= dev->profile_count) { + hidpp_log_error(&dev->base, "Profile number %d is incorrect.\n", number); return -EINVAL; } + /* we do not support not enabled profiles just now */ + if (!profile->page) + return -ENOTSUP; + memset(page_data, 0xff, sizeof(page_data)); switch (dev->profile_type) { @@ -1702,7 +1664,7 @@ hidpp10_set_profile(struct hidpp10_device *dev, int8_t number, struct hidpp10_pr case HIDPP10_PROFILE_G9: /* we do not know the actual values of the remaining field right now * so pre-fill with the current data */ - res = hidpp10_read_page(dev, directory[number].page, page_data); + res = hidpp10_read_page(dev, profile->page, page_data); if (res) return res; break; @@ -1779,7 +1741,7 @@ hidpp10_set_profile(struct hidpp10_device *dev, int8_t number, struct hidpp10_pr if (res < 0) return res; - page = directory[number].page; + page = profile->page; /* according to the spec, a profile can have an offset. * For all the devices we know, they all start at 0x0000 */ res = hidpp10_erase_memory(dev, page); @@ -1811,6 +1773,7 @@ hidpp10_set_profile(struct hidpp10_device *dev, int8_t number, struct hidpp10_pr if (res < 0) return res; + dev->profiles[number] = *profile; return res; } @@ -2655,14 +2618,10 @@ hidpp10_get_device_info(struct hidpp10_device *dev) { uint32_t feature_mask, notifications; uint8_t reflect; - int i; uint16_t xres, yres; uint16_t refresh_rate; enum hidpp10_led_status led[6]; - int8_t current_profile; - struct hidpp10_profile profiles[HIDPP10_NUM_PROFILES]; - int count; - struct hidpp10_directory directory[16]; + uint8_t current_profile; hidpp10_get_individual_features(dev, &feature_mask); hidpp10_get_hidpp_notifications(dev, ¬ifications); @@ -2674,18 +2633,14 @@ hidpp10_get_device_info(struct hidpp10_device *dev) hidpp10_get_optical_sensor_settings(dev, &reflect); hidpp10_get_current_profile(dev, ¤t_profile); - - count = hidpp10_get_profile_directory(dev, directory, - ARRAY_LENGTH(directory)); - for (i = 0; i < count && i < HIDPP10_NUM_PROFILES; i++) - hidpp10_get_profile(dev, i, &profiles[i]); - return 0; } struct hidpp10_device* -hidpp10_device_new(const struct hidpp_device *base, int idx, - enum hidpp10_profile_type type) +hidpp10_device_new(const struct hidpp_device *base, + int idx, + enum hidpp10_profile_type type, + unsigned int profile_count) { struct hidpp10_device *dev; @@ -2694,6 +2649,8 @@ hidpp10_device_new(const struct hidpp_device *base, int idx, dev->index = idx; dev->base = *base; dev->profile_type = type; + dev->profile_count = profile_count; + dev->profiles = zalloc(dev->profile_count * sizeof(struct hidpp10_profile)); if (hidpp10_get_device_info(dev) != 0) { hidpp10_device_destroy(dev); @@ -2703,6 +2660,19 @@ hidpp10_device_new(const struct hidpp_device *base, int idx, return dev; } +int +hidpp10_device_read_profiles(struct hidpp10_device *dev) +{ + unsigned int i; + + hidpp10_read_profile_directory(dev); + + for (i = 0; i < dev->profile_count && i < HIDPP10_NUM_PROFILES; i++) + hidpp10_read_profile(dev, i); + + return 0; +} + void hidpp10_device_destroy(struct hidpp10_device *dev) { @@ -2711,19 +2681,15 @@ hidpp10_device_destroy(struct hidpp10_device *dev) if (dev->dpi_table) free(dev->dpi_table); - if (dev->profile_directory) - free(dev->profile_directory); - if (dev->profiles) { - for (i = 0; i < dev->profile_count; i++) { - ARRAY_FOR_EACH(dev->profiles[i].macros, macro) { - if (*macro) { - free(*macro); - *macro = NULL; - } + for (i = 0; i < dev->profile_count; i++) { + ARRAY_FOR_EACH(dev->profiles[i].macros, macro) { + if (*macro) { + free(*macro); + *macro = NULL; } } - - free(dev->profiles); } + + free(dev->profiles); free(dev); } diff --git a/src/hidpp10.h b/src/hidpp10.h index 855c409b..8df467e1 100644 --- a/src/hidpp10.h +++ b/src/hidpp10.h @@ -59,15 +59,19 @@ struct hidpp10_device { unsigned index; uint8_t dpi_count; struct hidpp10_dpi_mapping *dpi_table; - struct hidpp10_directory *profile_directory; /* must be null terminated */ enum hidpp10_profile_type profile_type; struct hidpp10_profile *profiles; unsigned int profile_count; }; struct hidpp10_device* -hidpp10_device_new(const struct hidpp_device *base, int idx, - enum hidpp10_profile_type type); +hidpp10_device_new(const struct hidpp_device *base, + int idx, + enum hidpp10_profile_type type, + unsigned int profile_count); + +int +hidpp10_device_read_profiles(struct hidpp10_device *dev); void hidpp10_device_destroy(struct hidpp10_device *dev); @@ -463,6 +467,8 @@ union hidpp10_macro_data { _Static_assert(sizeof(union hidpp10_macro_data) == 5, "Invalid size"); struct hidpp10_profile { + uint8_t page; + uint8_t offset; struct { uint16_t xres; uint16_t yres; @@ -512,6 +518,7 @@ struct hidpp10_profile { size_t num_leds; unsigned int initialized; + bool enabled; }; struct hidpp10_directory { @@ -521,22 +528,17 @@ struct hidpp10_directory { } __attribute__((packed)); int -hidpp10_get_profile_directory(struct hidpp10_device *dev, - struct hidpp10_directory *out, - size_t nelems); +hidpp10_get_current_profile(struct hidpp10_device *dev, uint8_t *current_profile); int -hidpp10_get_current_profile(struct hidpp10_device *dev, int8_t *current_profile); +hidpp10_set_current_profile(struct hidpp10_device *dev, uint16_t current_profile); int -hidpp10_set_current_profile(struct hidpp10_device *dev, int16_t current_profile); - -int -hidpp10_get_profile(struct hidpp10_device *dev, int8_t number, +hidpp10_get_profile(struct hidpp10_device *dev, uint8_t number, struct hidpp10_profile *profile); int -hidpp10_set_profile(struct hidpp10_device *dev, int8_t number, +hidpp10_set_profile(struct hidpp10_device *dev, uint8_t number, struct hidpp10_profile *profile); enum ratbag_button_action_special diff --git a/src/liblur.c b/src/liblur.c index d15e074b..06fef169 100644 --- a/src/liblur.c +++ b/src/liblur.c @@ -146,7 +146,7 @@ hidpp10_init(int fd) hidpp_device_init(&base, fd); return hidpp10_device_new(&base, HIDPP_RECEIVER_IDX, - HIDPP10_PROFILE_UNKNOWN); + HIDPP10_PROFILE_UNKNOWN, 1); } _EXPORT_ int @@ -201,8 +201,7 @@ lur_receiver_enumerate(struct lur_receiver *lur, uint32_t serial; bool is_new_device = true; - d = hidpp10_device_new(&base, i, - HIDPP10_PROFILE_UNKNOWN); + d = hidpp10_device_new(&base, i, HIDPP10_PROFILE_UNKNOWN, 1); if (!d) continue; diff --git a/tools/hidpp10-dump-page.c b/tools/hidpp10-dump-page.c index a497f8db..8bc3dd03 100644 --- a/tools/hidpp10-dump-page.c +++ b/tools/hidpp10-dump-page.c @@ -98,7 +98,7 @@ main(int argc, char **argv) error(1, errno, "Failed to open path %s", path); hidpp_device_init(&base, fd); - dev = hidpp10_device_new(&base, HIDPP_WIRED_DEVICE_IDX, HIDPP10_PROFILE_UNKNOWN); + dev = hidpp10_device_new(&base, HIDPP_WIRED_DEVICE_IDX, HIDPP10_PROFILE_UNKNOWN, 5); if (argc == 2) rc = dump_all_pages(dev);