summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2018-11-22 10:24:54 +1000
committerJosé Expósito <jose.exposito89@gmail.com>2021-08-31 08:45:01 +0200
commit6bb02aaf307a38e60ec8e6b2198d8e0c30d59a95 (patch)
tree0078abc6aa906a55afbee130e49ca5baca619604
parent427c855d21b442620bf6472c2a0585ddca9673e0 (diff)
downloadlibinput-6bb02aaf307a38e60ec8e6b2198d8e0c30d59a95.tar.gz
High-resolution scroll wheel support
Starting with kernel v5.0 two new axes are available for high-resolution wheel scrolling: REL_WHEEL_HI_RES and REL_HWHEEL_HI_RES. Both axes send data in fractions of 120 where each multiple of 120 amounts to one logical scroll event. Fractions of 120 indicate a wheel movement less than one detent. This commit adds a new API for scroll events. Three new event types that encode the axis source in the event type name and a new API to get a normalized-to-120 value that also used by Windows and the kernel (each multiple of 120 represents a logical scroll click). This addresses a main shortcoming with the existing API - it was unreliable to calculate the click angle based on the axis value+discrete events and thus any caller using the axis value alone would be left with some ambiguity. With the v120 API it's now possible to (usually) calculate the click angle, but more importantly it provides the simplest hw-independent way of scrolling by a click or a fraction of a click. A new event type is required, the only way to integrate the v120 value otherwise was to start sending events with a discrete value of 0. This would break existing xf86-input-libinput (divide by zero, fixed in 0.28.2) and weston (general confusion). mutter, kwin are unaffected. With the new API, the old POINTER_AXIS event are deprecated - callers should use the new API where available and discard any POINTER_AXIS events. Notable: REL_WHEEL/REL_HWHEEL are emulated by the kernel but there's no guarantee that they'll come every accumulated 120 values, e.g. Logitech mice often send events that don't add up to 120 per detent. We use the kernel's wheel click emulation instead of doing our own. libinput guarantees high-resolution events even on pre-5.0 kernels. Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> Signed-off-by: José Expósito <jose.exposito89@gmail.com>
-rw-r--r--doc/user/development.rst1
-rw-r--r--doc/user/meson.build1
-rw-r--r--doc/user/scrolling.rst3
-rw-r--r--doc/user/wheel-api.rst183
-rw-r--r--src/evdev-fallback.c101
-rw-r--r--src/evdev-fallback.h4
-rw-r--r--src/evdev-mt-touchpad-edge-scroll.c28
-rw-r--r--src/evdev.c133
-rw-r--r--src/evdev.h28
-rw-r--r--src/libinput-private.h34
-rw-r--r--src/libinput.c189
-rw-r--r--src/libinput.h198
-rw-r--r--src/libinput.sym5
-rw-r--r--test/litest-device-mouse-low-dpi.c3
-rw-r--r--test/litest-device-mouse.c1
-rw-r--r--test/litest.c207
-rw-r--r--test/litest.h22
-rw-r--r--test/test-device.c32
-rw-r--r--test/test-gestures.c10
-rw-r--r--test/test-pointer.c220
-rw-r--r--test/test-switch.c11
-rw-r--r--test/test-touchpad-tap.c4
-rw-r--r--test/test-touchpad.c258
-rw-r--r--test/test-trackpoint.c22
-rw-r--r--tools/libinput-debug-events.c70
-rw-r--r--tools/libinput-debug-gui.c50
26 files changed, 1497 insertions, 321 deletions
diff --git a/doc/user/development.rst b/doc/user/development.rst
index b96d3654..4b7e4a0d 100644
--- a/doc/user/development.rst
+++ b/doc/user/development.rst
@@ -36,6 +36,7 @@ Topics below explain some behaviors of libinput.
normalization-of-relative-motion.rst
seats.rst
timestamps.rst
+ wheel-api.rst
.. _hacking_on_libinput:
diff --git a/doc/user/meson.build b/doc/user/meson.build
index 8d2714b2..332f67b9 100644
--- a/doc/user/meson.build
+++ b/doc/user/meson.build
@@ -167,6 +167,7 @@ src_rst = files(
'trackpoints.rst',
'trackpoint-configuration.rst',
'what-is-libinput.rst',
+ 'wheel-api.rst',
'features.rst',
'development.rst',
'troubleshooting.rst',
diff --git a/doc/user/scrolling.rst b/doc/user/scrolling.rst
index 82b88768..e568755d 100644
--- a/doc/user/scrolling.rst
+++ b/doc/user/scrolling.rst
@@ -130,6 +130,9 @@ button is logically held down, motion events are converted to scroll events.
Scroll sources
------------------------------------------------------------------------------
+.. note:: Scroll sources are deprecated with libinput 1.19. The scroll
+ source is now encoded in the event type.
+
libinput provides a pointer axis *source* for each scroll event. The
source can be obtained with the **libinput_event_pointer_get_axis_source()**
function and is one of **wheel**, **finger**, or **continuous**. The source
diff --git a/doc/user/wheel-api.rst b/doc/user/wheel-api.rst
new file mode 100644
index 00000000..e488a65a
--- /dev/null
+++ b/doc/user/wheel-api.rst
@@ -0,0 +1,183 @@
+.. _wheel_scrolling:
+
+==============================================================================
+Wheel scrolling
+==============================================================================
+
+libinput provides two events to handle wheel scrolling:
+
+- ``LIBINPUT_EVENT_POINTER_AXIS`` events are sent for regular wheel clicks,
+ usually those representing one detent on the device. These wheel clicks
+ usually require a rotation of 15 or 20 degrees.
+ **This event is deprecated as of libinput 1.19.**
+
+- ``LIBINPUT_EVENT_POINTER_SCROLL_WHEEL`` events are sent for regular and/or
+ high resolution wheel movements. High-resolution events are often 4 or 8
+ times more frequent than wheel clicks and require the device to be switched
+ into high-resolution mode (Linux kernel 5.0 and later). Where
+ high-resolution wheels are not provided by the kernel, libinput emulates
+ these events for regular wheel clicks.
+ **This event is available since libinput 1.19.**
+
+The events are separate for historical reasons. Both events are
+generated for the same device but are independent event streams. Callers
+must not assume any relation between the two, i.e. there is no guarantee
+that an axis event is sent before or after any specific high-resolution
+event and vice versa. Callers should not handle both events.
+
+.. warning:: do not handle both ``LIBINPUT_EVENT_POINTER_AXIS`` and
+ ``LIBINPUT_EVENT_POINTER_SCROLL_WHEEL``. Always use the latter where
+ possible, otherwise only use the former.
+
+Both events have their own set of APIs to access the data within:
+
+- ``LIBINPUT_EVENT_POINTER_AXIS``: Deprecated as of libinput 1.19, where
+ possible it is recommended to handle **only**
+ ``LIBINPUT_EVENT_POINTER_SCROLL_WHEEL``.
+
+ * ``libinput_event_pointer_get_axis_value()`` returns the angle of movement
+ in degrees.
+ * ``libinput_event_pointer_get_axis_source()`` returns the source of the
+ event: wheel, finger or continuous.
+ * ``libinput_event_pointer_get_axis_value_discrete()`` returns the number of
+ logical wheel clicks.
+
+- ``LIBINPUT_EVENT_POINTER_SCROLL_WHEEL`` available since libinput 1.19.
+
+ * ``libinput_event_pointer_get_scroll_value_v120()`` returns a value
+ normalized into the 0..120 range, see below. Any multiple of 120 should
+ be treated as one full wheel click.
+
+.. note:: Where possible, the ``libinput_event_pointer_get_axis_value()``,
+ ``libinput_event_pointer_get_axis_source()`` and
+ ``libinput_event_pointer_get_axis_value_discrete()`` API should be
+ avoided.
+
+------------------------------------------------------------------------------
+The v120 Wheel API
+------------------------------------------------------------------------------
+
+The ``v120`` value matches the Windows API for wheel scrolling. Wheel
+movements are normalized into multiples (or fractions) of 120 with each
+multiple of 120 representing one detent of movement. The ``v120`` API is the
+recommended API for callers that do not care about the exact physical
+motion and is the simplest API to handle high-resolution scrolling.
+
+Most wheels provide 24 detents per 360 degree rotation (click angle of 15),
+others provide 18 detents per 360 degree rotation (click angle 20). Mice
+falling outside these two are rare but do exist. Below is a table showing
+the various values for a single event, depending on the click angle of the
+wheel:
+
++-------------+------------+---------------+------+
+| Click angle | Axis value | Discrete value| v120 |
++=============+============+===============+======+
+| 15 | 15 | 1 | 120 |
++-------------+------------+---------------+------+
+| 20 | 20 | 1 | 120 |
++-------------+------------+---------------+------+
+
+Fast scrolling may trigger cover than one detent per event and thus each
+event may contain multiples of the value, discrete or v120 value:
+
++-------------+------------+---------------+------+
+| Click angle | Axis value | Discrete value| v120 |
++=============+============+===============+======+
+| 15 | 30 | 2 | 240 |
++-------------+------------+---------------+------+
+| 20 | 60 | 3 | 360 |
++-------------+------------+---------------+------+
+
+Scrolling on high-resolution wheels will produce fractions of 120, depending
+on the resolution of the wheel. The example below shows a mouse with click
+angle 15 and a resolution of 3 events per wheel click and a mouse with click
+angle 20 and a resolution of 2 events per wheel click.
+
++-------------+------------+---------------+------+
+| Click angle | Axis value | Discrete value| v120 |
++=============+============+===============+======+
+| 15 | 5 | 0 | 40 |
++-------------+------------+---------------+------+
+| 20 | 10 | 0 | 60 |
++-------------+------------+---------------+------+
+
+------------------------------------------------------------------------------
+Event sequences for high-resolution wheel mice
+------------------------------------------------------------------------------
+
+High-resolution scroll wheels provide multiple events for each detent is
+hit. For those mice, an event sequence covering two detents may look like
+this:
+
++--------------+---------+------------+---------------+------+
+| Event number | Type | Axis value | Discrete value| v120 |
++==============+=========+============+===============+======+
+| 1 | WHEEL | 5 | n/a | 40 |
++--------------+---------+------------+---------------+------+
+| 2 | WHEEL | 5 | n/a | 40 |
++--------------+---------+------------+---------------+------+
+| 3 | WHEEL | 5 | n/a | 40 |
++--------------+---------+------------+---------------+------+
+| 4 | AXIS | 15 | 1 | 120 |
++--------------+---------+------------+---------------+------+
+| 5 | WHEEL | 5 | n/a | 40 |
++--------------+---------+------------+---------------+------+
+| 6 | WHEEL | 5 | n/a | 40 |
++--------------+---------+------------+---------------+------+
+| 7 | AXIS | 15 | 1 | 120 |
++--------------+---------+------------+---------------+------+
+
+The above assumes a click angle of 15 for the physical detents. Note how the
+second set of high-resolution events do **not** add up to a multiple of
+120 before the low-resolution event. A caller must not assume any relation
+between ``LIBINPUT_EVENT_POINTER_SCROLL_WHEEL`` and
+``LIBINPUT_EVENT_POINTER_AXIS``.
+
+Fast-scrolling on a high-resolution mouse may trigger multiple fractions per
+hardware scanout cycle and result in an event sequence like this:
+
++---------------+---------+------------+---------------+------+
+| Event number | Type | Axis value | Discrete value| v120 |
++===============+=========+============+===============+======+
+| 1 | WHEEL | 5 | n/a | 40 |
++---------------+---------+------------+---------------+------+
+| 2 | WHEEL | 10 | n/a | 80 |
++---------------+---------+------------+---------------+------+
+| 3 | AXIS | 15 | 1 | 120 |
++---------------+---------+------------+---------------+------+
+| 4 | WHEEL | 10 | n/a | 80 |
++---------------+---------+------------+---------------+------+
+| 5 | WHEEL | 10 | n/a | 80 |
++---------------+---------+------------+---------------+------+
+| 6 | AXIS | 15 | 1 | 120 |
++---------------+---------+------------+---------------+------+
+| 7 | WHEEL | 5 | n/a | 40 |
++---------------+---------+------------+---------------+------+
+
+Note how the first low-resolution event is sent at an accumulated 15
+degrees, the second at an accumulated 20 degrees. The libinput API does not
+specify the smallest fraction a wheel supports.
+
+------------------------------------------------------------------------------
+Event sequences for regular wheel mice
+------------------------------------------------------------------------------
+
+``LIBINPUT_EVENT_POINTER_SCROLL_WHEEL`` for low-resolution mice are virtually
+identical to ``LIBINPUT_EVENT_POINTER_AXIS`` events. Note that the discrete
+value is always 0 for ``LIBINPUT_EVENT_POINTER_SCROLL_WHEEL``.
+
++--------------+---------+------------+---------------+------+
+| Event number | Type | Axis value | Discrete value| v120 |
++==============+=========+============+===============+======+
+| 1 | AXIS | 15 | 1 | 120 |
++--------------+---------+------------+---------------+------+
+| 2 | WHEEL | 15 | n/a | 120 |
++--------------+---------+------------+---------------+------+
+| 3 | WHEEL | 15 | n/a | 120 |
++--------------+---------+------------+---------------+------+
+| 4 | AXIS | 15 | 1 | 120 |
++--------------+---------+------------+---------------+------+
+
+Note that the order of ``LIBINPUT_EVENT_POINTER_AXIS`` vs
+``LIBINPUT_EVENT_POINTER_SCROLL_WHEEL`` events is not guaranteed, as shown in
+the example above.
diff --git a/src/evdev-fallback.c b/src/evdev-fallback.c
index f7c7e02b..85cf6ca9 100644
--- a/src/evdev-fallback.c
+++ b/src/evdev-fallback.c
@@ -230,59 +230,88 @@ fallback_flush_wheels(struct fallback_dispatch *dispatch,
{
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.is_inhibited) {
- dispatch->wheel.delta.x = 0;
- dispatch->wheel.delta.y = 0;
+ 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.delta.y *= -1;
- normalize_delta(device, &dispatch->wheel.delta, &unaccel);
+ 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.delta.x = 0;
- dispatch->wheel.delta.y = 0;
+ dispatch->wheel.hi_res.x = 0;
+ dispatch->wheel.hi_res.y = 0;
return;
}
- if (dispatch->wheel.delta.y != 0) {
- wheel_degrees.y = -1 * dispatch->wheel.delta.y *
- device->scroll.wheel_click_angle.y;
- discrete.y = -1 * dispatch->wheel.delta.y;
+ if (dispatch->wheel.hi_res.y != 0) {
+ int value = dispatch->wheel.hi_res.y;
- evdev_notify_axis(
+ 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),
- LIBINPUT_POINTER_AXIS_SOURCE_WHEEL,
&wheel_degrees,
&discrete);
- dispatch->wheel.delta.y = 0;
+ dispatch->wheel.lo_res.y = 0;
}
- if (dispatch->wheel.delta.x != 0) {
- wheel_degrees.x = dispatch->wheel.delta.x *
- device->scroll.wheel_click_angle.x;
- discrete.x = dispatch->wheel.delta.x;
+ if (dispatch->wheel.hi_res.x != 0) {
+ int value = dispatch->wheel.hi_res.x;
- evdev_notify_axis(
+ 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),
- LIBINPUT_POINTER_AXIS_SOURCE_WHEEL,
&wheel_degrees,
&discrete);
- dispatch->wheel.delta.x = 0;
+ dispatch->wheel.lo_res.x = 0;
}
}
@@ -855,11 +884,23 @@ fallback_process_relative(struct fallback_dispatch *dispatch,
dispatch->pending_event |= EVDEV_RELATIVE_MOTION;
break;
case REL_WHEEL:
- dispatch->wheel.delta.y += e->value;
+ 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.delta.x += e->value;
+ 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->pending_event |= EVDEV_WHEEL;
+ break;
+ case REL_HWHEEL_HI_RES:
+ dispatch->wheel.hi_res.x += e->value;
dispatch->pending_event |= EVDEV_WHEEL;
break;
}
@@ -1772,6 +1813,22 @@ 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_debounce(dispatch);
fallback_init_arbitration(dispatch, device);
diff --git a/src/evdev-fallback.h b/src/evdev-fallback.h
index 58f32426..fafd1821 100644
--- a/src/evdev-fallback.h
+++ b/src/evdev-fallback.h
@@ -98,7 +98,9 @@ struct fallback_dispatch {
struct device_coords rel;
struct {
- struct device_coords delta;
+ struct device_coords lo_res;
+ struct device_coords hi_res;
+ bool emulate_hi_res_wheel;
bool is_inhibited;
} wheel;
diff --git a/src/evdev-mt-touchpad-edge-scroll.c b/src/evdev-mt-touchpad-edge-scroll.c
index d63cc744..08876bef 100644
--- a/src/evdev-mt-touchpad-edge-scroll.c
+++ b/src/evdev-mt-touchpad-edge-scroll.c
@@ -426,7 +426,6 @@ tp_edge_scroll_post_events(struct tp_dispatch *tp, uint64_t time)
struct device_float_coords fraw;
struct normalized_coords normalized, tmp;
const struct normalized_coords zero = { 0.0, 0.0 };
- const struct discrete_coords zero_discrete = { 0.0, 0.0 };
tp_for_each_touch(tp, t) {
if (!t->dirty)
@@ -444,11 +443,10 @@ tp_edge_scroll_post_events(struct tp_dispatch *tp, uint64_t time)
case EDGE_NONE:
if (t->scroll.direction != -1) {
/* Send stop scroll event */
- evdev_notify_axis(device, time,
- bit(t->scroll.direction),
- LIBINPUT_POINTER_AXIS_SOURCE_FINGER,
- &zero,
- &zero_discrete);
+ evdev_notify_axis_finger(device,
+ time,
+ bit(t->scroll.direction),
+ &zero);
t->scroll.direction = -1;
}
continue;
@@ -494,11 +492,9 @@ tp_edge_scroll_post_events(struct tp_dispatch *tp, uint64_t time)
if (*delta == 0.0)
continue;
- evdev_notify_axis(device, time,
- bit(axis),
- LIBINPUT_POINTER_AXIS_SOURCE_FINGER,
- &normalized,
- &zero_discrete);
+ evdev_notify_axis_finger(device, time,
+ bit(axis),
+ &normalized);
t->scroll.direction = axis;
tp_edge_scroll_handle_event(tp, t, SCROLL_EVENT_POSTED, time);
@@ -513,15 +509,13 @@ tp_edge_scroll_stop_events(struct tp_dispatch *tp, uint64_t time)
struct evdev_device *device = tp->device;
struct tp_touch *t;
const struct normalized_coords zero = { 0.0, 0.0 };
- const struct discrete_coords zero_discrete = { 0.0, 0.0 };
tp_for_each_touch(tp, t) {
if (t->scroll.direction != -1) {
- evdev_notify_axis(device, time,
- bit(t->scroll.direction),
- LIBINPUT_POINTER_AXIS_SOURCE_FINGER,
- &zero,
- &zero_discrete);
+ evdev_notify_axis_finger(device,
+ time,
+ bit(t->scroll.direction),
+ &zero);
t->scroll.direction = -1;
/* reset touch to area state, avoids loading the
* state machine with special case handling */
diff --git a/src/evdev.c b/src/evdev.c
index 36c782f2..e8b37674 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -375,12 +375,11 @@ evdev_device_transform_y(struct evdev_device *device,
}
void
-evdev_notify_axis(struct evdev_device *device,
- uint64_t time,
- uint32_t axes,
- enum libinput_pointer_axis_source source,
- const struct normalized_coords *delta_in,
- const struct discrete_coords *discrete_in)
+evdev_notify_axis_legacy_wheel(struct evdev_device *device,
+ uint64_t time,
+ uint32_t axes,
+ const struct normalized_coords *delta_in,
+ const struct discrete_coords *discrete_in)
{
struct normalized_coords delta = *delta_in;
struct discrete_coords discrete = *discrete_in;
@@ -397,12 +396,73 @@ evdev_notify_axis(struct evdev_device *device,
discrete.y *= -1;
}
- pointer_notify_axis(&device->base,
- time,
- axes,
- source,
- &delta,
- &discrete);
+ pointer_notify_axis_legacy_wheel(&device->base,
+ time,
+ axes,
+ &delta,
+ &discrete);
+}
+
+void
+evdev_notify_axis_wheel(struct evdev_device *device,
+ uint64_t time,
+ uint32_t axes,
+ const struct normalized_coords *delta_in,
+ const struct wheel_v120 *v120_in)
+{
+ struct normalized_coords delta = *delta_in;
+ struct wheel_v120 v120 = *v120_in;
+
+ if (device->scroll.natural_scrolling_enabled) {
+ delta.x *= -1;
+ delta.y *= -1;
+ v120.x *= -1;
+ v120.y *= -1;
+ }
+
+ pointer_notify_axis_wheel(&device->base,
+ time,
+ axes,
+ &delta,
+ &v120);
+}
+
+void
+evdev_notify_axis_finger(struct evdev_device *device,
+ uint64_t time,
+ uint32_t axes,
+ const struct normalized_coords *delta_in)
+{
+ struct normalized_coords delta = *delta_in;
+
+ if (device->scroll.natural_scrolling_enabled) {
+ delta.x *= -1;
+ delta.y *= -1;
+ }
+
+ pointer_notify_axis_finger(&device->base,
+ time,
+ axes,
+ &delta);
+}
+
+void
+evdev_notify_axis_continous(struct evdev_device *device,
+ uint64_t time,
+ uint32_t axes,
+ const struct normalized_coords *delta_in)
+{
+ struct normalized_coords delta = *delta_in;
+
+ if (device->scroll.natural_scrolling_enabled) {
+ delta.x *= -1;
+ delta.y *= -1;
+ }
+
+ pointer_notify_axis_continuous(&device->base,
+ time,
+ axes,
+ &delta);
}
static void
@@ -2688,7 +2748,6 @@ evdev_post_scroll(struct evdev_device *device,
event.x = 0.0;
if (!normalized_is_zero(event)) {
- const struct discrete_coords zero_discrete = { 0.0, 0.0 };
uint32_t axes = device->scroll.direction;
if (event.y == 0.0)
@@ -2696,12 +2755,19 @@ evdev_post_scroll(struct evdev_device *device,
if (event.x == 0.0)
axes &= ~bit(LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL);
- evdev_notify_axis(device,
- time,
- axes,
- source,
- &event,
- &zero_discrete);
+ switch (source) {
+ case LIBINPUT_POINTER_AXIS_SOURCE_FINGER:
+ evdev_notify_axis_finger(device, time, axes, &event);
+ break;
+ case LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS:
+ evdev_notify_axis_continous(device, time, axes, &event);
+ break;
+ default:
+ evdev_log_bug_libinput(device,
+ "Posting invalid scroll source %d\n",
+ source);
+ break;
+ }
}
}
@@ -2711,16 +2777,29 @@ evdev_stop_scroll(struct evdev_device *device,
enum libinput_pointer_axis_source source)
{
const struct normalized_coords zero = { 0.0, 0.0 };
- const struct discrete_coords zero_discrete = { 0.0, 0.0 };
/* terminate scrolling with a zero scroll event */
- if (device->scroll.direction != 0)
- pointer_notify_axis(&device->base,
- time,
- device->scroll.direction,
- source,
- &zero,
- &zero_discrete);
+ if (device->scroll.direction != 0) {
+ switch (source) {
+ case LIBINPUT_POINTER_AXIS_SOURCE_FINGER:
+ pointer_notify_axis_finger(&device->base,
+ time,
+ device->scroll.direction,
+ &zero);
+ break;
+ case LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS:
+ pointer_notify_axis_continuous(&device->base,
+ time,
+ device->scroll.direction,
+ &zero);
+ break;
+ default:
+ evdev_log_bug_libinput(device,
+ "Stopping invalid scroll source %d\n",
+ source);
+ break;
+ }
+ }
device->scroll.buildup.x = 0;
device->scroll.buildup.y = 0;
diff --git a/src/evdev.h b/src/evdev.h
index 0732063c..c7d130f8 100644
--- a/src/evdev.h
+++ b/src/evdev.h
@@ -583,12 +583,28 @@ evdev_update_key_down_count(struct evdev_device *device,
int pressed);
void
-evdev_notify_axis(struct evdev_device *device,
- uint64_t time,
- uint32_t axes,
- enum libinput_pointer_axis_source source,
- const struct normalized_coords *delta_in,
- const struct discrete_coords *discrete_in);
+evdev_notify_axis_legacy_wheel(struct evdev_device *device,
+ uint64_t time,
+ uint32_t axes,
+ const struct normalized_coords *delta_in,
+ const struct discrete_coords *discrete_in);
+void
+evdev_notify_axis_wheel(struct evdev_device *device,
+ uint64_t time,
+ uint32_t axes,
+ const struct normalized_coords *delta_in,
+ const struct wheel_v120 *v120_in);
+void
+evdev_notify_axis_finger(struct evdev_device *device,
+ uint64_t time,
+ uint32_t axes,
+ const struct normalized_coords *delta_in);
+void
+evdev_notify_axis_continous(struct evdev_device *device,
+ uint64_t time,
+ uint32_t axes,
+ const struct normalized_coords *delta_in);
+
void
evdev_post_scroll(struct evdev_device *device,
uint64_t time,
diff --git a/src/libinput-private.h b/src/libinput-private.h
index 172035ab..d5845420 100644
--- a/src/libinput-private.h
+++ b/src/libinput-private.h
@@ -77,6 +77,11 @@ struct wheel_angle {
double x, y;
};
+/* A pair of wheel click data for the 120-normalized range */
+struct wheel_v120 {
+ int x, y;
+};
+
/* A pair of angles in degrees */
struct tilt_degrees {
double x, y;
@@ -568,12 +573,29 @@ pointer_notify_button(struct libinput_device *device,
enum libinput_button_state state);
void
-pointer_notify_axis(struct libinput_device *device,
- uint64_t time,
- uint32_t axes,
- enum libinput_pointer_axis_source source,
- const struct normalized_coords *delta,
- const struct discrete_coords *discrete);
+pointer_notify_axis_finger(struct libinput_device *device,
+ uint64_t time,
+ uint32_t axes,
+ const struct normalized_coords *delta);
+void
+pointer_notify_axis_continuous(struct libinput_device *device,
+ uint64_t time,
+ uint32_t axes,
+ const struct normalized_coords *delta);
+
+void
+pointer_notify_axis_legacy_wheel(struct libinput_device *device,
+ uint64_t time,
+ uint32_t axes,
+ const struct normalized_coords *delta,
+ const struct discrete_coords *discrete);
+
+void
+pointer_notify_axis_wheel(struct libinput_device *device,
+ uint64_t time,
+ uint32_t axes,
+ const struct normalized_coords *delta,
+ const struct wheel_v120 *v120);
void
touch_notify_touch_down(struct libinput_device *device,
diff --git a/src/libinput.c b/src/libinput.c
index 092762aa..a0c85043 100644
--- a/src/libinput.c
+++ b/src/libinput.c
@@ -87,6 +87,9 @@ event_type_to_str(enum libinput_event_type type)
CASE_RETURN_STRING(LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE);
CASE_RETURN_STRING(LIBINPUT_EVENT_POINTER_BUTTON);
CASE_RETURN_STRING(LIBINPUT_EVENT_POINTER_AXIS);
+ CASE_RETURN_STRING(LIBINPUT_EVENT_POINTER_SCROLL_WHEEL);
+ CASE_RETURN_STRING(LIBINPUT_EVENT_POINTER_SCROLL_FINGER);
+ CASE_RETURN_STRING(LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS);
CASE_RETURN_STRING(LIBINPUT_EVENT_TOUCH_DOWN);
CASE_RETURN_STRING(LIBINPUT_EVENT_TOUCH_UP);
CASE_RETURN_STRING(LIBINPUT_EVENT_TOUCH_MOTION);
@@ -175,6 +178,7 @@ struct libinput_event_pointer {
struct device_float_coords delta_raw;
struct device_coords absolute;
struct discrete_coords discrete;
+ struct wheel_v120 v120;
uint32_t button;
uint32_t seat_button_count;
enum libinput_button_state state;
@@ -366,6 +370,9 @@ libinput_event_get_pointer_event(struct libinput_event *event)
LIBINPUT_EVENT_POINTER_MOTION,
LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE,
LIBINPUT_EVENT_POINTER_BUTTON,
+ LIBINPUT_EVENT_POINTER_SCROLL_WHEEL,
+ LIBINPUT_EVENT_POINTER_SCROLL_FINGER,
+ LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS,
LIBINPUT_EVENT_POINTER_AXIS);
return (struct libinput_event_pointer *) event;
@@ -530,6 +537,9 @@ libinput_event_pointer_get_time(struct libinput_event_pointer *event)
LIBINPUT_EVENT_POINTER_MOTION,
LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE,
LIBINPUT_EVENT_POINTER_BUTTON,
+ LIBINPUT_EVENT_POINTER_SCROLL_WHEEL,
+ LIBINPUT_EVENT_POINTER_SCROLL_FINGER,
+ LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS,
LIBINPUT_EVENT_POINTER_AXIS);
return us2ms(event->time);
@@ -544,6 +554,9 @@ libinput_event_pointer_get_time_usec(struct libinput_event_pointer *event)
LIBINPUT_EVENT_POINTER_MOTION,
LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE,
LIBINPUT_EVENT_POINTER_BUTTON,
+ LIBINPUT_EVENT_POINTER_SCROLL_WHEEL,
+ LIBINPUT_EVENT_POINTER_SCROLL_FINGER,
+ LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS,
LIBINPUT_EVENT_POINTER_AXIS);
return event->time;
@@ -692,6 +705,9 @@ libinput_event_pointer_has_axis(struct libinput_event_pointer *event,
require_event_type(libinput_event_get_context(&event->base),
event->base.type,
0,
+ LIBINPUT_EVENT_POINTER_SCROLL_WHEEL,
+ LIBINPUT_EVENT_POINTER_SCROLL_FINGER,
+ LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS,
LIBINPUT_EVENT_POINTER_AXIS);
switch (axis) {
@@ -758,6 +774,62 @@ libinput_event_pointer_get_axis_value_discrete(struct libinput_event_pointer *ev
return value;
}
+LIBINPUT_EXPORT double
+libinput_event_pointer_get_scroll_value(struct libinput_event_pointer *event,
+ enum libinput_pointer_axis axis)
+{
+ struct libinput *libinput = event->base.device->seat->libinput;
+ double value = 0;
+
+ require_event_type(libinput_event_get_context(&event->base),
+ event->base.type,
+ 0.0,
+ LIBINPUT_EVENT_POINTER_SCROLL_WHEEL,
+ LIBINPUT_EVENT_POINTER_SCROLL_FINGER,
+ LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS);
+
+ if (!libinput_event_pointer_has_axis(event, axis)) {
+ log_bug_client(libinput, "value requested for unset axis\n");
+ } else {
+ switch (axis) {
+ case LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL:
+ value = event->delta.x;
+ break;
+ case LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL:
+ value = event->delta.y;
+ break;
+ }
+ }
+ return value;
+}
+
+LIBINPUT_EXPORT double
+libinput_event_pointer_get_scroll_value_v120(struct libinput_event_pointer *event,
+ enum libinput_pointer_axis axis)
+{
+ struct libinput *libinput = event->base.device->seat->libinput;
+ double value = 0;
+
+ require_event_type(libinput_event_get_context(&event->base),
+ event->base.type,
+ 0.0,
+ LIBINPUT_EVENT_POINTER_SCROLL_WHEEL);
+
+ if (!libinput_event_pointer_has_axis(event, axis)) {
+ log_bug_client(libinput, "value requested for unset axis\n");
+ } else {
+ switch (axis) {
+ case LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL:
+ value = event->v120.x;
+ break;
+ case LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL:
+ value = event->v120.y;
+ break;
+ }
+ }
+ return value;
+}
+
LIBINPUT_EXPORT enum libinput_pointer_axis_source
libinput_event_pointer_get_axis_source(struct libinput_event_pointer *event)
{
@@ -2438,14 +2510,82 @@ pointer_notify_button(struct libinput_device *device,
}
void
-pointer_notify_axis(struct libinput_device *device,
- uint64_t time,
- uint32_t axes,
- enum libinput_pointer_axis_source source,
- const struct normalized_coords *delta,
- const struct discrete_coords *discrete)
+pointer_notify_axis_finger(struct libinput_device *device,
+ uint64_t time,
+ uint32_t axes,
+ const struct normalized_coords *delta)
+{
+ struct libinput_event_pointer *axis_event, *axis_event_legacy;
+ const struct discrete_coords zero_discrete = {0};
+ const struct wheel_v120 zero_v120 = {0};
+
+ if (!device_has_cap(device, LIBINPUT_DEVICE_CAP_POINTER))
+ return;
+
+ axis_event = zalloc(sizeof *axis_event);
+ axis_event_legacy = zalloc(sizeof *axis_event_legacy);
+
+ *axis_event = (struct libinput_event_pointer) {
+ .time = time,
+ .delta = *delta,
+ .source = LIBINPUT_POINTER_AXIS_SOURCE_FINGER,
+ .axes = axes,
+ .discrete = zero_discrete,
+ .v120 = zero_v120,
+ };
+ *axis_event_legacy = *axis_event;
+
+ post_device_event(device, time,
+ LIBINPUT_EVENT_POINTER_SCROLL_FINGER,
+ &axis_event->base);
+ post_device_event(device, time,
+ LIBINPUT_EVENT_POINTER_AXIS,
+ &axis_event_legacy->base);
+}
+
+void
+pointer_notify_axis_continuous(struct libinput_device *device,
+ uint64_t time,
+ uint32_t axes,
+ const struct normalized_coords *delta)
+{
+ struct libinput_event_pointer *axis_event, *axis_event_legacy;
+ const struct discrete_coords zero_discrete = {0};
+ const struct wheel_v120 zero_v120 = {0};
+
+ if (!device_has_cap(device, LIBINPUT_DEVICE_CAP_POINTER))
+ return;
+
+ axis_event = zalloc(sizeof *axis_event);
+ axis_event_legacy = zalloc(sizeof *axis_event_legacy);
+
+ *axis_event = (struct libinput_event_pointer) {
+ .time = time,
+ .delta = *delta,
+ .source = LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS,
+ .axes = axes,
+ .discrete = zero_discrete,
+ .v120 = zero_v120,
+ };
+ *axis_event_legacy = *axis_event;
+
+ post_device_event(device, time,
+ LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS,
+ &axis_event->base);
+ post_device_event(device, time,
+ LIBINPUT_EVENT_POINTER_AXIS,
+ &axis_event_legacy->base);
+}
+
+void
+pointer_notify_axis_legacy_wheel(struct libinput_device *device,
+ uint64_t time,
+ uint32_t axes,
+ const struct normalized_coords *delta,
+ const struct discrete_coords *discrete)
{
struct libinput_event_pointer *axis_event;
+ const struct wheel_v120 zero_v120 = {0};
if (!device_has_cap(device, LIBINPUT_DEVICE_CAP_POINTER))
return;
@@ -2455,9 +2595,10 @@ pointer_notify_axis(struct libinput_device *device,
*axis_event = (struct libinput_event_pointer) {
.time = time,
.delta = *delta,
- .source = source,
+ .source = LIBINPUT_POINTER_AXIS_SOURCE_WHEEL,
.axes = axes,
.discrete = *discrete,
+ .v120 = zero_v120,
};
post_device_event(device, time,
@@ -2466,6 +2607,37 @@ pointer_notify_axis(struct libinput_device *device,
}
void
+pointer_notify_axis_wheel(struct libinput_device *device,
+ uint64_t time,
+ uint32_t axes,
+ const struct normalized_coords *delta,
+ const struct wheel_v120 *v120)
+{
+ struct libinput_event_pointer *axis_event;
+
+ if (!device_has_cap(device, LIBINPUT_DEVICE_CAP_POINTER))
+ return;
+
+ axis_event = zalloc(sizeof *axis_event);
+
+ *axis_event = (struct libinput_event_pointer) {
+ .time = time,
+ .delta = *delta,
+ .source = LIBINPUT_POINTER_AXIS_SOURCE_WHEEL,
+ .axes = axes,
+ .discrete.x = 0,
+ .discrete.y = 0,
+ .v120 = *v120,
+ };
+
+ post_device_event(device, time,
+ LIBINPUT_EVENT_POINTER_SCROLL_WHEEL,
+ &axis_event->base);
+
+ /* legacy wheel events are sent separately */
+}
+
+void
touch_notify_touch_down(struct libinput_device *device,
uint64_t time,
int32_t slot,
@@ -3361,6 +3533,9 @@ libinput_event_pointer_get_base_event(struct libinput_event_pointer *event)
LIBINPUT_EVENT_POINTER_MOTION,
LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE,
LIBINPUT_EVENT_POINTER_BUTTON,
+ LIBINPUT_EVENT_POINTER_SCROLL_WHEEL,
+ LIBINPUT_EVENT_POINTER_SCROLL_FINGER,
+ LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS,
LIBINPUT_EVENT_POINTER_AXIS);
return &event->base;
diff --git a/src/libinput.h b/src/libinput.h
index 46b38a4d..e0a9df67 100644
--- a/src/libinput.h
+++ b/src/libinput.h
@@ -253,6 +253,12 @@ enum libinput_pointer_axis {
*
* The source for a libinput_pointer_axis event. See
* libinput_event_pointer_get_axis_source() for details.
+ *
+ * @note Pointer axis sources are deprecated, the source is now encoded in
+ * the event types
+ * @ref LIBINPUT_EVENT_POINTER_SCROLL_WHEEL,
+ * @ref LIBINPUT_EVENT_POINTER_SCROLL_FINGER, and
+ * @ref LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS.
*/
enum libinput_pointer_axis_source {
/**
@@ -742,8 +748,80 @@ enum libinput_event_type {
LIBINPUT_EVENT_POINTER_MOTION = 400,
LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE,
LIBINPUT_EVENT_POINTER_BUTTON,
+ /**
+ * A scroll event from various sources.
+ *
+ * This event is deprecated as of libinput 1.19. Use
+ * @ref LIBINPUT_EVENT_POINTER_SCROLL_WHEEL,
+ * @ref LIBINPUT_EVENT_POINTER_SCROLL_FINGER, and
+ * @ref LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS instead.
+ *
+ * Use libinput_event_pointer_get_axis_source() to determine the
+ * source of a scroll event. For libinput versions 1.19 and later,
+ * the source is encoded in the event type.
+ *
+ * This event is sent **in addition** to events of type
+ * @ref LIBINPUT_EVENT_POINTER_SCROLL_WHEEL,
+ * @ref LIBINPUT_EVENT_POINTER_SCROLL_FINGER, and
+ * @ref LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS.
+ * Do not mix and match, either use the old event or the new events.
+ * libinput makes no guarantee about the relation between
+ * @ref LIBINPUT_EVENT_POINTER_AXIS and the new event types
+ * @ref LIBINPUT_EVENT_POINTER_SCROLL_WHEEL,
+ * @ref LIBINPUT_EVENT_POINTER_SCROLL_FINGER, and
+ * @ref LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS. You may receive
+ * multiple zero, one or more new events per legacy event.
+ *
+ * @warning Ignore this event if you are processing
+ * @ref LIBINPUT_EVENT_POINTER_SCROLL_WHEEL,
+ * @ref LIBINPUT_EVENT_POINTER_SCROLL_FINGER, and
+ * @ref LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS.
+ */
LIBINPUT_EVENT_POINTER_AXIS,
+ /**
+ * A scroll event from a wheel. This event is sent is sent **in
+ * addition** to the @ref LIBINPUT_EVENT_POINTER_AXIS
+ * event for all events with a
+ * libinput_event_pointer_get_axis_source() of @ref
+ * LIBINPUT_POINTER_AXIS_SOURCE_WHEEL. Ignore @ref
+ * LIBINPUT_EVENT_POINTER_AXIS if you are processing this event.
+ *
+ * See the libinput documentation for details.
+ *
+ * @since 1.19
+ */
+ LIBINPUT_EVENT_POINTER_SCROLL_WHEEL,
+
+ /**
+ * A scroll event caused by the movement of one or more fingers on a
+ * device. This event is sent is sent **in addition** to the @ref
+ * LIBINPUT_EVENT_POINTER_AXIS event for all events with a
+ * libinput_event_pointer_get_axis_source() of @ref
+ * LIBINPUT_POINTER_AXIS_SOURCE_FINGER. Ignore @ref
+ * LIBINPUT_EVENT_POINTER_AXIS if you are processing this event.
+ *
+ * See the libinput documentation for details.
+ *
+ * @since 1.19
+ */
+ LIBINPUT_EVENT_POINTER_SCROLL_FINGER,
+
+ /**
+ * A scroll event from a continuous scroll source, e.g. button
+ * scrolling. This event is sent is sent **in
+ * addition** to the @ref LIBINPUT_EVENT_POINTER_AXIS
+ * event for all events with a
+ * libinput_event_pointer_get_axis_source() of @ref
+ * LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS. Ignore @ref
+ * LIBINPUT_EVENT_POINTER_AXIS if you are processing this event.
+ *
+ * See the libinput documentation for details.
+ *
+ * @since 1.19
+ */
+ LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS,
+
LIBINPUT_EVENT_TOUCH_DOWN = 500,
LIBINPUT_EVENT_TOUCH_UP,
LIBINPUT_EVENT_TOUCH_MOTION,
@@ -1415,10 +1493,15 @@ libinput_event_pointer_get_seat_button_count(
* is a scroll stop event.
*
* For pointer events that are not of type @ref LIBINPUT_EVENT_POINTER_AXIS,
- * this function returns 0.
+ * @ref LIBINPUT_EVENT_POINTER_SCROLL_WHEEL, @ref
+ * LIBINPUT_EVENT_POINTER_SCROLL_FINGER, or @ref
+ * LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS this function returns 0.
*
* @note It is an application bug to call this function for events other than
- * @ref LIBINPUT_EVENT_POINTER_AXIS.
+ * @ref LIBINPUT_EVENT_POINTER_AXIS,
+ * @ref LIBINPUT_EVENT_POINTER_SCROLL_WHEEL,
+ * @ref LIBINPUT_EVENT_POINTER_SCROLL_FINGER, or
+ * @ref LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS.
*
* @return Non-zero if this event contains a value for this axis
*/
@@ -1474,7 +1557,9 @@ libinput_event_pointer_get_axis_value(struct libinput_event_pointer *event,
* Scrolling is in discrete steps, the value is the angle the wheel moved
* in degrees. The default is 15 degrees per wheel click, but some mice may
* have differently grained wheels. It is up to the caller how to interpret
- * such different step sizes.
+ * such different step sizes. Callers should use
+ * libinput_event_pointer_get_scroll_value_v120() for a simpler API of
+ * handling scroll wheel events of different step sizes.
*
* If the source is @ref LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS, no
* terminating event is guaranteed (though it may happen).
@@ -1490,6 +1575,12 @@ libinput_event_pointer_get_axis_value(struct libinput_event_pointer *event,
* @note It is an application bug to call this function for events other than
* @ref LIBINPUT_EVENT_POINTER_AXIS.
*
+ * @note This function is superfluous as of libinput 1.19. The event
+ * codes for @ref LIBINPUT_EVENT_POINTER_SCROLL_WHEEL, @ref
+ * LIBINPUT_EVENT_POINTER_SCROLL_FINGER and @ref
+ * LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS have the axis source encoded in
+ * the event type.
+ *
* @return The source for this axis event
*/
enum libinput_pointer_axis_source
@@ -1501,6 +1592,14 @@ libinput_event_pointer_get_axis_source(struct libinput_event_pointer *event);
* Return the axis value in discrete steps for a given axis event. How a
* value translates into a discrete step depends on the source.
*
+ * @note This function does not support high-resolution mouse wheels and
+ * should be considered deprecated as of libinput 1.19. Callers should use
+ * @ref LIBINPUT_EVENT_POINTER_SCROLL_WHEEL and
+ * libinput_event_pointer_get_scroll_value_v120() instead.
+ *
+ * If the event is not of type @ref LIBINPUT_EVENT_POINTER_AXIS, this
+ * function returns 0.
+ *
* If the source is @ref LIBINPUT_POINTER_AXIS_SOURCE_WHEEL, the discrete
* value correspond to the number of physical mouse wheel clicks.
*
@@ -1510,6 +1609,7 @@ libinput_event_pointer_get_axis_source(struct libinput_event_pointer *event);
* @return The discrete value for the given event.
*
* @see libinput_event_pointer_get_axis_value
+ * @see libinput_event_pointer_get_scroll_value_v120
*/
double
libinput_event_pointer_get_axis_value_discrete(struct libinput_event_pointer *event,
@@ -1518,6 +1618,98 @@ libinput_event_pointer_get_axis_value_discrete(struct libinput_event_pointer *ev
/**
* @ingroup event_pointer
*
+ * Return the axis value of the given axis. The interpretation of the value
+ * depends on the axis. For the two scrolling axes
+ * @ref LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL and
+ * @ref LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, the value of the event is in
+ * relative scroll units, with the positive direction being down or right,
+ * respectively. If libinput_event_pointer_has_axis() returns 0 for an axis,
+ * this function returns 0 for that axis.
+ *
+ * If the event is @ref LIBINPUT_EVENT_POINTER_SCROLL_FINGER, libinput
+ * guarantees that a scroll sequence is terminated with a scroll value of 0.
+ * A caller may use this information to decide on whether kinetic scrolling
+ * should be triggered on this scroll sequence.
+ * The coordinate system is identical to the cursor movement, i.e. a
+ * scroll value of 1 represents the equivalent relative motion of 1.
+ *
+ * If the event is @ref LIBINPUT_EVENT_POINTER_SCROLL_WHEEL, no terminating
+ * event is guaranteed (though it may happen).
+ * Scrolling is in discrete steps, the value is the angle the wheel moved
+ * in degrees. The default is 15 degrees per wheel click, but some mice may
+ * have differently grained wheels. It is up to the caller how to interpret
+ * such different step sizes. Callers should use
+ * libinput_event_pointer_get_scroll_value_v120() for a simpler API of
+ * handling scroll wheel events of different step sizes.
+ *
+ * If the event is @ref LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS, no
+ * terminating event is guaranteed (though it may happen).
+ * The coordinate system is identical to the cursor movement, i.e. a
+ * scroll value of 1 represents the equivalent relative motion of 1.
+ *
+ * For pointer events that are not of type
+ * @ref LIBINPUT_EVENT_POINTER_SCROLL_WHEEL,
+ * @ref LIBINPUT_EVENT_POINTER_SCROLL_FINGER, or
+ * @ref LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS, this function returns zero.
+ *
+ * @note It is an application bug to call this function for events other than
+ * @ref LIBINPUT_EVENT_POINTER_SCROLL_WHEEL,
+ * @ref LIBINPUT_EVENT_POINTER_SCROLL_FINGER, or
+ * @ref LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS.
+ *
+ * @return The axis value of this event
+ *
+ * @see libinput_event_pointer_get_scroll_value_v120
+ *
+ * @since 1.19
+ */
+double
+libinput_event_pointer_get_scroll_value(struct libinput_event_pointer *event,
+ enum libinput_pointer_axis axis);
+
+/**
+ * @ingroup event_pointer
+ *
+ * For events of type @ref LIBINPUT_EVENT_POINTER_SCROLL_WHEEL
+ * the v120-normalized value represents the movement in logical mouse wheel
+ * clicks, normalized to the -120..+120 range.
+ *
+ * A value that is a fraction of ±120 indicates a wheel movement less than
+ * one logical click, a caller should either scroll by the respective
+ * fraction of the normal scroll distance or accumulate that value until a
+ * multiple of 120 is reached.
+ *
+ * For most callers, this is the preferred way of handling high-resolution
+ * scroll events.
+ *
+ * The normalized v120 value does not take device-specific physical angles
+ * or distances into account, i.e. a wheel with a click angle of 20 degrees
+ * produces only 18 logical clicks per 360 degree rotation, a wheel with a
+ * click angle of 15 degrees produces 24 logical clicks per 360 degree
+ * rotation. Where the physical angle matters, use
+ * libinput_event_pointer_get_axis_value() instead.
+ *
+ * The magic number 120 originates from the <a
+ * href="http://download.microsoft.com/download/b/d/1/bd1f7ef4-7d72-419e-bc5c-9f79ad7bb66e/wheel.docx">
+ * Windows Vista Mouse Wheel design document</a>.
+ *
+ * @note It is an application bug to call this function for events other than
+ * @ref LIBINPUT_EVENT_POINTER_SCROLL_WHEEL.
+ *
+ * @return A value normalized to the 0-±120 range
+ *
+ * @see libinput_event_pointer_get_axis_value
+ * @see libinput_event_pointer_get_axis_value_discrete
+ *
+ * @since 1.19
+ */
+double
+libinput_event_pointer_get_scroll_value_v120(struct libinput_event_pointer *event,
+ enum libinput_pointer_axis axis);
+
+/**
+ * @ingroup event_pointer
+ *
* @return The generic libinput_event of this event
*/
struct libinput_event *
diff --git a/src/libinput.sym b/src/libinput.sym
index b45838e0..7e6fa06b 100644
--- a/src/libinput.sym
+++ b/src/libinput.sym
@@ -314,3 +314,8 @@ LIBINPUT_1.15 {
libinput_event_tablet_pad_get_key;
libinput_event_tablet_pad_get_key_state;
} LIBINPUT_1.14;
+
+LIBINPUT_1.19 {
+ libinput_event_pointer_get_scroll_value_v120;
+ libinput_event_pointer_get_scroll_value;
+} LIBINPUT_1.15;
diff --git a/test/litest-device-mouse-low-dpi.c b/test/litest-device-mouse-low-dpi.c
index 9525058e..a01b89f1 100644
--- a/test/litest-device-mouse-low-dpi.c
+++ b/test/litest-device-mouse-low-dpi.c
@@ -39,6 +39,9 @@ static int events[] = {
EV_REL, REL_X,
EV_REL, REL_Y,
EV_REL, REL_WHEEL,
+ EV_REL, REL_WHEEL_HI_RES,
+ EV_REL, REL_HWHEEL,
+ EV_REL, REL_HWHEEL_HI_RES,
-1 , -1,
};
diff --git a/test/litest-device-mouse.c b/test/litest-device-mouse.c
index 68275be8..d2c02fa3 100644
--- a/test/litest-device-mouse.c
+++ b/test/litest-device-mouse.c
@@ -39,6 +39,7 @@ static int events[] = {
EV_REL, REL_X,
EV_REL, REL_Y,
EV_REL, REL_WHEEL,
+ EV_REL, REL_WHEEL_HI_RES,
-1 , -1,
};
diff --git a/test/litest.c b/test/litest.c
index b000fe8b..a900c1c8 100644
--- a/test/litest.c
+++ b/test/litest.c
@@ -3097,6 +3097,15 @@ litest_event_type_str(enum libinput_event_type type)
case LIBINPUT_EVENT_POINTER_AXIS:
str = "AXIS";
break;
+ case LIBINPUT_EVENT_POINTER_SCROLL_WHEEL:
+ str = "SCROLL_WHEEL";
+ break;
+ case LIBINPUT_EVENT_POINTER_SCROLL_FINGER:
+ str = "SCROLL_FINGER";
+ break;
+ case LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS:
+ str = "SCROLL_CONTINUOUS";
+ break;
case LIBINPUT_EVENT_TOUCH_DOWN:
str = "TOUCH DOWN";
break;
@@ -3549,24 +3558,42 @@ litest_is_button_event(struct libinput_event *event,
struct libinput_event_pointer *
litest_is_axis_event(struct libinput_event *event,
+ enum libinput_event_type axis_type,
enum libinput_pointer_axis axis,
enum libinput_pointer_axis_source source)
{
struct libinput_event_pointer *ptrev;
- enum libinput_event_type type = LIBINPUT_EVENT_POINTER_AXIS;
+
+ litest_assert(axis_type == LIBINPUT_EVENT_POINTER_SCROLL_WHEEL ||
+ axis_type == LIBINPUT_EVENT_POINTER_SCROLL_FINGER ||
+ axis_type == LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS);
litest_assert_ptr_notnull(event);
- litest_assert_event_type(event, type);
+ litest_assert_event_type_is_one_of(event,
+ LIBINPUT_EVENT_POINTER_AXIS,
+ axis_type);
ptrev = libinput_event_get_pointer_event(event);
litest_assert(libinput_event_pointer_has_axis(ptrev, axis));
if (source != 0)
- litest_assert_int_eq(libinput_event_pointer_get_axis_source(ptrev),
+ litest_assert_int_eq(litest_event_pointer_get_axis_source(ptrev),
source);
return ptrev;
}
+bool
+litest_is_high_res_axis_event(struct libinput_event *event)
+{
+ litest_assert_event_type_is_one_of(event,
+ LIBINPUT_EVENT_POINTER_AXIS,
+ LIBINPUT_EVENT_POINTER_SCROLL_WHEEL,
+ LIBINPUT_EVENT_POINTER_SCROLL_FINGER,
+ LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS);
+
+ return (libinput_event_get_type(event) != LIBINPUT_EVENT_POINTER_AXIS);
+}
+
struct libinput_event_pointer *
litest_is_motion_event(struct libinput_event *event)
{
@@ -3751,6 +3778,53 @@ litest_is_proximity_event(struct libinput_event *event,
return tev;
}
+double
+litest_event_pointer_get_value(struct libinput_event_pointer *ptrev,
+ enum libinput_pointer_axis axis)
+{
+ struct libinput_event *event;
+ enum libinput_event_type type;
+
+ event = libinput_event_pointer_get_base_event(ptrev);
+ type = libinput_event_get_type(event);
+
+ switch (type) {
+ case LIBINPUT_EVENT_POINTER_AXIS:
+ return libinput_event_pointer_get_axis_value(ptrev, axis);
+ case LIBINPUT_EVENT_POINTER_SCROLL_WHEEL:
+ return libinput_event_pointer_get_scroll_value_v120(ptrev, axis);
+ case LIBINPUT_EVENT_POINTER_SCROLL_FINGER:
+ case LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS:
+ return libinput_event_pointer_get_scroll_value(ptrev, axis);
+ default:
+ abort();
+ }
+}
+
+enum libinput_pointer_axis_source
+litest_event_pointer_get_axis_source(struct libinput_event_pointer *ptrev)
+{
+ struct libinput_event *event;
+ enum libinput_event_type type;
+
+ event = libinput_event_pointer_get_base_event(ptrev);
+ type = libinput_event_get_type(event);
+
+ if (type == LIBINPUT_EVENT_POINTER_AXIS)
+ return libinput_event_pointer_get_axis_source(ptrev);
+
+ switch (type) {
+ case LIBINPUT_EVENT_POINTER_SCROLL_WHEEL:
+ return LIBINPUT_POINTER_AXIS_SOURCE_WHEEL;
+ case LIBINPUT_EVENT_POINTER_SCROLL_FINGER:
+ return LIBINPUT_POINTER_AXIS_SOURCE_FINGER;
+ case LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS:
+ return LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS;
+ default:
+ abort();
+ }
+}
+
void litest_assert_tablet_proximity_event(struct libinput *li,
enum libinput_tablet_tool_proximity_state state)
{
@@ -3912,50 +3986,109 @@ litest_assert_pad_key_event(struct libinput *li,
void
litest_assert_scroll(struct libinput *li,
+ enum libinput_event_type axis_type,
enum libinput_pointer_axis axis,
int minimum_movement)
{
- struct libinput_event *event, *next_event;
+ struct libinput_event *event;
struct libinput_event_pointer *ptrev;
+ bool last_hi_res_event_found, last_low_res_event_found;
int value;
int nevents = 0;
+ litest_assert(axis_type == LIBINPUT_EVENT_POINTER_SCROLL_WHEEL ||
+ axis_type == LIBINPUT_EVENT_POINTER_SCROLL_FINGER ||
+ axis_type == LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS);
+
+ last_hi_res_event_found = false;
+ last_low_res_event_found = false;
event = libinput_get_event(li);
- next_event = libinput_get_event(li);
- litest_assert_ptr_notnull(next_event); /* At least 1 scroll + stop scroll */
+ litest_assert_ptr_notnull(event);
while (event) {
- ptrev = litest_is_axis_event(event, axis, 0);
+ int min = minimum_movement;
+
+ ptrev = litest_is_axis_event(event, axis_type, axis, 0);
nevents++;
- if (next_event) {
- int min = minimum_movement;
+ /* Due to how the hysteresis works on touchpad
+ * events, the first event is reduced by the
+ * hysteresis margin that can cause the first event
+ * go under the minimum we expect for all other
+ * events */
+ if (nevents == 1)
+ min = minimum_movement/2;
+
+ value = litest_event_pointer_get_value(ptrev, axis);
+ if (litest_is_high_res_axis_event(event)) {
+ litest_assert(!last_hi_res_event_found);
- value = libinput_event_pointer_get_axis_value(ptrev,
- axis);
- /* Due to how the hysteresis works on touchpad
- * events, the first event is reduced by the
- * hysteresis margin that can cause the first event
- * go under the minimum we expect for all other
- * events */
- if (nevents == 1)
- min = minimum_movement/2;
+ if (axis_type == LIBINPUT_EVENT_POINTER_SCROLL_WHEEL)
+ min *= 120;
- /* Normal scroll event, check dir */
+ if (value == 0)
+ last_hi_res_event_found = true;
+ } else {
+ litest_assert(!last_low_res_event_found);
+
+ if (value == 0)
+ last_low_res_event_found = true;
+ }
+
+ if (value != 0) {
if (minimum_movement > 0)
litest_assert_int_ge(value, min);
else
litest_assert_int_le(value, min);
+ }
+
+ libinput_event_destroy(event);
+ event = libinput_get_event(li);
+ }
+
+ litest_assert(last_low_res_event_found);
+ litest_assert(last_hi_res_event_found);
+}
+
+void
+litest_assert_axis_end_sequence(struct libinput *li,
+ enum libinput_event_type axis_type,
+ enum libinput_pointer_axis axis,
+ enum libinput_pointer_axis_source source)
+{
+ struct libinput_event *event;
+ struct libinput_event_pointer *ptrev;
+ bool last_hi_res_event_found, last_low_res_event_found;
+ double val;
+ int i;
+
+ litest_assert(axis_type == LIBINPUT_EVENT_POINTER_SCROLL_WHEEL ||
+ axis_type == LIBINPUT_EVENT_POINTER_SCROLL_FINGER ||
+ axis_type == LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS);
+
+ last_hi_res_event_found = false;
+ last_low_res_event_found = false;
+
+ /* both high and low scroll end events must be sent */
+ for (i = 0; i < 2; i++) {
+ event = libinput_get_event(li);
+ ptrev = litest_is_axis_event(event, axis_type, axis, source);
+ val = litest_event_pointer_get_value(ptrev, axis);
+ ck_assert(val == 0.0);
+
+ if (litest_is_high_res_axis_event(event)) {
+ litest_assert(!last_hi_res_event_found);
+ last_hi_res_event_found = true;
} else {
- /* Last scroll event, must be 0 */
- ck_assert_double_eq(
- libinput_event_pointer_get_axis_value(ptrev, axis),
- 0.0);
+ litest_assert(!last_low_res_event_found);
+ last_low_res_event_found = true;
}
+
libinput_event_destroy(event);
- event = next_event;
- next_event = libinput_get_event(li);
}
+
+ litest_assert(last_low_res_event_found);
+ litest_assert(last_hi_res_event_found);
}
void
@@ -3979,6 +4112,30 @@ litest_assert_only_typed_events(struct libinput *li,
}
void
+litest_assert_only_axis_events(struct libinput *li,
+ enum libinput_event_type axis_type)
+{
+ struct libinput_event *event;
+
+ litest_assert(axis_type == LIBINPUT_EVENT_POINTER_SCROLL_WHEEL ||
+ axis_type == LIBINPUT_EVENT_POINTER_SCROLL_FINGER ||
+ axis_type == LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS);
+
+ libinput_dispatch(li);
+ event = libinput_get_event(li);
+ litest_assert_notnull(event);
+
+ while (event) {
+ litest_assert_event_type_is_one_of(event,
+ LIBINPUT_EVENT_POINTER_AXIS,
+ axis_type);
+ libinput_event_destroy(event);
+ libinput_dispatch(li);
+ event = libinput_get_event(li);
+ }
+}
+
+void
litest_assert_no_typed_events(struct libinput *li,
enum libinput_event_type type)
{
diff --git a/test/litest.h b/test/litest.h
index 888fb4a6..b6ffbf4e 100644
--- a/test/litest.h
+++ b/test/litest.h
@@ -747,9 +747,13 @@ litest_is_button_event(struct libinput_event *event,
struct libinput_event_pointer *
litest_is_axis_event(struct libinput_event *event,
+ enum libinput_event_type axis_type,
enum libinput_pointer_axis axis,
enum libinput_pointer_axis_source source);
+bool
+litest_is_high_res_axis_event(struct libinput_event *event);
+
struct libinput_event_pointer *
litest_is_motion_event(struct libinput_event *event);
@@ -797,6 +801,13 @@ struct libinput_event_tablet_tool *
litest_is_proximity_event(struct libinput_event *event,
enum libinput_tablet_tool_proximity_state state);
+double
+litest_event_pointer_get_value(struct libinput_event_pointer *ptrev,
+ enum libinput_pointer_axis axis);
+
+enum libinput_pointer_axis_source
+litest_event_pointer_get_axis_source(struct libinput_event_pointer *event);
+
void
litest_assert_key_event(struct libinput *li, unsigned int key,
enum libinput_key_state state);
@@ -808,14 +819,25 @@ litest_assert_button_event(struct libinput *li,
void
litest_assert_scroll(struct libinput *li,
+ enum libinput_event_type axis_type,
enum libinput_pointer_axis axis,
int minimum_movement);
void
+litest_assert_axis_end_sequence(struct libinput *li,
+ enum libinput_event_type axis_type,
+ enum libinput_pointer_axis axis,
+ enum libinput_pointer_axis_source source);
+
+void
litest_assert_only_typed_events(struct libinput *li,
enum libinput_event_type type);
void
+litest_assert_only_axis_events(struct libinput *li,
+ enum libinput_event_type axis_type);
+
+void
litest_assert_no_typed_events(struct libinput *li,
enum libinput_event_type type);
diff --git a/test/test-device.c b/test/test-device.c
index 57631f1d..00728d33 100644
--- a/test/test-device.c
+++ b/test/test-device.c
@@ -1337,7 +1337,11 @@ START_TEST(device_quirks_no_abs_mt_y)
struct libinput *li = dev->libinput;
struct libinput_event *event;
struct libinput_event_pointer *pev;
- int code;
+ bool hi_res_event_found, low_res_event_found;
+ int code, i;
+
+ hi_res_event_found = false;
+ low_res_event_found = false;
litest_drain_events(li);
@@ -1345,11 +1349,27 @@ START_TEST(device_quirks_no_abs_mt_y)
litest_event(dev, EV_SYN, SYN_REPORT, 0);
libinput_dispatch(li);
- event = libinput_get_event(li);
- pev = litest_is_axis_event(event,
- LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL,
- LIBINPUT_POINTER_AXIS_SOURCE_WHEEL);
- libinput_event_destroy(libinput_event_pointer_get_base_event(pev));
+ /* both high and low scroll end events must be sent */
+ for (i = 0; i < 2; i++) {
+ event = libinput_get_event(li);
+ pev = litest_is_axis_event(event,
+ LIBINPUT_EVENT_POINTER_SCROLL_WHEEL,
+ LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL,
+ LIBINPUT_POINTER_AXIS_SOURCE_WHEEL);
+
+ if (litest_is_high_res_axis_event(event)) {
+ litest_assert(!hi_res_event_found);
+ hi_res_event_found = true;
+ } else {
+ litest_assert(!low_res_event_found);
+ low_res_event_found = true;
+ }
+
+ libinput_event_destroy(libinput_event_pointer_get_base_event(pev));
+ }
+
+ litest_assert(low_res_event_found);
+ litest_assert(hi_res_event_found);
for (code = ABS_MISC + 1; code < ABS_MAX; code++) {
litest_event(dev, EV_ABS, code, 1);
diff --git a/test/test-gestures.c b/test/test-gestures.c
index 660a08a6..bf60bc22 100644
--- a/test/test-gestures.c
+++ b/test/test-gestures.c
@@ -806,7 +806,10 @@ test_gesture_3fg_buttonarea_scroll(enum hold_gesture_behaviour hold)
2);
}
- litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, 4);
+ litest_assert_scroll(li,
+ LIBINPUT_EVENT_POINTER_SCROLL_FINGER,
+ LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
+ 4);
}
static void
@@ -1301,7 +1304,10 @@ START_TEST(gestures_3fg_buttonarea_scroll_btntool)
litest_touch_up(dev, 1);
libinput_dispatch(li);
- litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, 4);
+ litest_assert_scroll(li,
+ LIBINPUT_EVENT_POINTER_SCROLL_FINGER,
+ LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
+ 4);
}
END_TEST
diff --git a/test/test-pointer.c b/test/test-pointer.c
index 6ed0a37b..2be64ee2 100644
--- a/test/test-pointer.c
+++ b/test/test-pointer.c
@@ -603,7 +603,9 @@ out:
}
static void
-test_wheel_event(struct litest_device *dev, int which, int amount)
+test_high_and_low_wheel_events_value(struct litest_device *dev,
+ int which,
+ int v120_amount)
{
struct libinput *li = dev->libinput;
struct libinput_event *event;
@@ -611,40 +613,64 @@ test_wheel_event(struct litest_device *dev, int which, int amount)
enum libinput_pointer_axis axis;
enum libinput_pointer_axis_source source;
- double scroll_step, expected, discrete;
+ double scroll_step, expected, discrete, v120;
scroll_step = wheel_click_angle(dev, which);
source = LIBINPUT_POINTER_AXIS_SOURCE_WHEEL;
- expected = amount * scroll_step;
- discrete = amount;
+ expected = scroll_step * (v120_amount/120);
+ discrete = v120_amount/120;
+ v120 = v120_amount;
if (libinput_device_config_scroll_get_natural_scroll_enabled(dev->libinput_device)) {
expected *= -1;
discrete *= -1;
+ v120 *= -1;
+ }
+
+ axis = (which == REL_WHEEL || which == REL_WHEEL_HI_RES) ?
+ LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL :
+ LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL;
+
+ event = libinput_get_event(li);
+
+ while(event) {
+ ptrev = litest_is_axis_event(event,
+ LIBINPUT_EVENT_POINTER_SCROLL_WHEEL,
+ axis,
+ source);
+
+ if (!litest_is_high_res_axis_event(event)) {
+ litest_assert_double_eq(
+ libinput_event_pointer_get_axis_value(ptrev, axis),
+ expected);
+ litest_assert_double_eq(
+ libinput_event_pointer_get_axis_value_discrete(ptrev, axis),
+ discrete);
+ } else {
+ litest_assert_double_eq(
+ libinput_event_pointer_get_scroll_value_v120(ptrev, axis),
+ v120);
+ }
+ libinput_event_destroy(event);
+ event = libinput_get_event(li);
}
+}
+
+static void
+test_wheel_event(struct litest_device *dev, int which, int amount)
+{
+ struct libinput *li = dev->libinput;
+ int event_amount = amount;
/* mouse scroll wheels are 'upside down' */
if (which == REL_WHEEL)
- amount *= -1;
- litest_event(dev, EV_REL, which, amount);
+ event_amount *= -1;
+ litest_event(dev, EV_REL, which, event_amount);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
libinput_dispatch(li);
- axis = (which == REL_WHEEL) ?
- LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL :
- LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL;
-
- event = libinput_get_event(li);
- ptrev = litest_is_axis_event(event, axis, source);
-
- litest_assert_double_eq(
- libinput_event_pointer_get_axis_value(ptrev, axis),
- expected);
- litest_assert_double_eq(
- libinput_event_pointer_get_axis_value_discrete(ptrev, axis),
- discrete);
- libinput_event_destroy(event);
+ test_high_and_low_wheel_events_value(dev, which, amount * 120);
}
START_TEST(pointer_scroll_wheel)
@@ -699,6 +725,84 @@ START_TEST(pointer_scroll_wheel_pressed_noscroll)
}
END_TEST
+START_TEST(pointer_scroll_hi_res_wheel_pressed_noscroll)
+{
+ struct litest_device *dev = litest_current_device();
+ struct libinput *li = dev->libinput;
+
+ litest_drain_events(li);
+
+ litest_button_click_debounced(dev, li, BTN_MIDDLE, true);
+ litest_drain_events(li);
+
+ for (int i = 0; i < 10; i++) {
+ litest_event(dev, EV_REL, REL_WHEEL_HI_RES, 12);
+ litest_event(dev, EV_REL, REL_HWHEEL_HI_RES, 12);
+ litest_event(dev, EV_SYN, SYN_REPORT, 0);
+ }
+
+ libinput_dispatch(li);
+
+ litest_assert_empty_queue(li);
+
+ litest_button_click_debounced(dev, li, BTN_MIDDLE, false);
+}
+END_TEST
+
+static void
+test_hi_res_wheel_event(struct litest_device *dev, int which, int v120_amount)
+{
+ struct libinput *li = dev->libinput;
+
+ switch(which) {
+ case REL_WHEEL_HI_RES:
+ /* mouse scroll wheels are 'upside down' */
+ litest_event(dev, EV_REL, REL_WHEEL_HI_RES, -1 * v120_amount);
+ litest_event(dev, EV_REL, REL_WHEEL, -1 * v120_amount/120);
+ litest_event(dev, EV_SYN, SYN_REPORT, 0);
+ break;
+ case REL_HWHEEL_HI_RES:
+ litest_event(dev, EV_REL, REL_HWHEEL_HI_RES, v120_amount);
+ litest_event(dev, EV_REL, REL_HWHEEL, v120_amount/120);
+ litest_event(dev, EV_SYN, SYN_REPORT, 0);
+ break;
+ default:
+ abort();
+ }
+
+ libinput_dispatch(li);
+
+ test_high_and_low_wheel_events_value(dev, which, v120_amount);
+}
+
+START_TEST(pointer_scroll_wheel_hires)
+{
+ struct litest_device *dev = litest_current_device();
+
+ if (!libevdev_has_event_code(dev->evdev, EV_REL, REL_WHEEL_HI_RES) &&
+ !libevdev_has_event_code(dev->evdev, EV_REL, REL_HWHEEL_HI_RES))
+ return;
+
+ litest_drain_events(dev->libinput);
+
+ for (int axis = REL_WHEEL_HI_RES; axis <= REL_HWHEEL_HI_RES; axis++) {
+ if (!libevdev_has_event_code(dev->evdev, EV_REL, axis))
+ continue;
+
+ test_hi_res_wheel_event(dev, axis, -120);
+ test_hi_res_wheel_event(dev, axis, 120);
+
+ test_hi_res_wheel_event(dev, axis, -5 * 120);
+ test_hi_res_wheel_event(dev, axis, 6 * 120);
+
+ test_hi_res_wheel_event(dev, axis, 30);
+ test_hi_res_wheel_event(dev, axis, -40);
+ test_hi_res_wheel_event(dev, axis, -60);
+ test_hi_res_wheel_event(dev, axis, 180);
+ }
+}
+END_TEST
+
START_TEST(pointer_scroll_natural_defaults)
{
struct litest_device *dev = litest_current_device();
@@ -785,6 +889,7 @@ START_TEST(pointer_scroll_has_axis_invalid)
libinput_dispatch(li);
event = libinput_get_event(li);
pev = litest_is_axis_event(event,
+ LIBINPUT_EVENT_POINTER_SCROLL_WHEEL,
LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
0);
@@ -1054,13 +1159,25 @@ START_TEST(pointer_scroll_button)
litest_drain_events(li);
litest_button_scroll(dev, BTN_LEFT, 1, 6);
- litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, 6);
+ litest_assert_scroll(li,
+ LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS,
+ LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
+ 6);
litest_button_scroll(dev, BTN_LEFT, 1, -7);
- litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, -7);
+ litest_assert_scroll(li,
+ LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS,
+ LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
+ -7);
litest_button_scroll(dev, BTN_LEFT, 8, 1);
- litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, 8);
+ litest_assert_scroll(li,
+ LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS,
+ LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL,
+ 8);
litest_button_scroll(dev, BTN_LEFT, -9, 1);
- litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, -9);
+ litest_assert_scroll(li,
+ LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS,
+ LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL,
+ -9);
/* scroll smaller than the threshold should not generate axis events */
litest_button_scroll(dev, BTN_LEFT, 1, 1);
@@ -1185,7 +1302,10 @@ START_TEST(pointer_scroll_button_middle_emulation)
litest_button_click(dev, BTN_RIGHT, 0);
libinput_dispatch(li);
- litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, -1);
+ litest_assert_scroll(li,
+ LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS,
+ LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
+ -1);
litest_assert_empty_queue(li);
/* Restore default scroll behavior */
@@ -1273,7 +1393,10 @@ START_TEST(pointer_scroll_button_lock)
litest_button_click_debounced(dev, li, BTN_LEFT, false);
libinput_dispatch(li);
- litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, 6);
+ litest_assert_scroll(li,
+ LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS,
+ LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
+ 6);
litest_assert_empty_queue(li);
@@ -1374,7 +1497,10 @@ START_TEST(pointer_scroll_button_lock_enable_while_down)
litest_button_click_debounced(dev, li, BTN_LEFT, true);
litest_button_click_debounced(dev, li, BTN_LEFT, false);
- litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, 6);
+ litest_assert_scroll(li,
+ LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS,
+ LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
+ 6);
litest_assert_empty_queue(li);
@@ -1437,7 +1563,10 @@ START_TEST(pointer_scroll_button_lock_enable_while_down_just_lock)
litest_button_click_debounced(dev, li, BTN_LEFT, true);
litest_button_click_debounced(dev, li, BTN_LEFT, false);
- litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, 6);
+ litest_assert_scroll(li,
+ LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS,
+ LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
+ 6);
litest_assert_empty_queue(li);
@@ -1479,7 +1608,8 @@ START_TEST(pointer_scroll_button_lock_otherbutton)
litest_event(dev, EV_REL, REL_Y, 6);
litest_event(dev, EV_SYN, SYN_REPORT, 0);
}
- litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_AXIS);
+ litest_assert_only_axis_events(li,
+ LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS);
/* other button passes on normally */
litest_button_click_debounced(dev, li, BTN_RIGHT, true);
@@ -1490,7 +1620,8 @@ START_TEST(pointer_scroll_button_lock_otherbutton)
/* stop scroll lock */
litest_button_click_debounced(dev, li, BTN_LEFT, true);
litest_button_click_debounced(dev, li, BTN_LEFT, false);
- litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_AXIS);
+ litest_assert_only_axis_events(li,
+ LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS);
/* other button passes on normally */
litest_button_click_debounced(dev, li, BTN_RIGHT, true);
@@ -1551,7 +1682,10 @@ START_TEST(pointer_scroll_button_lock_enable_while_otherbutton_down)
litest_button_click_debounced(dev, li, BTN_LEFT, true);
litest_button_click_debounced(dev, li, BTN_LEFT, false);
- litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, 6);
+ litest_assert_scroll(li,
+ LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS,
+ LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
+ 6);
litest_assert_empty_queue(li);
/* back to motion */
@@ -1666,7 +1800,10 @@ START_TEST(pointer_scroll_button_lock_middlebutton)
LIBINPUT_BUTTON_STATE_PRESSED);
litest_assert_button_event(li, BTN_RIGHT,
LIBINPUT_BUTTON_STATE_RELEASED);
- litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, 6);
+ litest_assert_scroll(li,
+ LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS,
+ LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
+ 6);
litest_assert_empty_queue(li);
break;
case LRLR:
@@ -2511,10 +2648,11 @@ START_TEST(middlebutton_button_scrolling)
ev = libinput_get_event(li);
do {
pev = litest_is_axis_event(ev,
+ LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS,
LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS);
- ck_assert_double_gt(libinput_event_pointer_get_axis_value(pev,
- LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL),
+ ck_assert_double_gt(litest_event_pointer_get_value(pev,
+ LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL),
0.0);
libinput_event_destroy(ev);
ev = libinput_get_event(li);
@@ -2524,14 +2662,10 @@ START_TEST(middlebutton_button_scrolling)
litest_event(dev, EV_SYN, SYN_REPORT, 0);
libinput_dispatch(li);
- ev = libinput_get_event(li);
- pev = litest_is_axis_event(ev,
- LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
- LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS);
- ck_assert_double_eq(libinput_event_pointer_get_axis_value(pev,
- LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL),
- 0.0);
- libinput_event_destroy(ev);
+ litest_assert_axis_end_sequence(li,
+ LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS,
+ LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
+ LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS);
/* no button release */
litest_assert_empty_queue(li);
@@ -3293,6 +3427,8 @@ TEST_COLLECTION(pointer)
litest_add(pointer_recover_from_lost_button_count, LITEST_BUTTON, LITEST_CLICKPAD);
litest_add(pointer_scroll_wheel, LITEST_WHEEL, LITEST_TABLET);
litest_add_for_device(pointer_scroll_wheel_pressed_noscroll, LITEST_MOUSE);
+ litest_add_for_device(pointer_scroll_hi_res_wheel_pressed_noscroll, LITEST_MOUSE);
+ litest_add(pointer_scroll_wheel_hires, LITEST_WHEEL, LITEST_TABLET);
litest_add(pointer_scroll_button, LITEST_RELATIVE|LITEST_BUTTON, LITEST_ANY);
litest_add(pointer_scroll_button_noscroll, LITEST_ABSOLUTE|LITEST_BUTTON, LITEST_RELATIVE);
litest_add(pointer_scroll_button_noscroll, LITEST_ANY, LITEST_RELATIVE|LITEST_BUTTON);
diff --git a/test/test-switch.c b/test/test-switch.c
index 8d6f56b3..f4f3402e 100644
--- a/test/test-switch.c
+++ b/test/test-switch.c
@@ -406,18 +406,17 @@ START_TEST(switch_disable_touchpad_edge_scroll_interrupt)
litest_timeout_edgescroll();
litest_touch_move_to(touchpad, 0, 99, 20, 99, 30, 10);
libinput_dispatch(li);
- litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_AXIS);
+ litest_assert_only_axis_events(li, LIBINPUT_EVENT_POINTER_SCROLL_FINGER);
litest_grab_device(sw);
litest_switch_action(sw, which, LIBINPUT_SWITCH_STATE_ON);
litest_ungrab_device(sw);
libinput_dispatch(li);
- event = libinput_get_event(li);
- litest_is_axis_event(event,
- LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
- LIBINPUT_POINTER_AXIS_SOURCE_FINGER);
- libinput_event_destroy(event);
+ litest_assert_axis_end_sequence(li,
+ LIBINPUT_EVENT_POINTER_SCROLL_FINGER,
+ LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
+ LIBINPUT_POINTER_AXIS_SOURCE_FINGER);
event = libinput_get_event(li);
litest_is_switch_event(event, which, LIBINPUT_SWITCH_STATE_ON);
diff --git a/test/test-touchpad-tap.c b/test/test-touchpad-tap.c
index b9d57ce8..064c9159 100644
--- a/test/test-touchpad-tap.c
+++ b/test/test-touchpad-tap.c
@@ -1735,7 +1735,7 @@ START_TEST(touchpad_tap_n_drag_2fg_scroll)
litest_assert_button_event(li, button,
LIBINPUT_BUTTON_STATE_RELEASED);
- litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_AXIS);
+ litest_assert_only_axis_events(li, LIBINPUT_EVENT_POINTER_SCROLL_FINGER);
litest_assert_empty_queue(li);
}
@@ -1824,7 +1824,7 @@ START_TEST(touchpad_tap_n_drag_draglock_2fg_scroll)
litest_assert_button_event(li, button,
LIBINPUT_BUTTON_STATE_RELEASED);
- litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_AXIS);
+ litest_assert_only_axis_events(li, LIBINPUT_EVENT_POINTER_SCROLL_FINGER);
litest_assert_empty_queue(li);
}
diff --git a/test/test-touchpad.c b/test/test-touchpad.c
index 4043199b..b7b34598 100644
--- a/test/test-touchpad.c
+++ b/test/test-touchpad.c
@@ -149,13 +149,25 @@ START_TEST(touchpad_2fg_scroll)
litest_drain_events(li);
test_2fg_scroll(dev, 0.1, 40, false);
- litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, 9);
+ litest_assert_scroll(li,
+ LIBINPUT_EVENT_POINTER_SCROLL_FINGER,
+ LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
+ 9);
test_2fg_scroll(dev, 0.1, -40, false);
- litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, -9);
+ litest_assert_scroll(li,
+ LIBINPUT_EVENT_POINTER_SCROLL_FINGER,
+ LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
+ -9);
test_2fg_scroll(dev, 40, 0.1, false);
- litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, 9);
+ litest_assert_scroll(li,
+ LIBINPUT_EVENT_POINTER_SCROLL_FINGER,
+ LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL,
+ 9);
test_2fg_scroll(dev, -40, 0.1, false);
- litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, -9);
+ litest_assert_scroll(li,
+ LIBINPUT_EVENT_POINTER_SCROLL_FINGER,
+ LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL,
+ -9);
/* 2fg scroll smaller than the threshold should not generate events */
test_2fg_scroll(dev, 0.1, 0.1, true);
@@ -206,6 +218,9 @@ START_TEST(touchpad_2fg_scroll_initially_diagonal)
expected_nevents++;
}
+ /* both high-resolution and low-resolution events are generated */
+ expected_nevents *= 2;
+
libinput_dispatch(li);
event = libinput_get_event(li);
@@ -213,6 +228,7 @@ START_TEST(touchpad_2fg_scroll_initially_diagonal)
struct libinput_event_pointer *ptrev;
ptrev = litest_is_axis_event(event,
+ LIBINPUT_EVENT_POINTER_SCROLL_FINGER,
LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
LIBINPUT_POINTER_AXIS_SOURCE_FINGER);
ck_assert(!libinput_event_pointer_has_axis(ptrev,
@@ -247,15 +263,27 @@ is_single_axis_2fg_scroll(struct litest_device *dev,
event = libinput_get_event(li);
while (event) {
- litest_assert_event_type(event, LIBINPUT_EVENT_POINTER_AXIS);
- ptrev = litest_is_axis_event(event, on_axis,
+ ptrev = litest_is_axis_event(event,
+ LIBINPUT_EVENT_POINTER_SCROLL_FINGER,
+ on_axis,
LIBINPUT_POINTER_AXIS_SOURCE_FINGER);
has_on_axis = libinput_event_pointer_has_axis(ptrev, on_axis);
has_off_axis = libinput_event_pointer_has_axis(ptrev, off_axis);
if (has_on_axis && has_off_axis) {
- val = (libinput_event_pointer_get_axis_value(ptrev, off_axis) == 0.0);
+ val = (litest_event_pointer_get_value(ptrev, off_axis) == 0.0);
+
+ /* There must be an extra low/high-resolution event with
+ * the same axis value (0.0). */
+ libinput_event_destroy(event);
+ event = libinput_get_event(li);
+ ck_assert_notnull(event);
+ ptrev = litest_is_axis_event(event,
+ LIBINPUT_EVENT_POINTER_SCROLL_FINGER,
+ on_axis,
+ LIBINPUT_POINTER_AXIS_SOURCE_FINGER);
+ ck_assert(val == (litest_event_pointer_get_value(ptrev, off_axis) == 0.0));
break;
}
@@ -380,10 +408,14 @@ START_TEST(touchpad_2fg_scroll_slow_distance)
struct libinput_event *event;
double width, height;
double y_move = 100;
+ bool last_hi_res_event_found, last_low_res_event_found;
if (!litest_has_2fg_scroll(dev))
return;
+ last_hi_res_event_found = false;
+ last_low_res_event_found = false;
+
/* We want to move > 5 mm. */
ck_assert_int_eq(libinput_device_get_size(dev->libinput_device,
&width,
@@ -404,17 +436,28 @@ START_TEST(touchpad_2fg_scroll_slow_distance)
event = libinput_get_event(li);
ck_assert_notnull(event);
- /* last event is value 0, tested elsewhere */
- while (libinput_next_event_type(li) != LIBINPUT_EVENT_NONE) {
+ while (event) {
struct libinput_event_pointer *ptrev;
double axisval;
ptrev = litest_is_axis_event(event,
+ LIBINPUT_EVENT_POINTER_SCROLL_FINGER,
LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
0);
- axisval = libinput_event_pointer_get_axis_value(ptrev,
+ axisval = litest_event_pointer_get_value(ptrev,
LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
- ck_assert(axisval > 0.0);
+
+ if (litest_is_high_res_axis_event(event)) {
+ litest_assert(!last_hi_res_event_found);
+ if (axisval == 0)
+ last_hi_res_event_found = true;
+ } else {
+ litest_assert(!last_low_res_event_found);
+ if (axisval == 0)
+ last_low_res_event_found = true;
+ }
+
+ ck_assert(axisval >= 0.0);
/* this is to verify we test the right thing, if the value
is greater than scroll.threshold we triggered the wrong
@@ -425,6 +468,8 @@ START_TEST(touchpad_2fg_scroll_slow_distance)
event = libinput_get_event(li);
}
+ litest_assert(last_low_res_event_found);
+ litest_assert(last_hi_res_event_found);
litest_assert_empty_queue(li);
libinput_event_destroy(event);
}
@@ -447,6 +492,7 @@ START_TEST(touchpad_2fg_scroll_source)
while ((event = libinput_get_event(li))) {
litest_is_axis_event(event,
+ LIBINPUT_EVENT_POINTER_SCROLL_FINGER,
LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
LIBINPUT_POINTER_AXIS_SOURCE_FINGER);
libinput_event_destroy(event);
@@ -474,7 +520,7 @@ START_TEST(touchpad_2fg_scroll_semi_mt)
30, 40,
10);
- litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_AXIS);
+ litest_assert_only_axis_events(li, LIBINPUT_EVENT_POINTER_SCROLL_FINGER);
}
END_TEST
@@ -501,7 +547,7 @@ START_TEST(touchpad_2fg_scroll_return_to_motion)
libinput_dispatch(li);
litest_timeout_finger_switch();
libinput_dispatch(li);
- litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_AXIS);
+ litest_assert_only_axis_events(li, LIBINPUT_EVENT_POINTER_SCROLL_FINGER);
litest_touch_move_to(dev, 0, 49, 70, 49, 50, 10);
litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
@@ -513,7 +559,7 @@ START_TEST(touchpad_2fg_scroll_return_to_motion)
libinput_dispatch(li);
litest_timeout_finger_switch();
libinput_dispatch(li);
- litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_AXIS);
+ litest_assert_only_axis_events(li, LIBINPUT_EVENT_POINTER_SCROLL_FINGER);
/* move with second finger */
litest_touch_move_to(dev, 1, 51, 70, 51, 50, 10);
@@ -557,7 +603,7 @@ START_TEST(touchpad_2fg_scroll_from_btnareas)
litest_touch_up(dev, 0);
litest_touch_up(dev, 1);
- litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_AXIS);
+ litest_assert_only_axis_events(li, LIBINPUT_EVENT_POINTER_SCROLL_FINGER);
}
END_TEST
@@ -600,13 +646,25 @@ START_TEST(touchpad_scroll_natural_2fg)
libinput_device_config_scroll_set_natural_scroll_enabled(dev->libinput_device, 1);
test_2fg_scroll(dev, 0.1, 40, false);
- litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, -9);
+ litest_assert_scroll(li,
+ LIBINPUT_EVENT_POINTER_SCROLL_FINGER,
+ LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
+ -9);
test_2fg_scroll(dev, 0.1, -40, false);
- litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, 9);
+ litest_assert_scroll(li,
+ LIBINPUT_EVENT_POINTER_SCROLL_FINGER,
+ LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
+ 9);
test_2fg_scroll(dev, 40, 0.1, false);
- litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, -9);
+ litest_assert_scroll(li,
+ LIBINPUT_EVENT_POINTER_SCROLL_FINGER,
+ LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL,
+ -9);
test_2fg_scroll(dev, -40, 0.1, false);
- litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, 9);
+ litest_assert_scroll(li,
+ LIBINPUT_EVENT_POINTER_SCROLL_FINGER,
+ LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL,
+ 9);
}
END_TEST
@@ -626,7 +684,10 @@ START_TEST(touchpad_scroll_natural_edge)
litest_touch_up(dev, 0);
libinput_dispatch(li);
- litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, -4);
+ litest_assert_scroll(li,
+ LIBINPUT_EVENT_POINTER_SCROLL_FINGER,
+ LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
+ -4);
litest_assert_empty_queue(li);
litest_touch_down(dev, 0, 99, 80);
@@ -634,7 +695,10 @@ START_TEST(touchpad_scroll_natural_edge)
litest_touch_up(dev, 0);
libinput_dispatch(li);
- litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, 4);
+ litest_assert_scroll(li,
+ LIBINPUT_EVENT_POINTER_SCROLL_FINGER,
+ LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
+ 4);
litest_assert_empty_queue(li);
}
@@ -657,7 +721,10 @@ START_TEST(touchpad_edge_scroll_vert)
litest_touch_up(dev, 0);
libinput_dispatch(li);
- litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, 4);
+ litest_assert_scroll(li,
+ LIBINPUT_EVENT_POINTER_SCROLL_FINGER,
+ LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
+ 4);
litest_assert_empty_queue(li);
litest_touch_down(dev, 0, 99, 80);
@@ -665,7 +732,10 @@ START_TEST(touchpad_edge_scroll_vert)
litest_touch_up(dev, 0);
libinput_dispatch(li);
- litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, -4);
+ litest_assert_scroll(li,
+ LIBINPUT_EVENT_POINTER_SCROLL_FINGER,
+ LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
+ -4);
litest_assert_empty_queue(li);
}
END_TEST
@@ -701,7 +771,10 @@ START_TEST(touchpad_edge_scroll_horiz)
litest_touch_up(dev, 0);
libinput_dispatch(li);
- litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, 4);
+ litest_assert_scroll(li,
+ LIBINPUT_EVENT_POINTER_SCROLL_FINGER,
+ LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL,
+ 4);
litest_assert_empty_queue(li);
litest_touch_down(dev, 0, 70, 99);
@@ -709,7 +782,10 @@ START_TEST(touchpad_edge_scroll_horiz)
litest_touch_up(dev, 0);
libinput_dispatch(li);
- litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, -4);
+ litest_assert_scroll(li,
+ LIBINPUT_EVENT_POINTER_SCROLL_FINGER,
+ LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL,
+ -4);
litest_assert_empty_queue(li);
}
END_TEST
@@ -727,7 +803,10 @@ START_TEST(touchpad_edge_scroll_horiz_clickpad)
litest_touch_up(dev, 0);
libinput_dispatch(li);
- litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, 4);
+ litest_assert_scroll(li,
+ LIBINPUT_EVENT_POINTER_SCROLL_FINGER,
+ LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL,
+ 4);
litest_assert_empty_queue(li);
litest_touch_down(dev, 0, 70, 99);
@@ -735,7 +814,10 @@ START_TEST(touchpad_edge_scroll_horiz_clickpad)
litest_touch_up(dev, 0);
libinput_dispatch(li);
- litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, -4);
+ litest_assert_scroll(li,
+ LIBINPUT_EVENT_POINTER_SCROLL_FINGER,
+ LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL,
+ -4);
litest_assert_empty_queue(li);
}
END_TEST
@@ -861,10 +943,11 @@ START_TEST(touchpad_edge_scroll_timeout)
double value;
ptrev = litest_is_axis_event(event,
+ LIBINPUT_EVENT_POINTER_SCROLL_FINGER,
LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
0);
- value = libinput_event_pointer_get_axis_value(ptrev,
- LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
+ value = litest_event_pointer_get_value(ptrev,
+ LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
ck_assert_double_lt(value, 5.0);
libinput_event_destroy(event);
nevents++;
@@ -896,7 +979,10 @@ START_TEST(touchpad_edge_scroll_no_motion)
litest_touch_up(dev, 0);
libinput_dispatch(li);
- litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, 4);
+ litest_assert_scroll(li,
+ LIBINPUT_EVENT_POINTER_SCROLL_FINGER,
+ LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
+ 4);
litest_assert_empty_queue(li);
}
END_TEST
@@ -938,10 +1024,11 @@ START_TEST(touchpad_edge_scroll_source)
while ((event = libinput_get_event(li))) {
struct libinput_event_pointer *ptrev;
- ck_assert_int_eq(libinput_event_get_type(event),
- LIBINPUT_EVENT_POINTER_AXIS);
- ptrev = libinput_event_get_pointer_event(event);
- ck_assert_int_eq(libinput_event_pointer_get_axis_source(ptrev),
+ ptrev = litest_is_axis_event(event,
+ LIBINPUT_EVENT_POINTER_SCROLL_FINGER,
+ LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
+ LIBINPUT_POINTER_AXIS_SOURCE_FINGER);
+ ck_assert_int_eq(litest_event_pointer_get_axis_source(ptrev),
LIBINPUT_POINTER_AXIS_SOURCE_FINGER);
libinput_event_destroy(event);
}
@@ -979,18 +1066,18 @@ START_TEST(touchpad_edge_scroll_into_buttonareas)
litest_touch_down(dev, 0, 99, 40);
litest_touch_move_to(dev, 0, 99, 40, 99, 95, 10);
- litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_AXIS);
+ litest_assert_only_axis_events(li, LIBINPUT_EVENT_POINTER_SCROLL_FINGER);
/* in the button zone now, make sure we still get events */
litest_touch_move_to(dev, 0, 99, 95, 99, 100, 10);
- litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_AXIS);
+ litest_assert_only_axis_events(li, LIBINPUT_EVENT_POINTER_SCROLL_FINGER);
/* and out of the zone again */
litest_touch_move_to(dev, 0, 99, 100, 99, 70, 10);
- litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_AXIS);
+ litest_assert_only_axis_events(li, LIBINPUT_EVENT_POINTER_SCROLL_FINGER);
/* still out of the zone */
litest_touch_move_to(dev, 0, 99, 70, 99, 50, 10);
- litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_AXIS);
+ litest_assert_only_axis_events(li, LIBINPUT_EVENT_POINTER_SCROLL_FINGER);
}
END_TEST
@@ -1010,15 +1097,15 @@ START_TEST(touchpad_edge_scroll_within_buttonareas)
/* within left button */
litest_touch_move_to(dev, 0, 20, 99, 40, 99, 10);
- litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_AXIS);
+ litest_assert_only_axis_events(li, LIBINPUT_EVENT_POINTER_SCROLL_FINGER);
/* over to right button */
litest_touch_move_to(dev, 0, 40, 99, 60, 99, 10);
- litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_AXIS);
+ litest_assert_only_axis_events(li, LIBINPUT_EVENT_POINTER_SCROLL_FINGER);
/* within right button */
litest_touch_move_to(dev, 0, 60, 99, 80, 99, 10);
- litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_AXIS);
+ litest_assert_only_axis_events(li, LIBINPUT_EVENT_POINTER_SCROLL_FINGER);
}
END_TEST
@@ -1027,8 +1114,6 @@ START_TEST(touchpad_edge_scroll_buttonareas_click_stops_scroll)
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
struct libinput_event *event;
- struct libinput_event_pointer *ptrev;
- double val;
if (!touchpad_has_horiz_edge_scroll_size(dev))
return;
@@ -1039,19 +1124,15 @@ START_TEST(touchpad_edge_scroll_buttonareas_click_stops_scroll)
litest_touch_down(dev, 0, 20, 95);
litest_touch_move_to(dev, 0, 20, 95, 70, 95, 10);
- litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_AXIS);
+ litest_assert_only_axis_events(li, LIBINPUT_EVENT_POINTER_SCROLL_FINGER);
litest_button_click(dev, BTN_LEFT, true);
libinput_dispatch(li);
- event = libinput_get_event(li);
- ptrev = litest_is_axis_event(event,
- LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL,
- LIBINPUT_POINTER_AXIS_SOURCE_FINGER);
- val = libinput_event_pointer_get_axis_value(ptrev,
- LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL);
- ck_assert(val == 0.0);
- libinput_event_destroy(event);
+ litest_assert_axis_end_sequence(li,
+ LIBINPUT_EVENT_POINTER_SCROLL_FINGER,
+ LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL,
+ LIBINPUT_POINTER_AXIS_SOURCE_FINGER);
event = libinput_get_event(li);
litest_is_button_event(event,
@@ -1083,8 +1164,6 @@ START_TEST(touchpad_edge_scroll_clickfinger_click_stops_scroll)
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
struct libinput_event *event;
- struct libinput_event_pointer *ptrev;
- double val;
if (!touchpad_has_horiz_edge_scroll_size(dev))
return;
@@ -1095,19 +1174,15 @@ START_TEST(touchpad_edge_scroll_clickfinger_click_stops_scroll)
litest_touch_down(dev, 0, 20, 95);
litest_touch_move_to(dev, 0, 20, 95, 70, 95, 10);
- litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_AXIS);
+ litest_assert_only_axis_events(li, LIBINPUT_EVENT_POINTER_SCROLL_FINGER);
litest_button_click(dev, BTN_LEFT, true);
libinput_dispatch(li);
- event = libinput_get_event(li);
- ptrev = litest_is_axis_event(event,
- LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL,
- LIBINPUT_POINTER_AXIS_SOURCE_FINGER);
- val = libinput_event_pointer_get_axis_value(ptrev,
- LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL);
- ck_assert(val == 0.0);
- libinput_event_destroy(event);
+ litest_assert_axis_end_sequence(li,
+ LIBINPUT_EVENT_POINTER_SCROLL_FINGER,
+ LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL,
+ LIBINPUT_POINTER_AXIS_SOURCE_FINGER);
event = libinput_get_event(li);
litest_is_button_event(event,
@@ -1142,15 +1217,14 @@ START_TEST(touchpad_edge_scroll_into_area)
litest_touch_down(dev, 0, 99, 20);
litest_touch_move_to(dev, 0, 99, 20, 99, 50, 15);
litest_touch_move_to(dev, 0, 99, 50, 20, 50, 15);
- litest_assert_only_typed_events(li,
- LIBINPUT_EVENT_POINTER_AXIS);
+ litest_assert_only_axis_events(li, LIBINPUT_EVENT_POINTER_SCROLL_FINGER);
+
litest_touch_move_to(dev, 0, 20, 50, 20, 20, 15);
litest_touch_move_to(dev, 0, 20, 20, 99, 20, 15);
litest_assert_empty_queue(li);
litest_touch_move_to(dev, 0, 99, 20, 99, 50, 15);
- litest_assert_only_typed_events(li,
- LIBINPUT_EVENT_POINTER_AXIS);
+ litest_assert_only_axis_events(li, LIBINPUT_EVENT_POINTER_SCROLL_FINGER);
}
END_TEST
@@ -1233,7 +1307,7 @@ START_TEST(touchpad_no_palm_detect_at_edge_for_edge_scrolling)
litest_touch_move_to(dev, 0, 99, 50, 99, 70, 5);
litest_touch_up(dev, 0);
- litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_AXIS);
+ litest_assert_only_axis_events(li, LIBINPUT_EVENT_POINTER_SCROLL_FINGER);
}
END_TEST
@@ -1636,7 +1710,7 @@ START_TEST(touchpad_no_palm_detect_2fg_scroll)
litest_assert_empty_queue(li);
litest_touch_move_two_touches(dev, 99, 50, 50, 50, 0, -20, 10);
- litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_AXIS);
+ litest_assert_only_axis_events(li, LIBINPUT_EVENT_POINTER_SCROLL_FINGER);
}
END_TEST
@@ -3322,7 +3396,8 @@ START_TEST(touchpad_trackpoint_mb_scroll)
litest_event(trackpoint, EV_SYN, SYN_REPORT, 0);
litest_button_click(touchpad, BTN_2, false);
- litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_AXIS);
+ litest_assert_only_axis_events(li,
+ LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS);
litest_delete_device(trackpoint);
}
@@ -3436,9 +3511,10 @@ START_TEST(touchpad_trackpoint_buttons_2fg_scroll)
struct libinput_event_pointer *pev;
pev = litest_is_axis_event(e,
+ LIBINPUT_EVENT_POINTER_SCROLL_FINGER,
LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
0);
- val = libinput_event_pointer_get_axis_value(pev,
+ val = litest_event_pointer_get_value(pev,
LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
ck_assert(val != 0.0);
libinput_event_destroy(e);
@@ -3452,15 +3528,16 @@ START_TEST(touchpad_trackpoint_buttons_2fg_scroll)
litest_touch_move_to(touchpad, 0, 40, 30, 40, 70, 10);
litest_touch_move_to(touchpad, 1, 60, 30, 60, 70, 10);
- litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_AXIS);
+ litest_assert_only_axis_events(li, LIBINPUT_EVENT_POINTER_SCROLL_FINGER);
while ((e = libinput_get_event(li))) {
struct libinput_event_pointer *pev;
pev = litest_is_axis_event(e,
+ LIBINPUT_EVENT_POINTER_SCROLL_FINGER,
LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
0);
- val = libinput_event_pointer_get_axis_value(pev,
+ val = litest_event_pointer_get_value(pev,
LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
ck_assert(val != 0.0);
libinput_event_destroy(e);
@@ -3479,7 +3556,7 @@ START_TEST(touchpad_trackpoint_buttons_2fg_scroll)
*/
litest_touch_move_to(touchpad, 0, 40, 70, 40, 60, 10);
litest_touch_move_to(touchpad, 1, 60, 70, 60, 60, 10);
- litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_AXIS);
+ litest_assert_only_axis_events(li, LIBINPUT_EVENT_POINTER_SCROLL_FINGER);
litest_touch_move_to(touchpad, 0, 40, 60, 40, 30, 10);
litest_touch_move_to(touchpad, 1, 60, 60, 60, 30, 10);
@@ -3489,6 +3566,7 @@ START_TEST(touchpad_trackpoint_buttons_2fg_scroll)
libinput_dispatch(li);
litest_assert_scroll(li,
+ LIBINPUT_EVENT_POINTER_SCROLL_FINGER,
LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
-1);
@@ -3684,7 +3762,7 @@ START_TEST(touchpad_state_after_syn_dropped_2fg_change)
litest_touch_move_two_touches(dev, 50, 50, 70, 50, 0, -20, 10);
litest_touch_up(dev, 0);
litest_touch_up(dev, 1);
- litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_AXIS);
+ litest_assert_only_axis_events(li, LIBINPUT_EVENT_POINTER_SCROLL_FINGER);
/* pointer motion still works? */
litest_touch_down(dev, 0, 50, 50);
@@ -4497,7 +4575,6 @@ START_TEST(touchpad_dwt_edge_scroll_interrupt)
struct litest_device *touchpad = litest_current_device();
struct litest_device *keyboard;
struct libinput *li = touchpad->libinput;
- struct libinput_event_pointer *stop_event;
if (!has_disable_while_typing(touchpad))
return;
@@ -4512,19 +4589,20 @@ START_TEST(touchpad_dwt_edge_scroll_interrupt)
litest_timeout_edgescroll();
litest_touch_move_to(touchpad, 0, 99, 20, 99, 30, 10);
libinput_dispatch(li);
- litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_AXIS);
+ litest_assert_only_axis_events(li, LIBINPUT_EVENT_POINTER_SCROLL_FINGER);
litest_keyboard_key(keyboard, KEY_A, true);
litest_keyboard_key(keyboard, KEY_A, false);
litest_keyboard_key(keyboard, KEY_A, true);
litest_keyboard_key(keyboard, KEY_A, false);
- /* scroll stop event */
+ /* scroll stop events (low and high resolution) */
litest_wait_for_event(li);
- stop_event = litest_is_axis_event(libinput_get_event(li),
- LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
- LIBINPUT_POINTER_AXIS_SOURCE_FINGER);
- libinput_event_destroy(libinput_event_pointer_get_base_event(stop_event));
+ litest_assert_axis_end_sequence(li,
+ LIBINPUT_EVENT_POINTER_SCROLL_FINGER,
+ LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
+ LIBINPUT_POINTER_AXIS_SOURCE_FINGER);
+
litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY);
litest_timeout_dwt_long();
@@ -5243,7 +5321,10 @@ START_TEST(touchpad_thumb_speed_empty_slots)
litest_touch_up(dev, 1);
litest_touch_up(dev, 2);
libinput_dispatch(li);
- litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, 2);
+ litest_assert_scroll(li,
+ LIBINPUT_EVENT_POINTER_SCROLL_FINGER,
+ LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
+ 2);
}
END_TEST
@@ -5368,7 +5449,7 @@ START_TEST(touchpad_thumb_no_doublethumb)
litest_touch_up(dev, 0);
litest_touch_up(dev, 1);
- litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_AXIS);
+ litest_assert_only_axis_events(li, LIBINPUT_EVENT_POINTER_SCROLL_FINGER);
}
END_TEST
@@ -6272,7 +6353,10 @@ START_TEST(touchpad_pressure_semi_mt_2fg_goes_light)
litest_pop_event_frame(dev);
libinput_dispatch(li);
- litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, 0);
+ litest_assert_scroll(li,
+ LIBINPUT_EVENT_POINTER_SCROLL_FINGER,
+ LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
+ 0);
litest_push_event_frame(dev);
litest_touch_move_extended(dev, 0, 40, 35, axes);
@@ -6603,7 +6687,7 @@ START_TEST(touchpad_speed_allow_nearby_finger)
litest_touch_up(dev, 0);
litest_touch_up(dev, 1);
- litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_AXIS);
+ litest_assert_only_axis_events(li, LIBINPUT_EVENT_POINTER_SCROLL_FINGER);
}
END_TEST
@@ -6671,7 +6755,7 @@ START_TEST(touchpad_speed_ignore_hovering_finger)
litest_touch_up(dev, 1);
litest_touch_up(dev, 0);
- litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_AXIS);
+ litest_assert_only_axis_events(li, LIBINPUT_EVENT_POINTER_SCROLL_FINGER);
}
END_TEST
diff --git a/test/test-trackpoint.c b/test/test-trackpoint.c
index 46484b4c..86f70296 100644
--- a/test/test-trackpoint.c
+++ b/test/test-trackpoint.c
@@ -77,13 +77,25 @@ START_TEST(trackpoint_scroll)
litest_drain_events(li);
litest_button_scroll(dev, BTN_MIDDLE, 1, 6);
- litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, 6);
+ litest_assert_scroll(li,
+ LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS,
+ LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
+ 6);
litest_button_scroll(dev, BTN_MIDDLE, 1, -7);
- litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, -7);
+ litest_assert_scroll(li,
+ LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS,
+ LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
+ -7);
litest_button_scroll(dev, BTN_MIDDLE, 8, 1);
- litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, 8);
+ litest_assert_scroll(li,
+ LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS,
+ LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL,
+ 8);
litest_button_scroll(dev, BTN_MIDDLE, -9, 1);
- litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, -9);
+ litest_assert_scroll(li,
+ LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS,
+ LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL,
+ -9);
/* scroll smaller than the threshold should not generate axis events */
litest_button_scroll(dev, BTN_MIDDLE, 1, 1);
@@ -147,7 +159,7 @@ START_TEST(trackpoint_scroll_source)
while ((event = libinput_get_event(li))) {
ptrev = libinput_event_get_pointer_event(event);
- ck_assert_int_eq(libinput_event_pointer_get_axis_source(ptrev),
+ ck_assert_int_eq(litest_event_pointer_get_axis_source(ptrev),
LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS);
libinput_event_destroy(event);
diff --git a/tools/libinput-debug-events.c b/tools/libinput-debug-events.c
index 9ac2b0c6..1fed8cb8 100644
--- a/tools/libinput-debug-events.c
+++ b/tools/libinput-debug-events.c
@@ -86,6 +86,15 @@ print_event_header(struct libinput_event *ev)
case LIBINPUT_EVENT_POINTER_AXIS:
type = "POINTER_AXIS";
break;
+ case LIBINPUT_EVENT_POINTER_SCROLL_WHEEL:
+ type = "POINTER_SCROLL_WHEEL";
+ break;
+ case LIBINPUT_EVENT_POINTER_SCROLL_FINGER:
+ type = "POINTER_SCROLL_FINGER";
+ break;
+ case LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS:
+ type = "POINTER_SCROLL_CONTINUOUS";
+ break;
case LIBINPUT_EVENT_TOUCH_DOWN:
type = "TOUCH_DOWN";
break;
@@ -156,7 +165,7 @@ print_event_header(struct libinput_event *ev)
prefix = (last_device != dev) ? '-' : ' ';
- printq("%c%-7s %-16s ",
+ printq("%c%-7s %-23s ",
prefix,
libinput_device_get_sysname(dev),
type);
@@ -474,46 +483,49 @@ static void
print_pointer_axis_event(struct libinput_event *ev)
{
struct libinput_event_pointer *p = libinput_event_get_pointer_event(ev);
- double v = 0, h = 0;
- int dv = 0, dh = 0;
+ double v = 0, h = 0, v120 = 0, h120 = 0;
const char *have_vert = "",
*have_horiz = "";
const char *source = "invalid";
+ enum libinput_pointer_axis axis;
+ enum libinput_event_type type;
+
+ type = libinput_event_get_type(ev);
- switch (libinput_event_pointer_get_axis_source(p)) {
- case LIBINPUT_POINTER_AXIS_SOURCE_WHEEL:
+ switch (type) {
+ case LIBINPUT_EVENT_POINTER_SCROLL_WHEEL:
source = "wheel";
break;
- case LIBINPUT_POINTER_AXIS_SOURCE_FINGER:
+ case LIBINPUT_EVENT_POINTER_SCROLL_FINGER:
source = "finger";
break;
- case LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS:
+ case LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS:
source = "continuous";
break;
- case LIBINPUT_POINTER_AXIS_SOURCE_WHEEL_TILT:
- source = "tilt";
+ default:
+ abort();
break;
}
- if (libinput_event_pointer_has_axis(p,
- LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL)) {
- v = libinput_event_pointer_get_axis_value(p,
- LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
- dv = libinput_event_pointer_get_axis_value_discrete(p,
- LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
+ axis = LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL;
+ if (libinput_event_pointer_has_axis(p, axis)) {
+ v = libinput_event_pointer_get_scroll_value(p, axis);
+ if (type == LIBINPUT_EVENT_POINTER_SCROLL_WHEEL)
+ v120 = libinput_event_pointer_get_scroll_value_v120(p, axis);
have_vert = "*";
}
- if (libinput_event_pointer_has_axis(p,
- LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL)) {
- h = libinput_event_pointer_get_axis_value(p,
- LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL);
- dh = libinput_event_pointer_get_axis_value_discrete(p,
- LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL);
+ axis = LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL;
+ if (libinput_event_pointer_has_axis(p, axis)) {
+ h = libinput_event_pointer_get_scroll_value(p, axis);
+ if (type == LIBINPUT_EVENT_POINTER_SCROLL_WHEEL)
+ h120 = libinput_event_pointer_get_scroll_value_v120(p, axis);
have_horiz = "*";
}
+
print_event_time(libinput_event_pointer_get_time(p));
- printq("vert %.2f/%d%s horiz %.2f/%d%s (%s)\n",
- v, dv, have_vert, h, dh, have_horiz, source);
+ printq("vert %.2f/%.1f%s horiz %.2f/%.1f%s (%s)\n",
+ v, v120, have_vert,
+ h, h120, have_horiz, source);
}
static void
@@ -833,9 +845,12 @@ handle_and_print_events(struct libinput *li)
tools_dispatch(li);
while ((ev = libinput_get_event(li))) {
- print_event_header(ev);
+ enum libinput_event_type type = libinput_event_get_type(ev);
- switch (libinput_event_get_type(ev)) {
+ if (type != LIBINPUT_EVENT_POINTER_AXIS)
+ print_event_header(ev);
+
+ switch (type) {
case LIBINPUT_EVENT_NONE:
abort();
case LIBINPUT_EVENT_DEVICE_ADDED:
@@ -859,6 +874,11 @@ handle_and_print_events(struct libinput *li)
print_pointer_button_event(ev);
break;
case LIBINPUT_EVENT_POINTER_AXIS:
+ /* ignore */
+ break;
+ case LIBINPUT_EVENT_POINTER_SCROLL_WHEEL:
+ case LIBINPUT_EVENT_POINTER_SCROLL_FINGER:
+ case LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS:
print_pointer_axis_event(ev);
break;
case LIBINPUT_EVENT_TOUCH_DOWN:
diff --git a/tools/libinput-debug-gui.c b/tools/libinput-debug-gui.c
index 861116e4..0ef66145 100644
--- a/tools/libinput-debug-gui.c
+++ b/tools/libinput-debug-gui.c
@@ -85,10 +85,6 @@ struct point {
double x, y;
};
-struct device_user_data {
- struct point scroll_accumulated;
-};
-
struct evdev_device {
struct list node;
struct libevdev *evdev;
@@ -1287,7 +1283,6 @@ register_evdev_device(struct window *w, struct libinput_device *dev)
const char *device_node;
int fd;
struct evdev_device *d;
- struct device_user_data *data;
ud = libinput_device_get_udev_device(dev);
device_node = udev_device_get_devnode(ud);
@@ -1310,9 +1305,6 @@ register_evdev_device(struct window *w, struct libinput_device *dev)
d->evdev = evdev;
d->libinput_device =libinput_device_ref(dev);
- data = zalloc(sizeof *data);
- libinput_device_set_user_data(dev, data);
-
c = g_io_channel_unix_new(fd);
g_io_channel_set_encoding(c, NULL, NULL);
d->source_id = g_io_add_watch(c, G_IO_IN,
@@ -1463,44 +1455,33 @@ static void
handle_event_axis(struct libinput_event *ev, struct window *w)
{
struct libinput_event_pointer *p = libinput_event_get_pointer_event(ev);
- struct libinput_device *dev = libinput_event_get_device(ev);
- struct device_user_data *data = libinput_device_get_user_data(dev);
double value;
- int discrete;
+ enum libinput_pointer_axis axis;
+ enum libinput_event_type type;
- assert(data);
+ type = libinput_event_get_type(ev);
- if (libinput_event_pointer_has_axis(p,
- LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL)) {
- value = libinput_event_pointer_get_axis_value(p,
- LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
+ axis = LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL;
+ if (libinput_event_pointer_has_axis(p, axis)) {
+ value = libinput_event_pointer_get_scroll_value(p, axis);
w->scroll.vy += value;
w->scroll.vy = clip(w->scroll.vy, 0, w->height);
- data->scroll_accumulated.y += value;
- discrete = libinput_event_pointer_get_axis_value_discrete(p,
- LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
- if (discrete) {
- w->scroll.vy_discrete += data->scroll_accumulated.y;
+ if (type == LIBINPUT_EVENT_POINTER_SCROLL_WHEEL) {
+ w->scroll.vy_discrete += value;
w->scroll.vy_discrete = clip(w->scroll.vy_discrete, 0, w->height);
- data->scroll_accumulated.y = 0;
}
}
- if (libinput_event_pointer_has_axis(p,
- LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL)) {
- value = libinput_event_pointer_get_axis_value(p,
- LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL);
+ axis = LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL;
+ if (libinput_event_pointer_has_axis(p, axis)) {
+ value = libinput_event_pointer_get_scroll_value(p, axis);
w->scroll.hx += value;
w->scroll.hx = clip(w->scroll.hx, 0, w->width);
- data->scroll_accumulated.x += value;
- discrete = libinput_event_pointer_get_axis_value_discrete(p,
- LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL);
- if (discrete) {
- w->scroll.hx_discrete += data->scroll_accumulated.x;
+ if (type == LIBINPUT_EVENT_POINTER_SCROLL_WHEEL) {
+ w->scroll.hx_discrete += value;
w->scroll.hx_discrete = clip(w->scroll.hx_discrete, 0, w->width);
- data->scroll_accumulated.x = 0;
}
}
}
@@ -1798,6 +1779,11 @@ handle_event_libinput(GIOChannel *source, GIOCondition condition, gpointer data)
case LIBINPUT_EVENT_TOUCH_FRAME:
break;
case LIBINPUT_EVENT_POINTER_AXIS:
+ /* ignore */
+ break;
+ case LIBINPUT_EVENT_POINTER_SCROLL_WHEEL:
+ case LIBINPUT_EVENT_POINTER_SCROLL_FINGER:
+ case LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS:
handle_event_axis(ev, w);
break;
case LIBINPUT_EVENT_POINTER_BUTTON: