Skip to content

Commit

Permalink
Merge branch 'for-4.20/logitech-highres' into for-linus
Browse files Browse the repository at this point in the history
High-resolution support for hid-logitech
  • Loading branch information
Jiri Kosina committed Oct 23, 2018
2 parents 4e7be68 + d9ca1c9 commit 276e722
Show file tree
Hide file tree
Showing 5 changed files with 383 additions and 28 deletions.
11 changes: 10 additions & 1 deletion Documentation/input/event-codes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,16 @@ A few EV_REL codes have special meanings:
* REL_WHEEL, REL_HWHEEL:

- These codes are used for vertical and horizontal scroll wheels,
respectively.
respectively. The value is the number of "notches" moved on the wheel, the
physical size of which varies by device. For high-resolution wheels (which
report multiple events for each notch of movement, or do not have notches)
this may be an approximation based on the high-resolution scroll events.

* REL_WHEEL_HI_RES:

- If a vertical scroll wheel supports high-resolution scrolling, this code
will be emitted in addition to REL_WHEEL. The value is the (approximate)
distance travelled by the user's finger, in microns.

EV_ABS
------
Expand Down
45 changes: 45 additions & 0 deletions drivers/hid/hid-input.c
Original file line number Diff line number Diff line change
Expand Up @@ -1838,3 +1838,48 @@ void hidinput_disconnect(struct hid_device *hid)
}
EXPORT_SYMBOL_GPL(hidinput_disconnect);

/**
* hid_scroll_counter_handle_scroll() - Send high- and low-resolution scroll
* events given a high-resolution wheel
* movement.
* @counter: a hid_scroll_counter struct describing the wheel.
* @hi_res_value: the movement of the wheel, in the mouse's high-resolution
* units.
*
* Given a high-resolution movement, this function converts the movement into
* microns and emits high-resolution scroll events for the input device. It also
* uses the multiplier from &struct hid_scroll_counter to emit low-resolution
* scroll events when appropriate for backwards-compatibility with userspace
* input libraries.
*/
void hid_scroll_counter_handle_scroll(struct hid_scroll_counter *counter,
int hi_res_value)
{
int low_res_scroll_amount;
/* Some wheels will rest 7/8ths of a notch from the previous notch
* after slow movement, so we want the threshold for low-res events to
* be in the middle of the notches (e.g. after 4/8ths) as opposed to on
* the notches themselves (8/8ths).
*/
int threshold = counter->resolution_multiplier / 2;

input_report_rel(counter->dev, REL_WHEEL_HI_RES,
hi_res_value * counter->microns_per_hi_res_unit);

counter->remainder += hi_res_value;
if (abs(counter->remainder) >= threshold) {
/* Add (or subtract) 1 because we want to trigger when the wheel
* is half-way to the next notch (i.e. scroll 1 notch after a
* 1/2 notch movement, 2 notches after a 1 1/2 notch movement,
* etc.).
*/
low_res_scroll_amount =
counter->remainder / counter->resolution_multiplier
+ (hi_res_value > 0 ? 1 : -1);
input_report_rel(counter->dev, REL_WHEEL,
low_res_scroll_amount);
counter->remainder -=
low_res_scroll_amount * counter->resolution_multiplier;
}
}
EXPORT_SYMBOL_GPL(hid_scroll_counter_handle_scroll);
Loading

0 comments on commit 276e722

Please sign in to comment.