diff --git a/src/driver-logitech-unifying.c b/src/driver-logitech-unifying.c index 3cdbaee9..d5be4860 100644 --- a/src/driver-logitech-unifying.c +++ b/src/driver-logitech-unifying.c @@ -48,9 +48,12 @@ #include "libratbag-private.h" #include "libratbag-hidraw.h" +#define HIDPP_CAP_RESOLUTION_2200 (1 << 0) + struct unifying_data { unsigned proto_major; unsigned proto_minor; + unsigned long capabilities; }; static void @@ -93,6 +96,34 @@ unifying_write_profile(struct ratbag_profile *profile) return -1; } +static int +unifying_init_feature(struct ratbag_device *device, uint16_t feature) +{ + struct unifying_data *drv_data = ratbag_get_drv_data(device); + int rc; + + switch (feature) { + case 0x0000: + case 0x0001: + /* these features are mandatory and already handled */ + break; + case 0x2200: { + uint16_t resolution; + uint8_t flags; + + drv_data->capabilities |= HIDPP_CAP_RESOLUTION_2200; + rc = hidpp20_mousepointer_get_mousepointer_info(device, &resolution, &flags); + if (rc) + return rc; + log_info(device->ratbag, "device is at %d dpi\n", resolution); + break; + } + default: + log_info(device->ratbag, "unknown feature 0x%04x\n", feature); + } + return 0; +} + static int unifying_20_probe(struct ratbag_device *device, const struct ratbag_id id) { @@ -104,9 +135,10 @@ unifying_20_probe(struct ratbag_device *device, const struct ratbag_id id) return rc; if (rc > 0) { - log_info(device->ratbag, "'%s' has %d features:\n", ratbag_device_get_name(device), rc); + log_debug(device->ratbag, "'%s' has %d features\n", ratbag_device_get_name(device), rc); for (i = 0; i < rc; i++) { - log_info(device->ratbag, "0x%04x\n", feature_list[i].feature); + log_debug(device->ratbag, "0x%04x\n", feature_list[i].feature); + unifying_init_feature(device, feature_list[i].feature); } } diff --git a/src/hidpp20.c b/src/hidpp20.c index fa1111fa..a074adbf 100644 --- a/src/hidpp20.c +++ b/src/hidpp20.c @@ -288,3 +288,45 @@ err: free(flist); return rc; } + +/* -------------------------------------------------------------------------- */ +/* 0x2200: Mouse Pointer Basic Optical Sensors */ +/* -------------------------------------------------------------------------- */ + +#define HIDPP_PAGE_MOUSE_POINTER_BASIC 0x2200 + +#define CMD_MOUSE_POINTER_BASIC_GET_INFO 0x08 +int +hidpp20_mousepointer_get_mousepointer_info(struct ratbag_device *device, + uint16_t *resolution, + uint8_t *flags) +{ + uint8_t feature_index, feature_type, feature_version; + union hidpp20_message msg = { + .msg.report_id = REPORT_ID_LONG, + .msg.device_idx = 0xff, + .msg.address = CMD_FEATURE_SET_GET_FEATURE_ID, + .msg.parameters[0] = feature_index, + }; + int rc; + + + rc = hidpp_root_get_feature(device, + HIDPP_PAGE_MOUSE_POINTER_BASIC, + &feature_index, + &feature_type, + &feature_version); + if (rc) + return rc; + + msg.msg.sub_id = feature_index; + + rc = hidpp20_request_command(device, &msg); + if (rc) + return rc; + + *resolution = (msg.msg.parameters[0] << 8) | msg.msg.parameters[1]; + *flags = msg.msg.parameters[2]; + + return 0; +} diff --git a/src/hidpp20.h b/src/hidpp20.h index 40be3bcd..54917341 100644 --- a/src/hidpp20.h +++ b/src/hidpp20.h @@ -77,4 +77,21 @@ struct hidpp20_feature { int hidpp20_feature_set_get(struct ratbag_device *device, struct hidpp20_feature **feature_list); +/* -------------------------------------------------------------------------- */ +/* 0x2200: Mouse Pointer Basic Optical Sensors */ +/* -------------------------------------------------------------------------- */ + +#define HIDDP20_MOUSE_POINTER_FLAGS_VERTICAL_TUNING (1 << 4) +#define HIDDP20_MOUSE_POINTER_FLAGS_OS_BALLISTICS (1 << 3) + +#define HIDDP20_MOUSE_POINTER_FLAGS_ACCELERATION_MASK 0x03 +#define HIDDP20_MOUSE_POINTER_ACCELERATION_NONE 0x00 +#define HIDDP20_MOUSE_POINTER_ACCELERATION_LOW 0x01 +#define HIDDP20_MOUSE_POINTER_ACCELERATION_MEDIUM 0x02 +#define HIDDP20_MOUSE_POINTER_ACCELERATION_HIGH 0x03 + +int hidpp20_mousepointer_get_mousepointer_info(struct ratbag_device *device, + uint16_t *resolution, + uint8_t *flags); + #endif /* HIDPP_20_H */