summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosé Expósito <jose.exposito89@gmail.com>2021-09-26 18:15:51 +0200
committerJosé Expósito <jose.exposito89@gmail.com>2021-11-08 18:00:34 +0100
commit4e52f0358056aaaee269a98c0f8bdb7e30c6342e (patch)
treef0f4b370cf1343f21fb5f61464408f7d37da372a
parent5e44861e0ed7fdb447170a03adb9ff361ae6e4ce (diff)
downloadlibinput-4e52f0358056aaaee269a98c0f8bdb7e30c6342e.tar.gz
wheel: centralize wheel handling
Move the logic to handle wheels to its own file. Refactor, no functional changes. Signed-off-by: José Expósito <jose.exposito89@gmail.com>
-rw-r--r--meson.build1
-rw-r--r--src/evdev-fallback.c171
-rw-r--r--src/evdev-fallback.h25
-rw-r--r--src/evdev-wheel.c207
4 files changed, 244 insertions, 160 deletions
diff --git a/meson.build b/meson.build
index 4269e39d..a423a962 100644
--- a/meson.build
+++ b/meson.build
@@ -368,6 +368,7 @@ src_libinput = src_libfilter + [
'src/evdev-tablet-pad.c',
'src/evdev-tablet-pad.h',
'src/evdev-tablet-pad-leds.c',
+ 'src/evdev-wheel.c',
'src/path-seat.c',
'src/udev-seat.c',
'src/udev-seat.h',
diff --git a/src/evdev-fallback.c b/src/evdev-fallback.c
index 785ac6e2..19ae4a0a 100644
--- a/src/evdev-fallback.c
+++ b/src/evdev-fallback.c
@@ -68,18 +68,8 @@ fallback_notify_physical_button(struct fallback_dispatch *dispatch,
int button,
enum libinput_button_state state)
{
- if (button == BTN_MIDDLE)
- dispatch->wheel.is_inhibited = (state == LIBINPUT_BUTTON_STATE_PRESSED);
-
- /* Lenovo TrackPoint Keyboard II sends its own scroll events when its
- * trackpoint is moved while the middle button is pressed.
- * Do not inhibit the scroll events.
- * https://gitlab.freedesktop.org/libinput/libinput/-/issues/651
- */
- if (evdev_device_has_model_quirk(device,
- QUIRK_MODEL_LENOVO_TRACKPOINT_KEYBOARD_2))
- dispatch->wheel.is_inhibited = false;
-
+ fallback_wheel_notify_physical_button(dispatch, device, time,
+ button, state);
evdev_pointer_notify_physical_button(device, time, button, state);
}
@@ -102,10 +92,10 @@ fallback_interface_get_switch_state(struct evdev_dispatch *evdev_dispatch,
LIBINPUT_SWITCH_STATE_OFF;
}
-static inline void
-normalize_delta(struct evdev_device *device,
- const struct device_coords *delta,
- struct normalized_coords *normalized)
+void
+fallback_normalize_delta(struct evdev_device *device,
+ const struct device_coords *delta,
+ struct normalized_coords *normalized)
{
normalized->x = delta->x * DEFAULT_MOUSE_DPI / (double)device->dpi;
normalized->y = delta->y * DEFAULT_MOUSE_DPI / (double)device->dpi;
@@ -195,7 +185,7 @@ fallback_flush_relative_motion(struct fallback_dispatch *dispatch,
fallback_rotate_relative(dispatch, device);
- normalize_delta(device, &dispatch->rel, &unaccel);
+ fallback_normalize_delta(device, &dispatch->rel, &unaccel);
raw.x = dispatch->rel.x;
raw.y = dispatch->rel.y;
dispatch->rel.x = 0;
@@ -224,110 +214,6 @@ fallback_flush_relative_motion(struct fallback_dispatch *dispatch,
}
static void
-fallback_flush_wheels(struct fallback_dispatch *dispatch,
- struct evdev_device *device,
- uint64_t time)
-{
- struct normalized_coords wheel_degrees = { 0.0, 0.0 };
- struct discrete_coords discrete = { 0.0, 0.0 };
- struct wheel_v120 v120 = { 0.0, 0.0 };
-
- if (!(device->seat_caps & EVDEV_DEVICE_POINTER))
- return;
-
- if (!dispatch->wheel.emulate_hi_res_wheel &&
- !dispatch->wheel.hi_res_event_received &&
- (dispatch->wheel.lo_res.x != 0 || dispatch->wheel.lo_res.y != 0)) {
- evdev_log_bug_kernel(device,
- "device supports high-resolution scroll but only low-resolution events have been received.\n"
- "See %s/incorrectly-enabled-hires.html for details\n",
- HTTP_DOC_LINK);
- dispatch->wheel.emulate_hi_res_wheel = true;
- dispatch->wheel.hi_res.x = dispatch->wheel.lo_res.x * 120;
- dispatch->wheel.hi_res.y = dispatch->wheel.lo_res.y * 120;
- }
-
- if (dispatch->wheel.is_inhibited) {
- dispatch->wheel.hi_res.x = 0;
- dispatch->wheel.hi_res.y = 0;
- dispatch->wheel.lo_res.x = 0;
- dispatch->wheel.lo_res.y = 0;
- return;
- }
-
- if (device->model_flags & EVDEV_MODEL_LENOVO_SCROLLPOINT) {
- struct normalized_coords unaccel = { 0.0, 0.0 };
-
- dispatch->wheel.hi_res.y *= -1;
- normalize_delta(device, &dispatch->wheel.hi_res, &unaccel);
- evdev_post_scroll(device,
- time,
- LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS,
- &unaccel);
- dispatch->wheel.hi_res.x = 0;
- dispatch->wheel.hi_res.y = 0;
-
- return;
- }
-
- if (dispatch->wheel.hi_res.y != 0) {
- int value = dispatch->wheel.hi_res.y;
-
- v120.y = -1 * value;
- wheel_degrees.y = -1 * value/120.0 * device->scroll.wheel_click_angle.y;
- evdev_notify_axis_wheel(
- device,
- time,
- bit(LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL),
- &wheel_degrees,
- &v120);
- dispatch->wheel.hi_res.y = 0;
- }
-
- if (dispatch->wheel.lo_res.y != 0) {
- int value = dispatch->wheel.lo_res.y;
-
- wheel_degrees.y = -1 * value * device->scroll.wheel_click_angle.y;
- discrete.y = -1 * value;
- evdev_notify_axis_legacy_wheel(
- device,
- time,
- bit(LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL),
- &wheel_degrees,
- &discrete);
- dispatch->wheel.lo_res.y = 0;
- }
-
- if (dispatch->wheel.hi_res.x != 0) {
- int value = dispatch->wheel.hi_res.x;
-
- v120.x = value;
- wheel_degrees.x = value/120.0 * device->scroll.wheel_click_angle.x;
- evdev_notify_axis_wheel(
- device,
- time,
- bit(LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL),
- &wheel_degrees,
- &v120);
- dispatch->wheel.hi_res.x = 0;
- }
-
- if (dispatch->wheel.lo_res.x != 0) {
- int value = dispatch->wheel.lo_res.x;
-
- wheel_degrees.x = value * device->scroll.wheel_click_angle.x;
- discrete.x = value;
- evdev_notify_axis_legacy_wheel(
- device,
- time,
- bit(LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL),
- &wheel_degrees,
- &discrete);
- dispatch->wheel.lo_res.x = 0;
- }
-}
-
-static void
fallback_flush_absolute_motion(struct fallback_dispatch *dispatch,
struct evdev_device *device,
uint64_t time)
@@ -895,29 +781,9 @@ fallback_process_relative(struct fallback_dispatch *dispatch,
dispatch->rel.y += e->value;
dispatch->pending_event |= EVDEV_RELATIVE_MOTION;
break;
- case REL_WHEEL:
- dispatch->wheel.lo_res.y += e->value;
- if (dispatch->wheel.emulate_hi_res_wheel)
- dispatch->wheel.hi_res.y += e->value * 120;
- dispatch->pending_event |= EVDEV_WHEEL;
- break;
- case REL_HWHEEL:
- dispatch->wheel.lo_res.x += e->value;
- if (dispatch->wheel.emulate_hi_res_wheel)
- dispatch->wheel.hi_res.x += e->value * 120;
- dispatch->pending_event |= EVDEV_WHEEL;
- break;
- case REL_WHEEL_HI_RES:
- dispatch->wheel.hi_res.y += e->value;
- dispatch->wheel.hi_res_event_received = true;
- dispatch->pending_event |= EVDEV_WHEEL;
- break;
- case REL_HWHEEL_HI_RES:
- dispatch->wheel.hi_res.x += e->value;
- dispatch->wheel.hi_res_event_received = true;
- dispatch->pending_event |= EVDEV_WHEEL;
- break;
}
+
+ fallback_wheel_process_relative(dispatch, device, e, time);
}
static inline void
@@ -1079,7 +945,7 @@ fallback_handle_state(struct fallback_dispatch *dispatch,
if (need_touch_frame)
touch_notify_frame(&device->base, time);
- fallback_flush_wheels(dispatch, device, time);
+ fallback_wheel_handle_state(dispatch, device, time);
/* Buttons and keys */
if (dispatch->pending_event & EVDEV_KEY) {
@@ -1827,22 +1693,7 @@ fallback_dispatch_create(struct libinput_device *libinput_device)
want_config);
}
- /* On kernel < 5.0 we need to emulate high-resolution
- wheel scroll events */
- if ((libevdev_has_event_code(device->evdev,
- EV_REL,
- REL_WHEEL) &&
- !libevdev_has_event_code(device->evdev,
- EV_REL,
- REL_WHEEL_HI_RES)) ||
- (libevdev_has_event_code(device->evdev,
- EV_REL,
- REL_HWHEEL) &&
- !libevdev_has_event_code(device->evdev,
- EV_REL,
- REL_HWHEEL_HI_RES)))
- dispatch->wheel.emulate_hi_res_wheel = true;
-
+ fallback_init_wheel(dispatch, device);
fallback_init_debounce(dispatch);
fallback_init_arbitration(dispatch, device);
diff --git a/src/evdev-fallback.h b/src/evdev-fallback.h
index e8c20631..3b3e3188 100644
--- a/src/evdev-fallback.h
+++ b/src/evdev-fallback.h
@@ -254,5 +254,30 @@ fallback_notify_physical_button(struct fallback_dispatch *dispatch,
uint64_t time,
int button,
enum libinput_button_state state);
+void
+fallback_normalize_delta(struct evdev_device *device,
+ const struct device_coords *delta,
+ struct normalized_coords *normalized);
+
+void
+fallback_init_wheel(struct fallback_dispatch *dispatch,
+ struct evdev_device *device);
+
+void
+fallback_wheel_notify_physical_button(struct fallback_dispatch *dispatch,
+ struct evdev_device *device,
+ uint64_t time,
+ int button,
+ enum libinput_button_state state);
+
+void
+fallback_wheel_process_relative(struct fallback_dispatch *dispatch,
+ struct evdev_device *device,
+ struct input_event *e, uint64_t time);
+
+void
+fallback_wheel_handle_state(struct fallback_dispatch *dispatch,
+ struct evdev_device *device,
+ uint64_t time);
#endif
diff --git a/src/evdev-wheel.c b/src/evdev-wheel.c
new file mode 100644
index 00000000..5cbaf3b9
--- /dev/null
+++ b/src/evdev-wheel.c
@@ -0,0 +1,207 @@
+/*
+ * Copyright © 2010 Intel Corporation
+ * Copyright © 2013 Jonas Ådahl
+ * Copyright © 2013-2017 Red Hat, Inc.
+ * Copyright © 2017 James Ye <jye836@gmail.com>
+ * Copyright © 2021 José Expósito
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include "config.h"
+
+#include "evdev-fallback.h"
+#include "util-input-event.h"
+
+void
+fallback_wheel_process_relative(struct fallback_dispatch *dispatch,
+ struct evdev_device *device,
+ struct input_event *e, uint64_t time)
+{
+ switch (e->code) {
+ case REL_WHEEL:
+ dispatch->wheel.lo_res.y += e->value;
+ if (dispatch->wheel.emulate_hi_res_wheel)
+ dispatch->wheel.hi_res.y += e->value * 120;
+ dispatch->pending_event |= EVDEV_WHEEL;
+ break;
+ case REL_HWHEEL:
+ dispatch->wheel.lo_res.x += e->value;
+ if (dispatch->wheel.emulate_hi_res_wheel)
+ dispatch->wheel.hi_res.x += e->value * 120;
+ dispatch->pending_event |= EVDEV_WHEEL;
+ break;
+ case REL_WHEEL_HI_RES:
+ dispatch->wheel.hi_res.y += e->value;
+ dispatch->wheel.hi_res_event_received = true;
+ dispatch->pending_event |= EVDEV_WHEEL;
+ break;
+ case REL_HWHEEL_HI_RES:
+ dispatch->wheel.hi_res.x += e->value;
+ dispatch->wheel.hi_res_event_received = true;
+ dispatch->pending_event |= EVDEV_WHEEL;
+ break;
+ }
+}
+
+void
+fallback_wheel_notify_physical_button(struct fallback_dispatch *dispatch,
+ struct evdev_device *device,
+ uint64_t time,
+ int button,
+ enum libinput_button_state state)
+{
+ if (button == BTN_MIDDLE)
+ dispatch->wheel.is_inhibited = (state == LIBINPUT_BUTTON_STATE_PRESSED);
+
+ /* Lenovo TrackPoint Keyboard II sends its own scroll events when its
+ * trackpoint is moved while the middle button is pressed.
+ * Do not inhibit the scroll events.
+ * https://gitlab.freedesktop.org/libinput/libinput/-/issues/651
+ */
+ if (evdev_device_has_model_quirk(device,
+ QUIRK_MODEL_LENOVO_TRACKPOINT_KEYBOARD_2))
+ dispatch->wheel.is_inhibited = false;
+}
+
+void
+fallback_wheel_handle_state(struct fallback_dispatch *dispatch,
+ struct evdev_device *device,
+ uint64_t time)
+{
+ struct normalized_coords wheel_degrees = { 0.0, 0.0 };
+ struct discrete_coords discrete = { 0.0, 0.0 };
+ struct wheel_v120 v120 = { 0.0, 0.0 };
+
+ if (!(device->seat_caps & EVDEV_DEVICE_POINTER))
+ return;
+
+ if (!dispatch->wheel.emulate_hi_res_wheel &&
+ !dispatch->wheel.hi_res_event_received &&
+ (dispatch->wheel.lo_res.x != 0 || dispatch->wheel.lo_res.y != 0)) {
+ evdev_log_bug_kernel(device,
+ "device supports high-resolution scroll but only low-resolution events have been received.\n"
+ "See %s/incorrectly-enabled-hires.html for details\n",
+ HTTP_DOC_LINK);
+ dispatch->wheel.emulate_hi_res_wheel = true;
+ dispatch->wheel.hi_res.x = dispatch->wheel.lo_res.x * 120;
+ dispatch->wheel.hi_res.y = dispatch->wheel.lo_res.y * 120;
+ }
+
+ if (dispatch->wheel.is_inhibited) {
+ dispatch->wheel.hi_res.x = 0;
+ dispatch->wheel.hi_res.y = 0;
+ dispatch->wheel.lo_res.x = 0;
+ dispatch->wheel.lo_res.y = 0;
+ return;
+ }
+
+ if (device->model_flags & EVDEV_MODEL_LENOVO_SCROLLPOINT) {
+ struct normalized_coords unaccel = { 0.0, 0.0 };
+
+ dispatch->wheel.hi_res.y *= -1;
+ fallback_normalize_delta(device, &dispatch->wheel.hi_res, &unaccel);
+ evdev_post_scroll(device,
+ time,
+ LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS,
+ &unaccel);
+ dispatch->wheel.hi_res.x = 0;
+ dispatch->wheel.hi_res.y = 0;
+
+ return;
+ }
+
+ if (dispatch->wheel.hi_res.y != 0) {
+ int value = dispatch->wheel.hi_res.y;
+
+ v120.y = -1 * value;
+ wheel_degrees.y = -1 * value/120.0 * device->scroll.wheel_click_angle.y;
+ evdev_notify_axis_wheel(
+ device,
+ time,
+ bit(LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL),
+ &wheel_degrees,
+ &v120);
+ dispatch->wheel.hi_res.y = 0;
+ }
+
+ if (dispatch->wheel.lo_res.y != 0) {
+ int value = dispatch->wheel.lo_res.y;
+
+ wheel_degrees.y = -1 * value * device->scroll.wheel_click_angle.y;
+ discrete.y = -1 * value;
+ evdev_notify_axis_legacy_wheel(
+ device,
+ time,
+ bit(LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL),
+ &wheel_degrees,
+ &discrete);
+ dispatch->wheel.lo_res.y = 0;
+ }
+
+ if (dispatch->wheel.hi_res.x != 0) {
+ int value = dispatch->wheel.hi_res.x;
+
+ v120.x = value;
+ wheel_degrees.x = value/120.0 * device->scroll.wheel_click_angle.x;
+ evdev_notify_axis_wheel(
+ device,
+ time,
+ bit(LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL),
+ &wheel_degrees,
+ &v120);
+ dispatch->wheel.hi_res.x = 0;
+ }
+
+ if (dispatch->wheel.lo_res.x != 0) {
+ int value = dispatch->wheel.lo_res.x;
+
+ wheel_degrees.x = value * device->scroll.wheel_click_angle.x;
+ discrete.x = value;
+ evdev_notify_axis_legacy_wheel(
+ device,
+ time,
+ bit(LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL),
+ &wheel_degrees,
+ &discrete);
+ dispatch->wheel.lo_res.x = 0;
+ }
+}
+
+void
+fallback_init_wheel(struct fallback_dispatch *dispatch,
+ struct evdev_device *device)
+{
+ /* On kernel < 5.0 we need to emulate high-resolution
+ wheel scroll events */
+ if ((libevdev_has_event_code(device->evdev,
+ EV_REL,
+ REL_WHEEL) &&
+ !libevdev_has_event_code(device->evdev,
+ EV_REL,
+ REL_WHEEL_HI_RES)) ||
+ (libevdev_has_event_code(device->evdev,
+ EV_REL,
+ REL_HWHEEL) &&
+ !libevdev_has_event_code(device->evdev,
+ EV_REL,
+ REL_HWHEEL_HI_RES)))
+ dispatch->wheel.emulate_hi_res_wheel = true;
+}