Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions src/hid_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,29 @@ void handle_main_input(parser_state_t *parser, item_t *item, hid_interface_t *if
*parser->p_usage = *(parser->p_usage - parser->usage_count);
}

/* Detect Resolution Multiplier in Feature items, store logical_max+1 as divider.
First occurrence only — subsequent multipliers for horizontal scroll are ignored. */
static void detect_resolution_multiplier(parser_state_t *parser, hid_interface_t *iface) {
if (parser->global_usage != HID_USAGE_DESKTOP_MOUSE)
return;

for (int i = 0; i < parser->usage_count; i++) {
if (parser->usages[i] == HID_USAGE_DESKTOP_RESOLUTION_MULTIPLIER) {
if (iface->mouse.has_resolution_multiplier)
return;

int32_t logical_max = parser->globals[RI_GLOBAL_LOGICAL_MAX].val;

if (logical_max < 0 || logical_max > 254)
return;

iface->mouse.has_resolution_multiplier = true;
iface->mouse.wheel_divider = (uint8_t)(logical_max + 1);
return;
}
}
}

void handle_main_item(parser_state_t *parser, item_t *item, hid_interface_t *iface) {
switch (item->hdr.tag) {
case RI_MAIN_COLLECTION:
Expand All @@ -154,6 +177,10 @@ void handle_main_item(parser_state_t *parser, item_t *item, hid_interface_t *ifa
case RI_MAIN_INPUT:
handle_main_input(parser, item, iface);
break;

case RI_MAIN_FEATURE:
detect_resolution_multiplier(parser, iface);
break;
}

parser->usage_count = 0;
Expand Down
4 changes: 4 additions & 0 deletions src/include/hid_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,10 @@ typedef struct {

bool is_found;
bool uses_report_id;

/* High-resolution scroll detection from mouse HID descriptor */
bool has_resolution_multiplier;
uint8_t wheel_divider;
} mouse_t;

typedef struct hid_interface_t hid_interface_t;
Expand Down
7 changes: 7 additions & 0 deletions src/mouse.c
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,13 @@ void extract_report_values(uint8_t *raw_report, int len, device_t *state, mouse_
extract_value(uses_id, &values->wheel, &mouse->wheel, raw_report, len);
extract_value(uses_id, &values->pan, &mouse->pan, raw_report, len);

/* Normalize hi-res scroll to standard notches. Standard mice have
wheel_divider == 0 (memset), pass through unchanged. */
if (mouse->has_resolution_multiplier && mouse->wheel_divider > 1u) {
values->wheel /= (int32_t)mouse->wheel_divider;
values->pan /= (int32_t)mouse->wheel_divider;
}

if (!extract_value(uses_id, &values->buttons, &mouse->buttons, raw_report, len)) {
values->buttons = state->mouse_buttons;
}
Expand Down