diff --git a/src/evdev-mt-touchpad-edge-scroll.c b/src/evdev-mt-touchpad-edge-scroll.c index 8605034c..26a86141 100644 --- a/src/evdev-mt-touchpad-edge-scroll.c +++ b/src/evdev-mt-touchpad-edge-scroll.c @@ -325,10 +325,10 @@ tp_edge_scroll_post_events(struct tp_dispatch *tp, uint64_t time) if (t->scroll.direction != -1) { /* Send stop scroll event */ pointer_notify_axis(device, time, - t->scroll.direction, + AS_MASK(t->scroll.direction), LIBINPUT_POINTER_AXIS_SOURCE_FINGER, - 0.0, - 0); + 0.0, 0.0, + 0, 0); t->scroll.direction = -1; } continue; @@ -350,10 +350,11 @@ tp_edge_scroll_post_events(struct tp_dispatch *tp, uint64_t time) if (fabs(*delta) < t->scroll.threshold) continue; - pointer_notify_axis(device, time, axis, + pointer_notify_axis(device, time, + AS_MASK(axis), LIBINPUT_POINTER_AXIS_SOURCE_FINGER, - *delta, - 0); + dx, dy, + 0, 0); t->scroll.direction = axis; tp_edge_scroll_handle_event(tp, t, SCROLL_EVENT_POSTED); @@ -371,10 +372,10 @@ tp_edge_scroll_stop_events(struct tp_dispatch *tp, uint64_t time) tp_for_each_touch(tp, t) { if (t->scroll.direction != -1) { pointer_notify_axis(device, time, - t->scroll.direction, + AS_MASK(t->scroll.direction), LIBINPUT_POINTER_AXIS_SOURCE_FINGER, - 0.0, - 0); + 0.0, 0.0, + 0.0, 0.0); t->scroll.direction = -1; } } diff --git a/src/evdev.c b/src/evdev.c index 0e78381c..2d73d690 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -539,22 +539,24 @@ evdev_process_absolute_motion(struct evdev_device *device, static void evdev_notify_axis(struct evdev_device *device, uint64_t time, - enum libinput_pointer_axis axis, + uint32_t axes, enum libinput_pointer_axis_source source, - double value, - double discrete) + double x, double y, + double x_discrete, double y_discrete) { if (device->scroll.natural_scrolling_enabled) { - value *= -1; - discrete *= -1; + x *= -1; + y *= -1; + x_discrete *= -1; + y_discrete *= -1; } pointer_notify_axis(&device->base, time, - axis, + axes, source, - value, - discrete); + x, y, + x_discrete, y_discrete); } static inline void @@ -579,9 +581,11 @@ evdev_process_relative(struct evdev_device *device, evdev_notify_axis( device, time, - LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, + AS_MASK(LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL), LIBINPUT_POINTER_AXIS_SOURCE_WHEEL, + 0.0, -1 * e->value * device->scroll.wheel_click_angle, + 0.0, -1 * e->value); break; case REL_HWHEEL: @@ -589,10 +593,12 @@ evdev_process_relative(struct evdev_device *device, evdev_notify_axis( device, time, - LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, + AS_MASK(LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL), LIBINPUT_POINTER_AXIS_SOURCE_WHEEL, e->value * device->scroll.wheel_click_angle, - e->value); + 0.0, + e->value, + 0.0); break; } } @@ -1802,7 +1808,7 @@ evdev_is_scrolling(const struct evdev_device *device, assert(axis == LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL || axis == LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL); - return (device->scroll.direction & (1 << axis)) != 0; + return (device->scroll.direction & AS_MASK(axis)) != 0; } static inline void @@ -1812,7 +1818,7 @@ evdev_start_scrolling(struct evdev_device *device, assert(axis == LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL || axis == LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL); - device->scroll.direction |= (1 << axis); + device->scroll.direction |= AS_MASK(axis); } void @@ -1863,27 +1869,20 @@ evdev_post_scroll(struct evdev_device *device, /* We use the trigger to enable, but the delta from this event for * the actual scroll movement. Otherwise we get a jump once * scrolling engages */ - if (dy != 0.0 && - evdev_is_scrolling(device, - LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL)) { - evdev_notify_axis(device, - time, - LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, - source, - dy, - 0); - } + if (!evdev_is_scrolling(device, + LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL)) + dy = 0.0; + if (!evdev_is_scrolling(device, + LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL)) + dx = 0.0; - if (dx != 0.0 && - evdev_is_scrolling(device, - LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL)) { + if (dx != 0.0 || dy != 0.0) evdev_notify_axis(device, time, - LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, + device->scroll.direction, source, - dx, - 0); - } + dx, dy, + 0.0, 0.0); } void @@ -1892,18 +1891,13 @@ evdev_stop_scroll(struct evdev_device *device, enum libinput_pointer_axis_source source) { /* terminate scrolling with a zero scroll event */ - if (device->scroll.direction & (1 << LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL)) + if (device->scroll.direction != 0) pointer_notify_axis(&device->base, time, - LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, + device->scroll.direction, source, - 0, 0); - if (device->scroll.direction & (1 << LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL)) - pointer_notify_axis(&device->base, - time, - LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, - source, - 0, 0); + 0.0, 0.0, + 0.0, 0.0); device->scroll.buildup_horizontal = 0; device->scroll.buildup_vertical = 0; diff --git a/src/libinput-private.h b/src/libinput-private.h index 415e53e3..012c82d0 100644 --- a/src/libinput-private.h +++ b/src/libinput-private.h @@ -278,10 +278,12 @@ pointer_notify_button(struct libinput_device *device, void pointer_notify_axis(struct libinput_device *device, uint64_t time, - enum libinput_pointer_axis axis, + uint32_t axes, enum libinput_pointer_axis_source source, - double value, - double discrete); + double x, + double y, + double x_discrete, + double y_discrete); void touch_notify_touch_down(struct libinput_device *device, diff --git a/src/libinput-util.h b/src/libinput-util.h index dc70bcd2..f76439f1 100644 --- a/src/libinput-util.h +++ b/src/libinput-util.h @@ -79,6 +79,7 @@ int list_empty(const struct list *list); #define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0]) #define ARRAY_FOR_EACH(_arr, _elem) \ for (size_t _i = 0; _i < ARRAY_LENGTH(_arr) && (_elem = &_arr[_i]); _i++) +#define AS_MASK(v) (1 << (v)) #define min(a, b) (((a) < (b)) ? (a) : (b)) #define max(a, b) (((a) > (b)) ? (a) : (b)) diff --git a/src/libinput.c b/src/libinput.c index 37df9626..00ab5f21 100644 --- a/src/libinput.c +++ b/src/libinput.c @@ -59,15 +59,15 @@ struct libinput_event_pointer { uint32_t time; double x; double y; + double x_discrete; + double y_discrete; double dx_unaccel; double dy_unaccel; uint32_t button; uint32_t seat_button_count; enum libinput_button_state state; - enum libinput_pointer_axis axis; enum libinput_pointer_axis_source source; - double value; - double discrete; + uint32_t axes; }; struct libinput_event_touch { @@ -380,22 +380,63 @@ libinput_event_pointer_get_seat_button_count( return event->seat_button_count; } -LIBINPUT_EXPORT enum libinput_pointer_axis -libinput_event_pointer_get_axis(struct libinput_event_pointer *event) +LIBINPUT_EXPORT int +libinput_event_pointer_has_axis(struct libinput_event_pointer *event, + enum libinput_pointer_axis axis) { - return event->axis; + if (event->base.type == LIBINPUT_EVENT_POINTER_AXIS) { + switch (axis) { + case LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL: + case LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL: + return !!(event->axes & AS_MASK(axis)); + } + } + return 0; } LIBINPUT_EXPORT double -libinput_event_pointer_get_axis_value(struct libinput_event_pointer *event) +libinput_event_pointer_get_axis_value(struct libinput_event_pointer *event, + enum libinput_pointer_axis axis) { - return event->value; + struct libinput *libinput = event->base.device->seat->libinput; + double value = 0; + + 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->x; + break; + case LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL: + value = event->y; + break; + } + } + + return value; } LIBINPUT_EXPORT double -libinput_event_pointer_get_axis_value_discrete(struct libinput_event_pointer *event) +libinput_event_pointer_get_axis_value_discrete(struct libinput_event_pointer *event, + enum libinput_pointer_axis axis) { - return event->discrete; + struct libinput *libinput = event->base.device->seat->libinput; + double value = 0; + + 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->x_discrete; + break; + case LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL: + value = event->y_discrete; + break; + } + } + return value; } LIBINPUT_EXPORT enum libinput_pointer_axis_source @@ -999,10 +1040,10 @@ pointer_notify_button(struct libinput_device *device, void pointer_notify_axis(struct libinput_device *device, uint64_t time, - enum libinput_pointer_axis axis, + uint32_t axes, enum libinput_pointer_axis_source source, - double value, - double discrete) + double x, double y, + double x_discrete, double y_discrete) { struct libinput_event_pointer *axis_event; @@ -1012,10 +1053,12 @@ pointer_notify_axis(struct libinput_device *device, *axis_event = (struct libinput_event_pointer) { .time = time, - .axis = axis, - .value = value, + .x = x, + .y = y, .source = source, - .discrete = discrete, + .axes = axes, + .x_discrete = x_discrete, + .y_discrete = y_discrete, }; post_device_event(device, time, diff --git a/src/libinput.h b/src/libinput.h index c6dd57e7..276660b9 100644 --- a/src/libinput.h +++ b/src/libinput.h @@ -653,17 +653,17 @@ libinput_event_pointer_get_seat_button_count( /** * @ingroup event_pointer * - * Return the axis that triggered this event. - * For pointer events that are not of type @ref LIBINPUT_EVENT_POINTER_AXIS, - * this function returns 0. + * Check if the event has a valid value for the given axis. * - * @note It is an application bug to call this function for events other than - * @ref LIBINPUT_EVENT_POINTER_AXIS. + * If this function returns non-zero for an axis and + * libinput_event_pointer_get_axis_value() returns a value of 0, the event + * is a scroll stop event. * - * @return the axis triggering this event + * @return non-zero if this event contains a value for this axis */ -enum libinput_pointer_axis -libinput_event_pointer_get_axis(struct libinput_event_pointer *event); +int +libinput_event_pointer_has_axis(struct libinput_event_pointer *event, + enum libinput_pointer_axis axis); /** * @ingroup event_pointer @@ -676,6 +676,9 @@ libinput_event_pointer_get_axis(struct libinput_event_pointer *event); * respectively. For the interpretation of the value, see * libinput_event_pointer_get_axis_source(). * + * If libinput_event_pointer_has_axis() returns 0 for an axis, this function + * returns 0 for that axis. + * * For pointer events that are not of type @ref LIBINPUT_EVENT_POINTER_AXIS, * this function returns 0. * @@ -687,7 +690,8 @@ libinput_event_pointer_get_axis(struct libinput_event_pointer *event); * @see libinput_event_pointer_get_axis_value_discrete */ double -libinput_event_pointer_get_axis_value(struct libinput_event_pointer *event); +libinput_event_pointer_get_axis_value(struct libinput_event_pointer *event, + enum libinput_pointer_axis axis); /** * @ingroup event_pointer @@ -744,7 +748,8 @@ libinput_event_pointer_get_axis_source(struct libinput_event_pointer *event); * @see libinput_event_pointer_get_axis_value */ double -libinput_event_pointer_get_axis_value_discrete(struct libinput_event_pointer *event); +libinput_event_pointer_get_axis_value_discrete(struct libinput_event_pointer *event, + enum libinput_pointer_axis axis); /** * @ingroup event_pointer diff --git a/src/libinput.sym b/src/libinput.sym index d9ebbc27..f1fa306c 100644 --- a/src/libinput.sym +++ b/src/libinput.sym @@ -83,6 +83,7 @@ global: libinput_event_pointer_get_dy_unaccelerated; libinput_event_pointer_get_seat_button_count; libinput_event_pointer_get_time; + libinput_event_pointer_has_axis; libinput_event_touch_get_base_event; libinput_event_touch_get_seat_slot; libinput_event_touch_get_slot; diff --git a/test/litest.c b/test/litest.c index 392ffe25..757f445d 100644 --- a/test/litest.c +++ b/test/litest.c @@ -983,11 +983,11 @@ litest_print_event(struct libinput_event *event) case LIBINPUT_EVENT_POINTER_AXIS: p = libinput_event_get_pointer_event(event); fprintf(stderr, - "axis %s value %.2f", - libinput_event_pointer_get_axis(p) == - LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL ? - "vert" : "horiz", - libinput_event_pointer_get_axis_value(p)); + "vert %.f horiz %.2f", + libinput_event_pointer_get_axis_value(p, + LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL), + libinput_event_pointer_get_axis_value(p, + LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL)); break; default: break; @@ -1198,23 +1198,24 @@ litest_assert_scroll(struct libinput *li, LIBINPUT_EVENT_POINTER_AXIS); ptrev = libinput_event_get_pointer_event(event); ck_assert(ptrev != NULL); - ck_assert_int_eq(libinput_event_pointer_get_axis(ptrev), axis); if (next_event) { /* Normal scroll event, check dir */ if (minimum_movement > 0) { ck_assert_int_ge( - libinput_event_pointer_get_axis_value(ptrev), + libinput_event_pointer_get_axis_value(ptrev, + axis), minimum_movement); } else { ck_assert_int_le( - libinput_event_pointer_get_axis_value(ptrev), + libinput_event_pointer_get_axis_value(ptrev, + axis), minimum_movement); } } else { /* Last scroll event, must be 0 */ ck_assert_int_eq( - libinput_event_pointer_get_axis_value(ptrev), + libinput_event_pointer_get_axis_value(ptrev, axis), 0); } libinput_event_destroy(event); diff --git a/test/pointer.c b/test/pointer.c index 2055c413..1af4f385 100644 --- a/test/pointer.c +++ b/test/pointer.c @@ -348,6 +348,7 @@ test_wheel_event(struct litest_device *dev, int which, int amount) struct libinput *li = dev->libinput; struct libinput_event *event; struct libinput_event_pointer *ptrev; + enum libinput_pointer_axis axis; /* the current evdev implementation scales the scroll wheel events up by a factor 15 */ @@ -375,14 +376,16 @@ test_wheel_event(struct litest_device *dev, int which, int amount) ptrev = libinput_event_get_pointer_event(event); ck_assert(ptrev != NULL); - ck_assert_int_eq(libinput_event_pointer_get_axis(ptrev), - which == REL_WHEEL ? + + axis = (which == REL_WHEEL) ? LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL : - LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL); - ck_assert_int_eq(libinput_event_pointer_get_axis_value(ptrev), expected); + LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL; + + ck_assert_int_eq(libinput_event_pointer_get_axis_value(ptrev, axis), + expected); ck_assert_int_eq(libinput_event_pointer_get_axis_source(ptrev), LIBINPUT_POINTER_AXIS_SOURCE_WHEEL); - ck_assert_int_eq(libinput_event_pointer_get_axis_value_discrete(ptrev), + ck_assert_int_eq(libinput_event_pointer_get_axis_value_discrete(ptrev, axis), discrete); libinput_event_destroy(event); } diff --git a/test/touchpad.c b/test/touchpad.c index 422e8fe6..dbe16a3a 100644 --- a/test/touchpad.c +++ b/test/touchpad.c @@ -1439,18 +1439,19 @@ START_TEST(touchpad_2fg_scroll_slow_distance) /* last event is value 0, tested elsewhere */ while (libinput_next_event_type(li) != LIBINPUT_EVENT_NONE) { + double axisval; 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(ptrev), - LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL); - ck_assert(libinput_event_pointer_get_axis_value(ptrev) > 0.0); + axisval = libinput_event_pointer_get_axis_value(ptrev, + LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL); + 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 condition */ - ck_assert(libinput_event_pointer_get_axis_value(ptrev) < 5.0); + ck_assert(axisval < 5.0); libinput_event_destroy(event); event = libinput_get_event(li); @@ -1627,18 +1628,19 @@ START_TEST(touchpad_edge_scroll_slow_distance) ck_assert_notnull(event); while (libinput_next_event_type(li) != LIBINPUT_EVENT_NONE) { + double axisval; 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(ptrev), + axisval = libinput_event_pointer_get_axis_value(ptrev, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL); - ck_assert(libinput_event_pointer_get_axis_value(ptrev) > 0.0); + 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 condition */ - ck_assert(libinput_event_pointer_get_axis_value(ptrev) < 5.0); + ck_assert(axisval < 5.0); libinput_event_destroy(event); event = libinput_get_event(li); diff --git a/tools/event-debug.c b/tools/event-debug.c index 090fc3f0..4d845ced 100644 --- a/tools/event-debug.c +++ b/tools/event-debug.c @@ -225,24 +225,18 @@ static void print_axis_event(struct libinput_event *ev) { struct libinput_event_pointer *p = libinput_event_get_pointer_event(ev); - enum libinput_pointer_axis axis = libinput_event_pointer_get_axis(p); - const char *ax; - double val; - - switch (axis) { - case LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL: - ax = "vscroll"; - break; - case LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL: - ax = "hscroll"; - break; - default: - abort(); - } + double v = 0, h = 0; + 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); + 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); print_event_time(libinput_event_pointer_get_time(p)); - val = libinput_event_pointer_get_axis_value(p); - printf("%s %.2f\n", ax, val); + printf("vert %.2f horiz %.2f\n", v, h); } static void diff --git a/tools/event-gui.c b/tools/event-gui.c index 9a08d8ef..4f9d7e67 100644 --- a/tools/event-gui.c +++ b/tools/event-gui.c @@ -358,20 +358,20 @@ static void handle_event_axis(struct libinput_event *ev, struct window *w) { struct libinput_event_pointer *p = libinput_event_get_pointer_event(ev); - enum libinput_pointer_axis axis = libinput_event_pointer_get_axis(p); - double v = libinput_event_pointer_get_axis_value(p); + double v, h; - switch (axis) { - case LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL: + v = libinput_event_pointer_get_axis_value(p, + LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL); + h = libinput_event_pointer_get_axis_value(p, + LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL); + + if (v != 0.0) { w->vy += (int)v; w->vy = clip(w->vy, 0, w->height); - break; - case LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL: + } + if (h != 0.0) { w->hx += (int)v; w->hx = clip(w->hx, 0, w->width); - break; - default: - abort(); } }