struct discrete_coords discrete = { 0.0, 0.0 };
struct wheel_v120 v120 = { 0.0, 0.0 };
+ /* This mouse has a trackstick instead of a mouse wheel and sends
+ * trackstick data via REL_WHEEL. Normalize it like normal x/y coordinates.
+ */
if (device->model_flags & EVDEV_MODEL_LENOVO_SCROLLPOINT) {
struct normalized_coords unaccel = { 0.0, 0.0 };
- dispatch->wheel.hi_res.y *= -1;
- fallback_normalize_delta(device, &dispatch->wheel.hi_res, &unaccel);
+ dispatch->wheel.lo_res.y *= -1;
+ fallback_normalize_delta(device, &dispatch->wheel.lo_res, &unaccel);
evdev_post_scroll(device,
time,
LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS,
&unaccel);
dispatch->wheel.hi_res.x = 0;
dispatch->wheel.hi_res.y = 0;
+ dispatch->wheel.lo_res.x = 0;
+ dispatch->wheel.lo_res.y = 0;
return;
}
--- /dev/null
+/*
+ * Copyright © 2013 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include "config.h"
+
+#include "litest.h"
+#include "litest-int.h"
+
+static struct input_id input_id = {
+ .bustype = 0x3,
+ .vendor = 0x04b3,
+ .product = 0x3109,
+};
+
+static int events[] = {
+ EV_KEY, BTN_LEFT,
+ EV_KEY, BTN_RIGHT,
+ EV_KEY, BTN_MIDDLE,
+ EV_REL, REL_X,
+ EV_REL, REL_Y,
+ EV_REL, REL_WHEEL,
+ EV_REL, REL_WHEEL_HI_RES,
+ EV_REL, REL_HWHEEL,
+ -1 , -1,
+};
+
+/* Note: device is not tagged with LITEST_WHEEL to avoid running the
+ * "standard" wheel tests. Device has a custom wheel
+ * behavior that is tested directly.
+ */
+TEST_DEVICE("lenovo-scrollpoint",
+ .type = LITEST_LENOVO_SCROLLPOINT,
+ .features = LITEST_RELATIVE | LITEST_BUTTON,
+ .interface = NULL,
+
+ .name = "HID 04b3:3109",
+ .id = &input_id,
+ .absinfo = NULL,
+ .events = events,
+)
}
END_TEST
+START_TEST(pointer_scroll_wheel_lenovo_scrollpoint)
+{
+ struct litest_device *dev = litest_current_device();
+ struct libinput *li = dev->libinput;
+ struct libinput_event *event;
+ struct libinput_event_pointer *ptrev;
+ double v;
+
+ litest_drain_events(dev->libinput);
+
+ /* Lenovo ScrollPoint has a trackstick instead of a wheel, data sent
+ * via REL_WHEEL is close to x/y coordinate space.
+ */
+ litest_event(dev, EV_REL, REL_WHEEL, 30);
+ litest_event(dev, EV_SYN, SYN_REPORT, 0);
+ litest_event(dev, EV_REL, REL_WHEEL, -60);
+ litest_event(dev, EV_SYN, SYN_REPORT, 0);
+ libinput_dispatch(li);
+
+ /* Hi-res scroll event first */
+ event = libinput_get_event(li);
+ litest_assert(litest_is_high_res_axis_event(event));
+ ptrev = litest_is_axis_event(event,
+ LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS,
+ LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
+ LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS);
+
+ v = libinput_event_pointer_get_scroll_value(ptrev, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
+ litest_assert_double_eq(v, -30.0);
+ libinput_event_destroy(event);
+
+ /* legacy lo-res scroll event */
+ event = libinput_get_event(li);
+ litest_assert(!litest_is_high_res_axis_event(event));
+ ptrev = litest_is_axis_event(event,
+ LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS,
+ LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
+ LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS);
+ v = libinput_event_pointer_get_axis_value(ptrev, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
+ litest_assert_double_eq(v, -30.0);
+ libinput_event_destroy(event);
+
+ /* Hi-res scroll event first */
+ event = libinput_get_event(li);
+ ptrev = litest_is_axis_event(event,
+ LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS,
+ LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
+ LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS);
+
+ v = libinput_event_pointer_get_scroll_value(ptrev, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
+ litest_assert_double_eq(v, 60.0);
+ libinput_event_destroy(event);
+
+ /* legacy lo-res scroll event */
+ event = libinput_get_event(li);
+ litest_assert(!litest_is_high_res_axis_event(event));
+ ptrev = litest_is_axis_event(event,
+ LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS,
+ LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
+ LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS);
+ v = libinput_event_pointer_get_axis_value(ptrev, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
+ litest_assert_double_eq(v, 60.0);
+ libinput_event_destroy(event);
+
+}
+END_TEST
+
START_TEST(pointer_scroll_natural_defaults)
{
struct litest_device *dev = litest_current_device();
/* button scrolling is only enabled if there is a
middle button present */
- if (libinput_device_pointer_has_button(device, BTN_MIDDLE))
+ if (libinput_device_pointer_has_button(device, BTN_MIDDLE) &&
+ dev->which != LITEST_LENOVO_SCROLLPOINT)
expected = LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN;
else
expected = LIBINPUT_CONFIG_SCROLL_NO_SCROLL;
litest_add(pointer_scroll_wheel_hires_send_only_lores_horizontal, LITEST_WHEEL, LITEST_TABLET);
litest_add(pointer_scroll_wheel_inhibit_small_deltas, LITEST_WHEEL, LITEST_TABLET);
litest_add(pointer_scroll_wheel_inhibit_dir_change, LITEST_WHEEL, LITEST_TABLET);
+ litest_add_for_device(pointer_scroll_wheel_lenovo_scrollpoint, LITEST_LENOVO_SCROLLPOINT);
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);